How do I specify a mediatype of text/plain;charset=UTF-8 in a Spring Boot Test - spring

Here's my test :
#Test
fun `test config properties`() {
mockMvc.request(HttpMethod.GET,"someUrl") {
accept = MediaType.TEXT_PLAIN
}.andExpect {
status { isOk }
content { contentType(MediaType.TEXT_PLAIN) }
}
}
and it fails with this:
Expected :text/plain Actual :text/plain;charset=UTF-8
This is using the Kotlin DSL for MockMVC.
How do I change the accept to allow for charset=UTF-8 ?

There is one factory method which accepts custom value. Try:
MediaType.valueOf("text/plain;charset=UTF-8")

If charset is not the objective of the test Spring Boot provides more flexible assertion of the content-type using contentTypeCompatibleWith():
For instance, in Kotlin DSL it would look like this:
mockMvc.get("/") {
accept = TEXT_HTML
}.andExpect {
content {
contentTypeCompatibleWith(TEXT_HTML)
// ... more assertions here...
}
}

You can also use the constructor accepting the encoding as a parameter:
new MediaType(MediaType.TEXT_PLAIN, StandardCharsets.UTF_8)

Related

Springdoc openapi migration from springfox

I am working on the migration of swagger spring fox to spring doc open api. I followed below link.
https://deepak-shinde.medium.com/migrating-from-springfox-swagger-2-to-springdoc-openapi-3-79a79757b8d1
Below version used.
spring_boot_version= "2.5.5"
springdoc_openapi_version= "1.6.0"
In gradle dependency mentioned as below
implementation "org.springdoc:springdoc-openapi-ui:$springdoc_openapi_version"
implementation "org.springdoc:springdoc-openapi-javadoc:$springdoc_openapi_version"
I defined rest controller.
#RestController
#RequestMapping("/v1")
#Slf4j
#Tag(name = "Master", description = "Master service API")
public class MasterController {
#Operation(summary = "Get test data",security = {
#SecurityRequirement(name = MasterConstant.HTTP_AUTH_SECURITY_SCHEME) }, tags = {
"Master" } ,description = " This method is used to get test data")
#PostMapping("/codes")
public ResponseEntity<MasterCodeResponse> getTestData()
}
application.properties
springdoc.swagger-ui.path=swagger-ui
springdoc.packages-to-exclude=com.master.persistence.*
springdoc.packages-to-scan=com.master.controller,com.common.controller // here * by default not working as its not listing apis
springdoc.api-docs.resolve-schema-properties=false
When i invoke v3/apidocs - Tags is coming empty. No controller name or description is displayed.
"openapi":"3.0.1",
"info":{
"title":"Test REST API",
"version":"1.0.0"
},
"servers":[
{
"url":"http://localhost:8082/master-service/",
"description":"Generated server url"
}
],
"security":[
{
"bearerAuth":[
]
}
],
"tags":[
{
}
],
Same way for operations tags is coming empty.
"/v1/codes":{
"post":{
"tags":[
null
],
"o
Below bean is defined
#Bean
public OpenAPI customizeOpenAPI() {
final String securitySchemeName = "bearerAuth";
return new OpenAPI().addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
.components(
new Components().addSecuritySchemes(securitySchemeName,
new SecurityScheme().name(securitySchemeName).type(SecurityScheme.Type.HTTP)
.scheme("bearer").bearerFormat("JWT")))
.info(new Info().title("Test REST API").version("1.0.0"));
}
Please let me know how to get the summary of the opertaion and controller tags in swagger as well as in the apidocs yaml. Please advice if i am doing something wrong here.
There were some issue about tags, as you can see here
You should try to update springdoc-openapi to at least version 1.6.7.

Spring cloud contract load active profiles

I have a contract like:
Contract.make {
ignoreForDevEnvironment() ? ignored() : ""
description ""
request {
method 'POST'
url '/something'
body($(execute("someMethod()")))
}
response {
status 200
}
}
private static Boolean ignoreForDevEnvironment() {
//read Spring Active profiles
//return true if `dev` profile is listed
}
I want my method ignoreForDevEnvironment to read the active spring profiles, how can I achieve this?

#RequestHeader behaviour not as expected; working without required User-Agent

I have a project set up using Spring Boot with Kotlin to make REST APIs.
I'm trying to use the #RequestHeader to recognize the User-Agent. The said header is required=true -
#PostMapping("details", produces = ["application/json"])
fun addInfo(#RequestHeader(name = "User-Agent", required = true) userAgent: String,
#Valid #RequestBody podEntity: PodEntity): ResponseEntity<String> {
pod.addPod(podcastEntity)
return ResponseEntity<String>("{ \"status\":\"Added\" }", HttpStatus.CREATED)
}
Problems -
However, even if I'm not sending the User-Agent header, the API is working and adding data. But, if I change the header to any other non default names, like, user or request-source, the required=true requirement is enforced to and the API does not work. Does it mean that default headers cannot be made mandatory using the required tag?
The other problem is that in the case of custom header, when the required header is missing for the request, the API fails by giving 400 error code but does not throw any exception. I was expecting HttpClientErrorException for my junit test case but on checking the console, I see no exception. Adding #Throws is also not helping. How do enable my function to throw an exception when the required header is missing?
Unit test -
#Test
fun test_getAll_fail_missingHeaders() {
val url = getRootUrl() + "/details/all"
val headers = HttpHeaders()
val request = HttpEntity(pod, headers)
try {
restTemplate!!.postForEntity(url, request, String::class.java)
fail()
} catch (ex: HttpClientErrorException) {
assertEquals(400, ex.rawStatusCode);
assertEquals(true, ex.responseBodyAsString.contains("Missing request header"))
}
}

How do you define a file response as a Message

I'm using proto to define a REST service
In my service, I'm trying to document that a service responds with a file.
I've looked through here https://github.com/protocolbuffers/protobuf/tree/master/src/google/protobuf but couldn't find anything that looked like a file.
service SomeService {
rpc GetStaticAsset(GetMessageRequest) returns (FileAsset) {
option (google.api.http) = {
get: "/static/{assetName}"
};
}
}
message FileAsset {
¯\_(ツ)_/¯
}
Found the answer here:
message Chunk {
bytes Content = 1;
}

Grails Spring Security Rest - 403 Forbidden

So I just started learning Grails, and I am trying incorporate the Spring Security REST plugin into my app, the plugin is installed in addition to spring security core which is working. In my REST client, when I hit "api/login" I am able to get an access token and it says I have the role of "ROLE_ADMIN", but then when I try to hit something using that, I keep getting a 403 Forbidden. In Postman, the REST client I am using, I have my Authorization header with "Bearer {key}", with my url of "http://localhost:8080/test/api/secret" and it gives the 403 error. I am trying to setup the log4j logging to see any other issues, but does anyone know what I should look into, any help would be appreciated. I provided my classes below if that helps, I generally used default values for everything such as the UrlMappings.
RandomController.groovy
package test
import grails.plugin.springsecurity.annotation.Secured
#Secured(['IS_AUTHENTICATED_ANONYMOUSLY'])
class MyController {
#Secured(['ROLE_ADMIN'])
def secret() {
render "You have ACCESS!!!"
}
}
Bootstrap.groovy
class BootStrap {
def init = { servletContext ->
def adminRole = new SecRole(authority: 'ROLE_ADMIN').save(flush: true)
def testUser = new SecUser(username: 'bob', password: 'test')
testUser.save(flush: true)
SecUserSecRole.create testUser, adminRole, true
}
def destroy = {
}
}
UrlMappings.groovy
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/api/$controller/$action?/$id?(.$format)?"{ constraints { // apply constraints here
} }
"/"(view:"/index")
"500"(view:'/error')
}
}
For what I can see from the code you posted, if you invoke url http://localhost:8080/test/api/secret, it should execute default action (maybe index) in SecretController but the controller you posted is called MyController.
To investigate further, you should enable more verbose logging using log4j configuration as suggested in the doc http://alvarosanchez.github.io/grails-spring-security-rest/1.5.1/docs/guide/debugging.html

Resources