8000 Normalizes request body and URL by parsing params to a list and sorting by patrickberkeley · Pull Request #211 · parroty/exvcr · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Normalizes request body and URL by parsing params to a list and sorting #211

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

Merged
merged 2 commits into from
Aug 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fixture/custom_cassettes/response_mocking_with_param.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"request": {
"url": "http://example.com?auth_token=123abc",
"url": "http://example.com?auth_token=123abc&another_param=456",
"method": "get"
},
"response": {
Expand Down
2 changes: 1 addition & 1 deletion fixture/vcr_cassettes/different_query_params_on.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"headers": [],
"method": "get",
"options": [],
"url": "http://localhost:34006/server?p=3"
"url": "http://localhost:34006/server?p=3&q=string"
},
"response": {
"body": "test_response_before",
Expand Down
28 changes: 25 additions & 3 deletions lib/exvcr/handler.ex
10000
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ defmodule ExVCR.Handler do
pattern = Regex.compile!(Enum.at(match, 1))
Regex.match?(pattern, key_url)
else
request_url == key_url
normalize_url(request_url) == normalize_url(key_url)
end
else
request_url = parse_url(request_url, recorder_options)
key_url = parse_url(key_url, recorder_options)

request_url == key_url
normalize_url(request_url) == normalize_url(key_url)
end
end

Expand Down Expand Up @@ -170,13 +170,35 @@ defmodule ExVCR.Handler do
pattern = Regex.compile!(Enum.at(match, 1))
Regex.match?(pattern, key_body)
else
request_body == key_body
normalize_request_body(request_body) == normalize_request_body(key_body)
end
else
true
end
end

defp normalize_url(url) do
original_url = URI.parse(url)

original_url
|> Map.put(:query, normalize_query(original_url.query))
|> URI.to_string()
end

defp normalize_request_body(request_body) do
normalize_query(request_body)
end

defp normalize_query(nil), do: nil

defp normalize_query(query) do
query
|> URI.decode_query()
|> Map.to_list()
|> Enum.sort_by(fn {key, _val} -> key end)
|> URI.encode_query()
end

defp get_response_from_server(request, recorder, record?) do
adapter = ExVCR.Recorder.options(recorder)[:adapter]
response = :meck.passthrough(request)
Expand Down
3 changes: 1 addition & 2 deletions test/handler_custom_mode_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ defmodule ExVCR.Adapter.HandlerCustomModeTest do

test "query param match succeeds with custom mode" do
use_cassette "response_mocking_with_param", custom: true do
HTTPotion.get("http://example.com?auth_token=123abc", []).body =~ ~r/Custom Response/
HTTPotion.get("http://example.com?another_param=456&auth_token=123abc", []).body =~ ~r/Custom Response/
end
end


test "custom with valid response" do
use_cassette "response_mocking", custom: true do
assert HTTPotion.get("http://example.com", []).body =~ ~r/Custom Response/
Expand Down
2 changes: 1 addition & 1 deletion test/handler_options_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule ExVCR.Adapter.HandlerOptionsTest do
test "specifying match_requests_on: [:query] matches query params" do
use_cassette "different_query_params_on", match_requests_on: [:query] do
HttpServer.start(path: "/server", port: @port, response: "test_response_before")
assert HTTPotion.get("#{@url}?p=3", []).body =~ ~r/test_response_before/
assert HTTPotion.get("#{@url}?q=string&p=3", []).body =~ ~r/test_response_before/
HttpServer.stop(@port)

# this method call should NOT be mocked as previous "test_response_before" response
Expand Down
32 changes: 32 additions & 0 deletions test/handler_stub_mode_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ defmodule ExVCR.Adapter.HandlerStubModeTest do
end
end

test "url matches as regardless of query param order" do
use_cassette :stub, [url: "http://localhost?param1=10&param2=20&param3=30"] do
{:ok, status_code, _headers, body} = :ibrowse.send_req('http://localhost?param3=30&param1=10&param2=20', [], :get)
assert status_code == '200'
assert to_string(body) =~ ~r/Hello World/
end
end

test "url matches as regex" do
use_cassette :stub, [url: "~r/.+/"] do
{:ok, status_code, _headers, body} = :ibrowse.send_req('http://localhost', [], :get)
Expand All @@ -39,6 +47,14 @@ defmodule ExVCR.Adapter.HandlerStubModeTest do
end
end

test "request_body matches as string" do
use_cassette :stub, [url: 'http://localhost', method: :post, request_body: "some-string", body: "Hello World"] do
{:ok, status_code, _headers, body} = :ibrowse.send_req('http://localhost', [], :post, 'some-string')
assert status_code == '200'
assert to_string(body) =~ ~r/Hello World/
end
end

test "request_body matches as regex" do
use_cassette :stub, [url: 'http://localhost', method: :post, request_body: "~r/param1/", body: "Hello World"] do
{:ok, status_code, _headers, body} = :ibrowse.send_req('http://localhost', [], :post, 'param1=value1&param2=value2')
Expand All @@ -55,6 +71,22 @@ defmodule ExVCR.Adapter.HandlerStubModeTest do
end
end

test "request_body matches as unordered list of params" do
use_cassette :stub, [url: 'http://localhost', method: :post, request_body: "param1=10&param3=30&param2=20", body: "Hello World"] do
{:ok, status_code, _headers, body} = :ibrowse.send_req('http://localhost', [], :post, 'param2=20&param1=10&param3=30')
assert status_code == '200'
assert to_string(body) =~ ~r/Hello World/
end
end

test "request_body mismatches as unordered list of params" do
assert_raise ExVCR.InvalidRequestError, fn ->
use_cassette :stub, [url: 'http://localhost', method: :post, request_body: "param1=10&param3=30&param4=40", body: "Hello World"] do
{:ok, _status_code, _headers, _body} = :ibrowse.send_req('http://localhost', [], :post, 'param2=20&param1=10&param3=30')
end
end
end

test "request_body mismatch should raise error" do
assert_raise ExVCR.InvalidRequestError, fn ->
use_cassette :stub, [url: 'http://localhost', method: :post, request_body: '{"one" => 1}'] do
Expand Down
0