Skip to content

Commit

Permalink
Merge ab692f5 into b849240
Browse files Browse the repository at this point in the history
  • Loading branch information
myronmarston committed Nov 1, 2016
2 parents b849240 + ab692f5 commit 9c1e83d
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 19 deletions.
32 changes: 32 additions & 0 deletions fixture/vcr_cassettes/hackney_with_body.json
@@ -0,0 +1,32 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": {
"with_body": true
},
"request_body": "",
"url": "http://www.example.com"
},
"response": {
"body": "\"<!doctype html>\\n<html>\\n<head>\\n <title>Example Domain</title>\\n\\n <meta charset=\\\"utf-8\\\" />\\n <meta http-equiv=\\\"Content-type\\\" content=\\\"text/html; charset=utf-8\\\" />\\n <meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1\\\" />\\n <style type=\\\"text/css\\\">\\n body {\\n background-color: #f0f0f2;\\n margin: 0;\\n padding: 0;\\n font-family: \\\"Open Sans\\\", \\\"Helvetica Neue\\\", Helvetica, Arial, sans-serif;\\n \\n }\\n div {\\n width: 600px;\\n margin: 5em auto;\\n padding: 50px;\\n background-color: #fff;\\n border-radius: 1em;\\n }\\n a:link, a:visited {\\n color: #38488f;\\n text-decoration: none;\\n }\\n @media (max-width: 700px) {\\n body {\\n background-color: #fff;\\n }\\n div {\\n width: auto;\\n margin: 0 auto;\\n border-radius: 0;\\n padding: 1em;\\n }\\n }\\n </style> \\n</head>\\n\\n<body>\\n<div>\\n <h1>Example Domain</h1>\\n <p>This domain is established to be used for illustrative examples in documents. You may use this\\n domain in examples without prior coordination or asking for permission.</p>\\n <p><a href=\\\"http://www.iana.org/domains/example\\\">More information...</a></p>\\n</div>\\n</body>\\n</html>\\n\"",
"headers": {
"Cache-Control": "max-age=604800",
"Content-Type": "text/html",
"Date": "Tue, 01 Nov 2016 04:58:34 GMT",
"Etag": "\"359670651+ident\"",
"Expires": "Tue, 08 Nov 2016 04:58:34 GMT",
"Last-Modified": "Fri, 09 Aug 2013 23:54:35 GMT",
"Server": "ECS (pae/3796)",
"Vary": "Accept-Encoding",
"X-Cache": "HIT",
"x-ec-custom-error": "1",
"Content-Length": "1270"
},
"status_code": 200,
"type": "ok"
}
}
]
4 changes: 2 additions & 2 deletions lib/exvcr/adapter.ex
Expand Up @@ -33,8 +33,8 @@ defmodule ExVCR.Adapter do
@doc """
Callback from ExVCR.Handler when response is retrieved from the json file cache.
"""
def hook_response_from_cache(response), do: response
defoverridable [hook_response_from_cache: 1]
def hook_response_from_cache(_request, response), do: response
defoverridable [hook_response_from_cache: 2]

@doc """
Callback from ExVCR.Handler to get the response content tuple from the ExVCR.Reponse record.
Expand Down
18 changes: 11 additions & 7 deletions lib/exvcr/adapter/hackney.ex
Expand Up @@ -63,13 +63,17 @@ defmodule ExVCR.Adapter.Hackney do
@doc """
Callback from ExVCR.Handler when response is retrieved from the json file cache.
"""
def hook_response_from_cache(nil), do: nil
def hook_response_from_cache(%ExVCR.Response{type: "error"} = response), do: response
def hook_response_from_cache(%ExVCR.Response{body: body} = response) do
client = make_ref()
client_key_atom = client |> inspect |> String.to_atom
Store.set(client_key_atom, body)
%{response | body: client}
def hook_response_from_cache(_request, nil), do: nil
def hook_response_from_cache(_request, %ExVCR.Response{type: "error"} = response), do: response
def hook_response_from_cache([_, _, _, _, opts], %ExVCR.Response{body: body} = response) do
if :with_body in opts || {:with_body, true} in opts do
response
else
client = make_ref()
client_key_atom = client |> inspect |> String.to_atom
Store.set(client_key_atom, body)
%{response | body: client}
end
end

defp handle_body_request(recorder, [client]) do
Expand Down
26 changes: 17 additions & 9 deletions lib/exvcr/adapter/hackney/converter.ex
Expand Up @@ -32,22 +32,30 @@ defmodule ExVCR.Adapter.Hackney.Converter do

# If option value is tuple, make it as list, for encoding as json.
defp sanitize_options(options) do
Enum.map(options, fn({key, value}) ->
if is_tuple(value) do
{key, Tuple.to_list(value)}
else
{key, value}
end
Enum.map(options, fn
{key, value} ->
if is_tuple(value) do
{key, Tuple.to_list(value)}
else
{key, value}
end
key when is_atom(key) ->
{key, true}
end)
end

# Client is already replaced by body through ExVCR.Adapter.Hackney adapter.
defp response_to_string({:ok, status_code, headers, client}) do
defp response_to_string({:ok, status_code, headers, body_or_client}) do
body = case body_or_client do
string when is_binary(string) -> string
# Client is already replaced by body through ExVCR.Adapter.Hackney adapter.
ref when is_reference(ref) -> inspect(ref)
end

%ExVCR.Response{
type: "ok",
status_code: status_code,
headers: parse_headers(headers),
body: inspect client
body: body
}
end

Expand Down
2 changes: 1 addition & 1 deletion lib/exvcr/handler.ex
Expand Up @@ -22,7 +22,7 @@ defmodule ExVCR.Handler do
adapter = ExVCR.Recorder.options(recorder)[:adapter]
params = adapter.generate_keys_for_request(request)
{response, responses} = find_response(Recorder.get(recorder), params, recorder_options)
response = adapter.hook_response_from_cache(response)
response = adapter.hook_response_from_cache(request, response)

case { response, stub_mode?(recorder_options) } do
{ nil, true } ->
Expand Down
13 changes: 13 additions & 0 deletions test/adapter_hackney_test.exs
Expand Up @@ -152,6 +152,19 @@ defmodule ExVCR.Adapter.HackneyTest do
end
end

for option <- [:with_body, {:with_body, true}] do
@option option

test "request using `#{inspect option}` option" do
use_cassette "hackney_with_body" do
{:ok, status_code, headers, body} = :hackney.request(:get, "http://www.example.com", [], [], [@option])
assert body =~ ~r/Example Domain/
assert status_code == 200
assert List.keyfind(headers, "Content-Type", 0) == {"Content-Type", "text/html"}
end
end
end

defp assert_response(response, function \\ nil) do
assert response.status_code == 200
assert is_binary(response.body)
Expand Down
21 changes: 21 additions & 0 deletions test/recorder_hackney_test.exs
Expand Up @@ -8,6 +8,8 @@ defmodule ExVCR.RecorderHackneyTest do
@url_with_query "http://localhost:#{@port}/server?password=sample"

setup_all do
File.rm_rf(@dummy_cassette_dir)

on_exit fn ->
File.rm_rf(@dummy_cassette_dir)
HttpServer.stop(@port)
Expand Down Expand Up @@ -103,4 +105,23 @@ defmodule ExVCR.RecorderHackneyTest do

ExVCR.Config.response_headers_blacklist([])
end

for option <- [:with_body, {:with_body, true}] do
@option option

test "request using `#{inspect option}` option records and replays the same thing" do
recorded_body = use_cassette_with_hackney(@option)
assert recorded_body =~ ~r/test_response/
replayed_body = use_cassette_with_hackney(@option)
assert replayed_body == recorded_body
end
end

defp use_cassette_with_hackney(option) do
use_cassette "record_hackney_with_body_#{inspect option}" do
{:ok, status_code, _headers, body} = :hackney.request(:get, @url, [], [], [option])
assert status_code == 200
body
end
end
end

0 comments on commit 9c1e83d

Please sign in to comment.