webmock
webmock copied to clipboard
Allow disabling normalized query parameters
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 this has been an issue with webmock since always. It's worth another review in http client adapters though.
Any plans (todos, etc.) to reach this feature?
@bestwebua no plans. sorry.
Do you have any specific example that you can share?
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 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 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 the thing is that it's also request params are being normalized, not just stubbed url params.
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 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.