Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MockPart is not added to parameter list anymore for Content-Type application/json #26400

Closed
cmdjulian opened this issue Jan 18, 2021 · 3 comments
Assignees
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: regression A bug that is also a regression
Milestone

Comments

@cmdjulian
Copy link

Affects: 5.3.3


After the update to version 5.3.3 a few of my MockMvc tests failed. After hours of debuging I found out that it is related to #26261.
In my test I do the following.

mvc.multipart(POSTS_ME) {
        part(mockMultipartJson("video_attributes", payload))
        file(mockMultipartFile("video", "sample_video.mp4", "video/mp4", video))
}

protected fun mockMultipartFile(name: String, file: String, type: String, resource: Resource) =
    MockMultipartFile(name, file, type, resource.inputStream)

protected fun mockMultipartJson(partName: String, payload: Map<String, Any?>) =
    MockPart(partName, JSONObject(payload).toString().encodeToByteArray()).apply {
        headers.contentType = MediaType.APPLICATION_JSON
}

Using Postman everything works as expected. I found out my Part file is not getting set as request parameter inside the MockHttpRequest. My Controller has the following methods:

@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE], params = ["image_attributes"])
fun createImagePost(
    @RequestPart("image") image: MultipartFile,
    @Valid @RequestPart("image_attributes") attributes: CreatePostWithContentCommand,
    request: HttpServletRequest
): ResponseEntity<PostDto>

@PostMapping(consumes = [MediaType.MULTIPART_FORM_DATA_VALUE], params = ["video_attributes"])
fun createVideoPost(
    @RequestPart("video") video: MultipartFile,
    @Valid @RequestPart("video_attributes") attributes: CreatePostWithContentCommand,
    request: HttpServletRequest
): ResponseEntity<PostDto>

My Controller decides based on the Request-Paramter which method to call. The methods do various different things with the underlying image / video file. In the MockMultipartHttpServletRequestBuilder class of version 5.3.3 is now an additional check if the Content-Type of my Part file (video_attributes) is compatible to 'text/html', which it is not. Because of that method toParameterValue() my Parts name is not added to the parameter collection anymore. As I said, with Postman everything works.
Can you please elaborate on that for me? Is there a way to make the test work again? I would rather not change my endpoint just to get the test working, especially by dividing the endpoint or using an additional query parameter this makes my API less efficient.

Thanks in advance, looking forward to your response.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 18, 2021
@rstoyanchev rstoyanchev self-assigned this Jan 19, 2021
@rstoyanchev rstoyanchev added in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: regression A bug that is also a regression and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 19, 2021
@rstoyanchev rstoyanchev added this to the 5.3.4 milestone Jan 19, 2021
@rstoyanchev
Copy link
Contributor

In the MockMultipartHttpServletRequestBuilder class of version 5.3.3 is now an additional check if the Content-Type of my Part file (video_attributes) is compatible to 'text/html'

It's checking for compatibility with "text/plain" because the part will be represented as a request parameter which needs to be converted as a String. Not all content types make sense to be converted to String but I guess that check is too restrictive.

At runtime we rely on the Servlet container to return request parameter values for parts. Taking some inspiration from Jetty I guess we can simply turn the content to a String.

@rstoyanchev
Copy link
Contributor

rstoyanchev commented Jan 20, 2021

@codeMoney095 thanks for the report. There is now a fix in the master branch. If you are able to verify with 5.3.4-SNAPSHOT please do!

@cmdjulian
Copy link
Author

Thank you for the fast and professional response. Yes I can confirm its working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module in: web Issues in web modules (web, webmvc, webflux, websocket) type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

3 participants