Skip to content

Request parameter with special character (plus) duplicated in request snippet #632

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

Closed
neubarth opened this issue Aug 5, 2019 · 4 comments
Assignees
Labels
for: external-project Should have been opened against a different project status: invalid Suggestion or bug report that we don't feel is valid

Comments

@neubarth
Copy link

neubarth commented Aug 5, 2019

When the value of a request parameter contains the plus sign (+), the parameter occurs twice in the generated snippet.

Example controller test:

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import io.restassured.module.mockmvc.RestAssuredMockMvc;

@RunWith(SpringRunner.class)
@WebMvcTest(TestController.class)
@AutoConfigureRestDocs
public class TestControllerTest {

    @Autowired
    protected MockMvc mockMvc;

    @Before
    public void setUp() {
        RestAssuredMockMvc.mockMvc(mockMvc);
    }

    @Test
    public void test() {
        RestDocumentationResultHandler documentHandler = document(
                "{class-name}/{method-name}",
                requestParameters(parameterWithName("phone").description("phone number")));
        String phoneNumber = "+491234567";
        RestAssuredMockMvc.given().log().all().queryParam("phone", phoneNumber)
                .when().get("/test")
                .then().apply(documentHandler);
    }
}

Resulting snippet:

[source,http,options="nowrap"]
----
GET /test?phone=+491234567&phone=%2B491234567 HTTP/1.1
Host: localhost:8080
---

If i remove the + sign in phoneNumber, the snippet is correct, i.e. the parameter occurs only once.

Versions used:
spring-restdocs-mockmvc : 2.0.3
rest-assured : 4.0.0
Spring Boot 2.1.5

@marcgemis
Copy link

I have the same problem when the value is the empty string.

@wilkinsona wilkinsona added type: bug A bug and removed status: waiting-for-triage Untriaged issue labels Aug 13, 2019
@wilkinsona wilkinsona added this to the 2.0.4.RELEASE milestone Aug 13, 2019
@wilkinsona wilkinsona self-assigned this Aug 13, 2019
@wilkinsona
Copy link
Member

wilkinsona commented Aug 14, 2019

@neubarth Thanks for the report. I've reproduced the problem.

@marcgemis That doesn't sound like the same problem to me. The problem reported here is due to the + being decoded into a and then encoded back into a +, and being left as a + which results in it being encoded as %2B. As a result phone appears to have two values: +491234567 and %2B491234567. I don't understand how that could occur with an empty string. Perhaps you could open a separate issue with a minimal sample that reproduces your problem?

@wilkinsona
Copy link
Member

This is, at least in part, a bug in REST Assured. + is a reserved character in a query string and RFC 2396 says the following about escape encoding such characters:

Normally, the only time escape encodings can safely be made is when the URI is being created from its component parts; each component may have its own set of characters that are reserved

It's REST Assured that's taking the queryParam("phone", phoneNumber) and adding it to the URL's query string so I think REST Assured should be encoding the + as %2B when it does so.

@wilkinsona
Copy link
Member

The problem does not occur when REST Assured is used directly rather than via its MockMVC integration. When used directly it results in a RequestSpecificationImpl that returns http://localhost:8080/?phone=%2B123456789 from getURI(). The problem also does not occur when using MockMvc directly.

I've tried to find a workaround, for example by using .get("/test?phone=%2B491234567") rather than .queryParam("phone", phoneNumber) to include the phone number query parameter, but this leads to double-encoding and the % being encoded.

@neubarth I think I've done all I can here. Please open a REST Assured issue and comment here with a link to it. I'm happy to help as needed and also to re-open this issue if my analysis turns out to be faulty.

Lastly, please note the REST Docs does not, yet, officially support REST Assured 4.0. I'd actually missed it being released so thanks for bringing that to my attention. I've opened #635.

@wilkinsona wilkinsona added for: external-project Should have been opened against a different project and removed type: bug A bug labels Aug 14, 2019
@wilkinsona wilkinsona removed this from the 2.0.4.RELEASE milestone Aug 14, 2019
@wilkinsona wilkinsona added the status: invalid Suggestion or bug report that we don't feel is valid label Aug 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project Should have been opened against a different project status: invalid Suggestion or bug report that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

4 participants