Skip to content

Commit

Permalink
Add Finch support (#175)
Browse files Browse the repository at this point in the history
* Add Finch support

* Start telemetry app for tests to get rid of warning logs

* Change test matrix to cover OTP21,23 and Elixir 1.10,1.11

* Update excoveralls to fix 'Handshake Failure' on OTP 23

* Remove old TODOs

* (De)serialize error reason struct using Elixir core functions

* Update README to indicate Finch support
  • Loading branch information
reisub authored Aug 3, 2021
1 parent a8e4a85 commit 9318245
Show file tree
Hide file tree
Showing 25 changed files with 928 additions and 10 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
otp: ['20.3']
elixir: ['1.5', '1.9']
otp: ['21','23']
elixir: ['1.10', '1.11']
global-mock: [true, false]
env:
MIX_ENV: test
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ The following HTTP libraries can be applied.
- <a href="https://github.com/tim/erlang-oauth/" target="_blank">erlang-oauth</a>
- <a href="https://github.com/Zatvobor/tirexs" target="_blank">tirexs</a>
- support is very limited, and tested only with `:httpc.request/1` and `:httpc.request/4`.
- <a href="https://github.com/keathley/finch" target="_blank">Finch</a>
- the deprecated `Finch.request/6` functions is not supported

HTTP interactions are recorded as JSON file. The JSON file can be recorded
automatically (`vcr_cassettes`) or manually updated (`custom_cassettes`).
Expand Down Expand Up @@ -99,6 +101,7 @@ defmodule ExVCR.Adapter.HackneyTest do

setup_all do
HTTPoison.start
:ok
end

test "get request" do
Expand All @@ -118,6 +121,7 @@ defmodule ExVCR.Adapter.HttpcTest do

setup_all do
:inets.start
:ok
end

test "get request" do
Expand All @@ -127,6 +131,30 @@ defmodule ExVCR.Adapter.HttpcTest do
assert to_string(body) =~ ~r/Example Domain/
end
end
end
```

##### Example with Finch

```Elixir
defmodule ExVCR.Adapter.FinchTest do
use ExUnit.Case, async: true
use ExVCR.Mock, adapter: ExVCR.Adapter.Finch

setup_all do
Finch.start_link(name: MyFinch)
:ok
end

test "get request" do
use_cassette "example_finch_request" do
{:ok, response} = Finch.build(:get, "http://example.com/") |> Finch.request(MyFinch)
assert response.status == 200
assert Map.new(response.headers)["content-type"] == "text/html; charset=UTF-8"
assert response.body =~ ~r/Example Domain/
end
end
end
```

#### Custom Cassettes
Expand Down
19 changes: 19 additions & 0 deletions fixture/custom_cassettes/finch_generic_string_error.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"body": "%{reason: \"some made up error which could happen, in theory\"}",
"headers": [],
"status_code": null,
"type": "error"
}
}
]
19 changes: 19 additions & 0 deletions fixture/custom_cassettes/finch_generic_timeout_error.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"body": "%{reason: :timeout}",
"headers": [],
"status_code": null,
"type": "error"
}
}
]
19 changes: 19 additions & 0 deletions fixture/custom_cassettes/finch_httperror.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"body": "%Mint.HTTPError{module: Mint.HTTP2, reason: :too_many_concurrent_requests}",
"headers": [],
"status_code": null,
"type": "error"
}
}
]
19 changes: 19 additions & 0 deletions fixture/custom_cassettes/finch_tuple_transport_error.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"body": "%Mint.TransportError{reason: {:bad_alpn_protocol, \"h3\"}}",
"headers": [],
"status_code": null,
"type": "error"
}
}
]
19 changes: 19 additions & 0 deletions fixture/vcr_cassettes/error_finch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://invalid_url/"
},
"response": {
"binary": false,
"body": "%Mint.TransportError{reason: :nxdomain}",
"headers": [],
"status_code": null,
"type": "error"
}
}
]
31 changes: 31 additions & 0 deletions fixture/vcr_cassettes/example_finch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"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: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n \n }\n div {\n width: 600px;\n margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n }\n a:link, a:visited {\n color: #38488f;\n text-decoration: none;\n }\n @media (max-width: 700px) {\n div {\n margin: 0 auto;\n width: auto;\n }\n }\n </style> \n</head>\n\n<body>\n<div>\n <h1>Example Domain</h1>\n <p>This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.</p>\n <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n",
"headers": {
"age": "355150",
"cache-control": "max-age=604800",
"content-type": "text/html; charset=UTF-8",
"date": "Wed, 28 Jul 2021 19:21:33 GMT",
"etag": "\"3147526947+ident\"",
"expires": "Wed, 04 Aug 2021 19:21:33 GMT",
"last-modified": "Thu, 17 Oct 2019 07:18:26 GMT",
"server": "ECS (bsa/EB17)",
"vary": "Accept-Encoding",
"x-cache": "HIT",
"content-length": "1256"
},
"status_code": 200,
"type": "ok"
}
}
]
31 changes: 31 additions & 0 deletions fixture/vcr_cassettes/example_finch_different.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"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: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n \n }\n div {\n width: 600px;\n margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n }\n a:link, a:visited {\n color: #38488f;\n text-decoration: none;\n }\n @media (max-width: 700px) {\n div {\n margin: 0 auto;\n width: auto;\n }\n }\n </style> \n</head>\n\n<body>\n<div>\n <h1>Example Domain</h1>\n <p>This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.</p>\n <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n",
"headers": {
"age": "538495",
"cache-control": "max-age=604800",
"content-type": "text/html; charset=UTF-8",
"date": "Wed, 28 Jul 2021 19:21:35 GMT",
"etag": "\"3147526947+ident\"",
"expires": "Wed, 04 Aug 2021 19:21:35 GMT",
"last-modified": "Thu, 17 Oct 2019 07:18:26 GMT",
"server": "ECS (bsa/EB23)",
"vary": "Accept-Encoding",
"x-cache": "HIT",
"content-length": "1256"
},
"status_code": 200,
"type": "ok"
}
}
]
60 changes: 60 additions & 0 deletions fixture/vcr_cassettes/example_finch_multiple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"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: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n \n }\n div {\n width: 600px;\n margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n }\n a:link, a:visited {\n color: #38488f;\n text-decoration: none;\n }\n @media (max-width: 700px) {\n div {\n margin: 0 auto;\n width: auto;\n }\n }\n </style> \n</head>\n\n<body>\n<div>\n <h1>Example Domain</h1>\n <p>This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.</p>\n <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n",
"headers": {
"age": "355150",
"cache-control": "max-age=604800",
"content-type": "text/html; charset=UTF-8",
"date": "Wed, 28 Jul 2021 19:21:33 GMT",
"etag": "\"3147526947+ident\"",
"expires": "Wed, 04 Aug 2021 19:21:33 GMT",
"last-modified": "Thu, 17 Oct 2019 07:18:26 GMT",
"server": "ECS (bsa/EB17)",
"vary": "Accept-Encoding",
"x-cache": "HIT",
"content-length": "1256"
},
"status_code": 200,
"type": "ok"
}
},
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://example.com/2"
},
"response": {
"binary": false,
"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: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", \"Open Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n \n }\n div {\n width: 600px;\n margin: 5em auto;\n padding: 2em;\n background-color: #fdfdff;\n border-radius: 0.5em;\n box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);\n }\n a:link, a:visited {\n color: #38488f;\n text-decoration: none;\n }\n @media (max-width: 700px) {\n div {\n margin: 0 auto;\n width: auto;\n }\n }\n </style> \n</head>\n\n<body>\n<div>\n <h1>Example Domain</h1>\n <p>This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.</p>\n <p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n</div>\n</body>\n</html>\n",
"headers": {
"accept-ranges": "bytes",
"age": "213974",
"cache-control": "max-age=604800",
"content-type": "text/html; charset=UTF-8",
"date": "Wed, 28 Jul 2021 19:21:34 GMT",
"expires": "Wed, 04 Aug 2021 19:21:34 GMT",
"last-modified": "Mon, 26 Jul 2021 07:55:21 GMT",
"server": "ECS (bsa/EB16)",
"vary": "Accept-Encoding",
"x-cache": "404-HIT",
"content-length": "1256"
},
"status_code": 404,
"type": "ok"
}
}
]
29 changes: 29 additions & 0 deletions fixture/vcr_cassettes/finch_delete.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "delete",
"options": {
"receive_timeout": 10000
},
"request_body": "",
"url": "http://httpbin.org/delete"
},
"response": {
"binary": false,
"body": "{\n \"args\": {}, \n \"data\": \"\", \n \"files\": {}, \n \"form\": {}, \n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"User-Agent\": \"mint/1.3.0\", \n \"X-Amzn-Trace-Id\": \"Root=1-6101ae3f-0ad32f626360baed57e12388\"\n }, \n \"json\": null, \n \"origin\": \"31.217.26.129\", \n \"url\": \"http://httpbin.org/delete\"\n}\n",
"headers": {
"date": "Wed, 28 Jul 2021 19:21:35 GMT",
"content-type": "application/json",
"content-length": "297",
"connection": "keep-alive",
"server": "gunicorn/19.9.0",
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true"
},
"status_code": 200,
"type": "ok"
}
}
]
23 changes: 23 additions & 0 deletions fixture/vcr_cassettes/finch_get_localhost.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": [],
"request_body": "",
"url": "http://localhost:34008/server"
},
"response": {
"binary": false,
"body": "test_response",
"headers": {
"server": "Cowboy",
"date": "Wed, 28 Jul 2021 19:21:32 GMT",
"content-length": "13"
},
"status_code": 200,
"type": "ok"
}
}
]
21 changes: 21 additions & 0 deletions fixture/vcr_cassettes/finch_get_timeout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[
{
"request": {
"body": "",
"headers": [],
"method": "get",
"options": {
"receive_timeout": 1
},
"request_body": "",
"url": "http://example.com/"
},
"response": {
"binary": false,
"body": "%Mint.TransportError{reason: :timeout}",
"headers": [],
"status_code": null,
"type": "error"
}
}
]
Loading

0 comments on commit 9318245

Please sign in to comment.