webmock icon indicating copy to clipboard operation
webmock copied to clipboard

Allow disabling normalized query parameters

Open kepstin opened this issue 9 years ago • 10 comments

In my application, I need to do some operations on the query string exactly as it was used in the request, without reordering any parameters or changing how the url encoding was done (e.g. + converted to %20)

This is because the application API uses a checksum calculated over the encoded query string, and I can't validate that the checksum was done correctly unless I can get the query string as generated.

e.g. if a request is made with:

uri = URI.parse('http://www.example.com/path?b=foo&a=bar+baz')
Net::HTTP.get(uri)

then WebMock will print:

       stub_request(:get, "http://www.example.com/path?a=bar%20baz&b=foo").
         with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'www.example.com', 'User-Agent'=>'Ruby'}).
         to_return(:status => 200, :body => "", :headers => {})

And if a block is passed to the 'with' on the stub request, then request.uri.query in the block will be a=bar%20baz&b=foo instead of the expected b=foo&a=bar+baz.

kepstin avatar Oct 29 '15 17:10 kepstin

@kepstin this has been an issue with webmock since always. It's worth another review in http client adapters though.

bblimke avatar Oct 30 '15 09:10 bblimke

Any plans (todos, etc.) to reach this feature?

bestwebua avatar Oct 27 '20 22:10 bestwebua

@bestwebua no plans. sorry.

Do you have any specific example that you can share?

bblimke avatar Oct 27 '20 22:10 bblimke

Hello, @bblimke! This time if we will change uri query behaviour (from decoded to encoded) all our tests that use stub_request will be passed. It happens because stub_request use normalized params by default. But if it can be a configurable option it will be more flexible:

stub_request(http_method, uri, normalized_params: false)

This will make possible to check passed uri query for cases when encoded params matter. So if this enhancement make sense for your library let me know.

bestwebua avatar Oct 28 '20 08:10 bestwebua

@bestwebua I think adding normalized_params options, will be unnecessary complication and in most cases, people who need it, will use it by default, therefore it would make more sense to have it as a WebMock configuration setting rather than option passed to stub_request.

I think the right solution is to keep both normalized and original version. Use normalized version for all comparisons, yet use original version for reporting.

bblimke avatar Oct 28 '20 10:10 bblimke

@bblimke I meant that normalized_params should be with default value true, so not necessary pass it always.

stub_request(http_method, uri) # normalized_params == true
stub_request(http_method, uri, normalized_params: false)

bestwebua avatar Oct 28 '20 10:10 bestwebua

@bestwebua the thing is that it's also request params are being normalized, not just stubbed url params.

bblimke avatar Oct 28 '20 11:10 bblimke

Indeed, for my use case it's actually only the request parameters that matter, not the stubbed URL params. I'm passing a block to the .with method on the mock which runs some code that looks at request.uri in order to validate specific details, and for that to work correctly it needs to get a non-normalized copy of the request params.

For my use case, being able to access a non-normalized copy of the query string and/or full uri in this context would be sufficient. For example, the original (pre-normalization) request uri could be saved to a separate attribute on the RequestSignature object.

kepstin avatar Sep 18 '23 15:09 kepstin

@kepstin thank you for re-raising this issue. I agree that WebMock should store the original, not-normalized copy and offer a base configuration or params that allow matching against the exact, not normalized values.

bblimke avatar Feb 06 '24 11:02 bblimke