• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

parroty / exvcr / f6cc9bc0ae05f24b374e6c1fa9b52e9d0967e032-PR-202

pending completion
f6cc9bc0ae05f24b374e6c1fa9b52e9d0967e032-PR-202

Pull #202

github

parroty
Pull Request #202: Fix name conflict for finch test case

577 of 642 relevant lines covered (89.88%)

95.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.15
/lib/exvcr/adapter/hackney.ex
1
defmodule ExVCR.Adapter.Hackney do
2
  @moduledoc """
3
  Provides adapter methods to mock :hackney methods.
4
  """
5

6
  use ExVCR.Adapter
7
  alias ExVCR.Adapter.Hackney.Store
8
  alias ExVCR.Util
9

10
  defmacro __using__(_opts) do
11
    quote do
12
      Store.start
13
    end
14
  end
15

16
  defdelegate convert_from_string(string), to: ExVCR.Adapter.Hackney.Converter
28✔
17
  defdelegate convert_to_string(request, response), to: ExVCR.Adapter.Hackney.Converter
14✔
18
  defdelegate parse_request_body(request_body), to: ExVCR.Adapter.Hackney.Converter
42✔
19

20
  @doc """
21
  Returns the name of the mock target module.
22
  """
23
  def module_name do
24
    :hackney
25
  end
26

27
  @doc """
28
  Returns list of the mock target methods with function name and callback.
29
  Implementation for global mock.
30
  """
31
  def target_methods() do
32
    [
33
      {:request, &ExVCR.Recorder.request([&1, &2, &3, &4, &5])},
44✔
34
      {:request, &ExVCR.Recorder.request([&1, &2, &3, &4])},
×
35
      {:request, &ExVCR.Recorder.request([&1, &2, &3])},
×
36
      {:request, &ExVCR.Recorder.request([&1, &2])},
×
37
      {:request, &ExVCR.Recorder.request([&1])},
×
38
      {:body, &handle_body_request([&1])},
30✔
39
      {:body, &handle_body_request([&1, &2])}
×
40
    ]
41
  end
42

43
  @doc """
44
  Returns list of the mock target methods with function name and callback.
45
  """
46
  def target_methods(recorder) do
47
    [
48
      {:request, &ExVCR.Recorder.request(recorder, [&1, &2, &3, &4, &5])},
×
49
      {:request, &ExVCR.Recorder.request(recorder, [&1, &2, &3, &4])},
×
50
      {:request, &ExVCR.Recorder.request(recorder, [&1, &2, &3])},
×
51
      {:request, &ExVCR.Recorder.request(recorder, [&1, &2])},
×
52
      {:request, &ExVCR.Recorder.request(recorder, [&1])},
×
53
      {:body, &handle_body_request(recorder, [&1])},
×
54
      {:body, &handle_body_request(recorder, [&1, &2])}
×
55
    ]
56
  end
57

58
  @doc """
59
  Generate key for searching response.
60
  """
61
  def generate_keys_for_request(request) do
62
    url          = Enum.fetch!(request, 1)
42✔
63
    method       = Enum.fetch!(request, 0)
42✔
64
    request_body = Enum.fetch(request, 3) |> parse_request_body
42✔
65
    headers      = Enum.at(request, 2, []) |> Util.stringify_keys()
42✔
66

67
    [url: url, method: method, request_body: request_body, headers: headers]
68
  end
69

70
  @doc """
71
  Callback from ExVCR.Handler when response is retrieved from the HTTP server.
72
  """
73
  def hook_response_from_server(response) do
74
    apply_filters(response)
14✔
75
  end
76

77
  defp apply_filters({:ok, status_code, headers, reference}) do
78
    filtered_headers = ExVCR.Filter.remove_blacklisted_headers(headers)
13✔
79
    {:ok, status_code, filtered_headers, reference}
13✔
80
  end
81

82
  defp apply_filters({:ok, status_code, headers}) do
83
    filtered_headers = ExVCR.Filter.remove_blacklisted_headers(headers)
×
84
    {:ok, status_code, filtered_headers}
×
85
  end
86

87
  defp apply_filters({:error, reason}) do
88
    {:error, reason}
89
  end
90

91
  @doc """
92
  Callback from ExVCR.Handler when response is retrieved from the json file cache.
93
  """
94
  def hook_response_from_cache(_request, nil), do: nil
95
  def hook_response_from_cache(_request, %ExVCR.Response{type: "error"} = response), do: response
2✔
96
  def hook_response_from_cache(_request, %ExVCR.Response{body: nil} = response), do: response
2✔
97
  def hook_response_from_cache([_, _, _, _, opts], %ExVCR.Response{body: body} = response) do
98
    if :with_body in opts || {:with_body, true} in opts do
24✔
99
      response
5✔
100
    else
101
      client          = make_ref()
19✔
102
      client_key_atom = client |> inspect |> String.to_atom
19✔
103
      Store.set(client_key_atom, body)
19✔
104
      %{response | body: client}
19✔
105
    end
106
  end
107

108
  defp handle_body_request(args) do
109
    ExVCR.Actor.CurrentRecorder.get()
110
    |> handle_body_request(args)
30✔
111
  end
112

113
  defp handle_body_request(nil, args) do
114
    :meck.passthrough(args)
×
115
  end
116

117
  defp handle_body_request(recorder, [client]) do
118
    handle_body_request(recorder, [client, :infinity])
30✔
119
  end
120

121
  defp handle_body_request(recorder, [client, max_length]) do
122
    client_key_atom = client |> inspect |> String.to_atom
30✔
123
    if body = Store.get(client_key_atom) do
30✔
124
      Store.delete(client_key_atom)
19✔
125
      {:ok, body}
126
    else
127
      case :meck.passthrough([client, max_length]) do
11✔
128
        {:ok, body} ->
129
          body = ExVCR.Filter.filter_sensitive_data(body)
10✔
130

131
          client_key_string = inspect(client)
10✔
132
          ExVCR.Recorder.update(recorder,
10✔
133
            fn(%{request: _request, response: response}) ->
134
              response.body == client_key_string
10✔
135
            end,
136
            fn(%{request: request, response: response}) ->
137
              %{request: request, response: %{response | body: body}}
10✔
138
            end
139
          )
140
          {:ok, body}
141
        {ret, body} ->
142
          {ret, body}
143
      end
144
    end
145
  end
146

147
  @doc """
148
  Returns the response from the ExVCR.Reponse record.
149
  """
150
  def get_response_value_from_cache(response) do
151
    if response.type == "error" do
28✔
152
      {:error, response.body}
2✔
153
    else
154
      case response.body do
26✔
155
        nil -> {:ok, response.status_code, response.headers}
2✔
156
        _   -> {:ok, response.status_code, response.headers, response.body}
24✔
157
      end
158
    end
159
  end
160

161
  @doc """
162
  Default definitions for stub.
163
  """
164
  def default_stub_params(:headers), do: %{"Content-Type" => "text/html"}
2✔
165
  def default_stub_params(:status_code), do: 200
166
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc