Skip to content

Commit

Permalink
Added support to ignore_urls (#168)
Browse files Browse the repository at this point in the history
* Added ignore_urls support

* Fix ignore_localhost and strict_mode
  • Loading branch information
diegonogueira authored Apr 29, 2021
1 parent de7f631 commit 68b4ae1
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 5 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ erl_crash.dump
*.ez
/tmp
/_build
/doc
/doc
.dockerignore
.devcontainer
Dockerfile
docker-compose.yml
1 change: 1 addition & 0 deletions fixture/vcr_cassettes/ignore_urls_on.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
44 changes: 44 additions & 0 deletions fixture/vcr_cassettes/ignore_urls_unset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://localhost:34006/server"
},
"response": {
"binary": false,
"body": "test_response_before",
"headers": {
"server": "Cowboy",
"date": "Sun, 08 Apr 2018 12:50:46 GMT",
"content-length": "20"
},
"status_code": 200,
"type": "ok"
}
},
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://127.0.0.1:34006/server"
},
"response": {
"binary": false,
"body": "test_response_before",
"headers": {
"server": "Cowboy",
"date": "Sun, 08 Apr 2018 12:50:46 GMT",
"content-length": "20"
},
"status_code": 200,
"type": "ok"
}
}
]
25 changes: 25 additions & 0 deletions fixture/vcr_cassettes/ignore_urls_with_headers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[
{
"request": {
"body": "",
"headers": {
"User-Agent": "ExVCR"
},
"method": "get",
"options": [],
"request_body": "",
"url": "http://127.0.0.1:34006/server"
},
"response": {
"binary": false,
"body": "test_response_before",
"headers": {
"server": "Cowboy",
"date": "Tue, 20 Apr 2021 13:54:51 GMT",
"content-length": "20"
},
"status_code": 200,
"type": "ok"
}
}
]
7 changes: 7 additions & 0 deletions lib/exvcr/config.ex
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ defmodule ExVCR.Config do
Setting.set(:ignore_localhost, value)
end

@doc """
Skip recording cassettes for urls requests when set
"""
def ignore_urls(value) do
Setting.set(:ignore_urls, value)
end

@doc """
Throw error if there is no matching cassette for an HTTP request
"""
Expand Down
4 changes: 4 additions & 0 deletions lib/exvcr/config_loader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ defmodule ExVCR.ConfigLoader do
Config.ignore_localhost(env[:ignore_localhost])
end

if env[:ignore_urls] != nil do
Config.ignore_urls(env[:ignore_urls])
end

if env[:strict_mode] != nil do
Config.strict_mode(env[:strict_mode])
end
Expand Down
33 changes: 29 additions & 4 deletions lib/exvcr/handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ defmodule ExVCR.Handler do
Provide operations for request/response.
"""

alias ExVCR.Recorder
alias ExVCR.{Recorder, Setting, Util}
alias ExVCR.Actor.Options
alias ExVCR.Util

@doc """
Get response from either server or cache.
Expand Down Expand Up @@ -175,7 +174,14 @@ defmodule ExVCR.Handler do
end

defp ignore_request?(request, recorder) do
ignore_localhost = ExVCR.Recorder.options(recorder)[:ignore_localhost] || ExVCR.Setting.get(:ignore_localhost)
ignore_localhost?(request, recorder) ||
ignore_urls?(request, recorder)
end

defp ignore_localhost?(request, recorder) do
ignore_localhost =
Keyword.get(Recorder.options(recorder), :ignore_localhost, Setting.get(:ignore_localhost))

if ignore_localhost do
adapter = ExVCR.Recorder.options(recorder)[:adapter]
params = adapter.generate_keys_for_request(request)
Expand All @@ -187,8 +193,27 @@ defmodule ExVCR.Handler do
end
end

defp ignore_urls?(request, recorder) do
ignore_urls = ExVCR.Recorder.options(recorder)[:ignore_urls] || ExVCR.Setting.get(:ignore_urls)

if ignore_urls do
adapter = ExVCR.Recorder.options(recorder)[:adapter]
params = adapter.generate_keys_for_request(request)

url = to_string(params[:url])

Enum.any?(ignore_urls, fn r_url ->
Regex.match?(r_url, url)
end)
else
false
end
end

defp ignore_server_fetch!(request, recorder) do
strict_mode = ExVCR.Recorder.options(recorder)[:strict_mode] || ExVCR.Setting.get(:strict_mode)
strict_mode =
Keyword.get(Recorder.options(recorder), :strict_mode, Setting.get(:strict_mode))

if strict_mode do
message = """
A matching cassette was not found for this request.
Expand Down
16 changes: 16 additions & 0 deletions test/ignore_localhost_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,20 @@ defmodule ExVCR.IgnoreLocalhostTest do
HttpServer.stop(@port)
end
end

test "it records localhost requests when overrides the config setting" do
ExVCR.Setting.set(:ignore_localhost, true)

use_cassette "ignore_localhost_unset", ignore_localhost: false do
HttpServer.start(path: "/server", port: @port, response: "test_response_before")
assert HTTPotion.get(@url, []).body =~ ~r/test_response_before/
HttpServer.stop(@port)
# this method call should be mocked
HttpServer.start(path: "/server", port: @port, response: "test_response_after")
assert HTTPotion.get(@url, []).body =~ ~r/test_response_before/
HttpServer.stop(@port)
end

ExVCR.Setting.set(:strict_mode, false)
end
end
63 changes: 63 additions & 0 deletions test/ignore_urls_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
defmodule ExVCR.IgnoreUrlsTest do
use ExVCR.Mock
use ExUnit.Case, async: false

@port 34006
@url "http://localhost:#{@port}/server"
@ignore_urls [
~r/http:\/\/localhost.*/,
~r/http:\/\/127\.0\.0\.1.*/
]

setup_all do
HTTPotion.start
:ok
end

test "it does not record url requests when the config has been set" do
use_cassette "ignore_urls_on", ignore_urls: @ignore_urls do
HttpServer.start(path: "/server", port: @port, response: "test_response_before")
assert HTTPotion.get(@url, []).body =~ ~r/test_response_before/
HttpServer.stop(@port)
# this method call should NOT be mocked
HttpServer.start(path: "/server", port: @port, response: "test_response_after")
assert HTTPotion.get(@url, []).body =~ ~r/test_response_after/
HttpServer.stop(@port)
# this method call should NOT be mocked
non_localhost_url = "http://127.0.0.1:#{@port}/server"
HttpServer.start(path: "/server", port: @port, response: "test_response_after")
assert HTTPotion.get(non_localhost_url, []).body =~ ~r/test_response_after/
HttpServer.stop(@port)
end
end

test "it records urls requests when the config has not been set" do
use_cassette "ignore_urls_unset" do
HttpServer.start(path: "/server", port: @port, response: "test_response_before")
assert HTTPotion.get(@url, []).body =~ ~r/test_response_before/
HttpServer.stop(@port)
# this method call should be mocked
HttpServer.start(path: "/server", port: @port, response: "test_response_after")
assert HTTPotion.get(@url, []).body =~ ~r/test_response_before/
HttpServer.stop(@port)
# this method call should NOT be mocked
non_localhost_url = "http://127.0.0.1:#{@port}/server"
HttpServer.start(path: "/server", port: @port, response: "test_response_after")
assert HTTPotion.get(non_localhost_url, []).body =~ ~r/test_response_before/
HttpServer.stop(@port)
end
end

test "ignore_urls option works with request headers" do
use_cassette "ignore_urls_with_headers", ignore_urls: @ignore_urls do
HttpServer.start(path: "/server", port: @port, response: "test_response_after")
assert HTTPotion.get(@url, headers: ["User-Agent": "ExVCR"]).body =~ ~r/test_response_after/
HttpServer.stop(@port)
# this method call should be mocked
non_localhost_url = "http://127.0.0.1:#{@port}/server"
HttpServer.start(path: "/server", port: @port, response: "test_response_before")
assert HTTPotion.get(non_localhost_url, headers: ["User-Agent": "ExVCR"]).body =~ ~r/test_response_before/
HttpServer.stop(@port)
end
end
end
18 changes: 18 additions & 0 deletions test/strict_mode_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,22 @@ defmodule ExVCR.StrictModeTest do
assert HTTPotion.get(@url, []).body =~ ~r/test_response/
end
end

test "it does not uses a cassette when override the defaut config" do
ExVCR.Setting.set(:strict_mode, true)

use_cassette "strict_mode_cassette", strict_mode: false do
assert HTTPotion.get(@url, []).body =~ ~r/test_response/
end

use_cassette "strict_mode_cassette" do
assert HTTPotion.get(@url, []).body =~ ~r/test_response/
end

use_cassette "strict_mode_cassette", strict_mode: true do
assert HTTPotion.get(@url, []).body =~ ~r/test_response/
end

ExVCR.Setting.set(:strict_mode, false)
end
end

0 comments on commit 68b4ae1

Please sign in to comment.