faraday-hot_mock 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4f1312baf1b9659238322e8f0700f7dffcc1eb5854e6c827d35ad86d9d2f7652
4
+ data.tar.gz: 8bb84381f365ac2bbc02b2fbfabec03824a092f61dfe9f14985e678d9be3254c
5
+ SHA512:
6
+ metadata.gz: 2e7e4946d1afee93a8732a00fd667c58d091faf3d2b3b83e7814f446fc03e44a53212996174f762e70d31d7d176e353055565e9ee31095654745a50e4f324008
7
+ data.tar.gz: 84ebe958dfe19c87eb636edf000f6dc2533528a7cfd304eb762c5d1198cf8820fc5397c55ef545413f5118be522b216aea849737b1bb2eec984c9811573d1327
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright Sean Hogge
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Faraday::HotMock
2
+
3
+ When using Faraday with Rails to develop an API integration, it can be challenging to simulate errors from the API if they don't provide a mechanism for doing so.
4
+
5
+ This adapter attempts to make that simpler by parsing YAML files at runtime. If a match exists in any YAML file in the proper location, that response is returned. If no match exists, a real call is made.
6
+
7
+ _**This adapter is meant for Faraday usage in Rails, not for Faraday that's used in other frameworks or situations.**_
8
+
9
+
10
+ ## Usage
11
+
12
+ Create YAML files in `lib/faraday/mocks/#{Rails.env}` - the name of the files doesn't matter, and you can nest them in subdirectories.
13
+
14
+ This means that if you have a Staging environment, or a UAT environment along with a Demo and Development environment, you can mock each separately.
15
+
16
+ You can organize your per-environment mocks as you see fit - all in one file, or split between descriptive directories and file names.
17
+
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```ruby
24
+ gem "faraday-hot_mock", git: "https://github.com/seanhogge/faraday-hot_mock"
25
+ ```
26
+
27
+ And then execute:
28
+ ```bash
29
+ $ bundle
30
+ ```
31
+
32
+ Then, use this adapter in your middleware pipeline, making sure that it's last:
33
+
34
+ ```ruby
35
+ @conn = Faraday.new(url: "https://dog.ceo/api/") do |faraday|
36
+ faraday.request :json
37
+ faraday.response :json
38
+ faraday.adapter :hot_mock
39
+ end
40
+ ```
41
+
42
+ Optionally, specify a fallback adapter (`Faraday.default_adapter` is the default) - this is what will be used if a matching mock can't be found. It's unlikely you will ever need to specify the fallback.
43
+
44
+ ```ruby
45
+ @conn = Faraday.new(url: "https://dog.ceo/api/") do |faraday|
46
+ faraday.request :json
47
+ faraday.response :json
48
+ faraday.adapter :hot_mock, fallback: :cool_community_adapter
49
+ end
50
+ ```
51
+
52
+ Then add the switch: `tmp/mocking-#{Rails.env}.txt`. Just like Rails' own `tmp/caching-dev.txt` file, this will toggle HotMock on when present, and off when not present.
53
+
54
+ > ⚠️ REMEMBER: For caching, it's `tmp/caching-dev.txt`, but for mocking it's `tmp/mocking-development.txt`
55
+
56
+ Now, create the directory `lib/faraday/mocks/` and a subdirectory for each environment you want to hot mock. Within that directory, create whatever files and subdirectories you like.
57
+
58
+ > ⚠️ REMEMBER: it's `lib/faraday/mocks`, not `app/lib/faraday/mocks`
59
+
60
+ Consider adding these directories to .gitignore unless you want mocks to be shared.
61
+
62
+ ```yaml
63
+ # lib/faraday/mocks/development/vendor_name_mocks.yml
64
+ - url_pattern: vendorname.com.*/endpoint
65
+ method: POST
66
+ status: 418
67
+ headers:
68
+ Content-Type: application/json
69
+ body:
70
+ error: I'm a teapot
71
+ ```
72
+
73
+ Now, any POST request made to `vendorname.com/api/v1/endpoint` will return a mock 418 response with a JSON body. A GET to the same endpoint will make the actual call.
74
+
75
+ If you edit the file to be:
76
+
77
+ ```yaml
78
+ # lib/faraday/mocks/development/vendor_name_mocks.yml
79
+ - url_pattern: vendorname.com.*/endpoint
80
+ method: POST
81
+ status: 503
82
+ headers:
83
+ Content-Type: application/json
84
+ body:
85
+ error: Service Unavailable
86
+ ```
87
+
88
+ then the next request made to `vendorname.com/api/v1/endpoint` will return a mock 503 response with a JSON body. No need to reload anything.
89
+
90
+ This lets you quickly simulate any type of response you need.
91
+
92
+ If you want to disable mocks, you can:
93
+
94
+ - Comment out individual entries
95
+ - Comment out entire files
96
+ - Rename the directory from "development" to "development-disabled" or anything that isn't a Rails environment name
97
+ - Delete the entry
98
+ - Delete the file(s)
99
+ - Delete the directory
100
+
101
+ If you'd rather keep the file(s) around, just delete `tmp/mocking-development.txt`. That will globally disable any mocked responses.
102
+
103
+
104
+ ## Contributing
105
+
106
+ Fork, work, PR while following the [Code of Conduct](https://github.com/seanhogge/faraday-hot_mock/CODE_OF_CONDUCT.md)
107
+
108
+
109
+ ## License
110
+
111
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "pathname"
5
+ require "faraday"
6
+
7
+ module Faraday
8
+ module HotMock
9
+ class Adapter < Faraday::Adapter
10
+ def initialize(app, options = {})
11
+ super(app)
12
+ @mock_dir = options[:mock_dir] || default_mock_dir
13
+ @enabled_file = options[:enabled_file] || "tmp/mocking-#{Rails.env}.txt"
14
+ fallback = options[:fallback] || Faraday.default_adapter
15
+ @fallback_adapter = Faraday::Adapter.lookup_middleware(fallback)
16
+ @mocks = load_mocks
17
+ end
18
+
19
+ def call(env)
20
+ super
21
+ if mocking_enabled? && @mocks && (mock = find_mock(env.method, env.url))
22
+ save_response(env, mock["status"] || 200, mock["body"] || "", mock["headers"] || {})
23
+ else
24
+ @fallback_adapter.new(@app, @options).call(env)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def load_mocks
31
+ return [] unless Dir.exist?(Rails.root.join @mock_dir)
32
+
33
+ mocks = []
34
+
35
+ yaml_files.each do |file|
36
+ file_mocks = YAML.load_file(file)
37
+ mocks.concat(file_mocks) if file_mocks.is_a?(Array)
38
+ end
39
+
40
+ mocks
41
+ end
42
+
43
+ def mocking_enabled?
44
+ File.exist?(Rails.root.join @enabled_file)
45
+ end
46
+
47
+ def default_mock_dir
48
+ rails_env = defined?(Rails) ? Rails.env : ENV["RAILS_ENV"] || "development"
49
+ "lib/faraday/mocks/#{rails_env}"
50
+ end
51
+
52
+ def find_mock(method, url)
53
+ return nil unless @mocks.any?
54
+
55
+ @mocks.find do |mock|
56
+ url_matches = Regexp.new(mock["url_pattern"]).match?(url)
57
+ method_matches = mock["method"].nil? || mock["method"].to_s.upcase == method.to_s.upcase
58
+
59
+ url_matches && method_matches
60
+ end
61
+ end
62
+
63
+ def yaml_files
64
+ Dir.glob(File.join(Rails.root.join(@mock_dir), "**", "*.{yml,yaml}"))
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,6 @@
1
+ module Faraday
2
+ module HotMock
3
+ class Railtie < ::Rails::Railtie
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Faraday
2
+ module HotMock
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ require "faraday/hot_mock/version"
2
+ require "faraday/hot_mock/railtie"
3
+ require "faraday/hot_mock/adapter"
4
+ require "faraday"
5
+
6
+ module Faraday
7
+ module HotMock
8
+ end
9
+ end
10
+
11
+ Faraday::Adapter.register_middleware hot_mock: Faraday::HotMock::Adapter
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :faraday_hot_mock do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: faraday-hot_mock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sean Hogge
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rails
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '7'
26
+ - !ruby/object:Gem::Dependency
27
+ name: faraday
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: '3'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '2'
43
+ - - "<"
44
+ - !ruby/object:Gem::Version
45
+ version: '3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: pry
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ type: :development
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ description: Faraday middleware for simple mocking of Faraday requests per environment
61
+ by means of YAML files read at runtime.
62
+ email:
63
+ - sean@seanhogge.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - MIT-LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - lib/faraday/hot_mock.rb
72
+ - lib/faraday/hot_mock/adapter.rb
73
+ - lib/faraday/hot_mock/railtie.rb
74
+ - lib/faraday/hot_mock/version.rb
75
+ - lib/tasks/faraday/hot_mock_tasks.rake
76
+ homepage: https://github.com/seanhogge/faraday-hot_mock
77
+ licenses:
78
+ - MIT
79
+ metadata:
80
+ allowed_push_host: https://rubygems.org
81
+ homepage_uri: https://github.com/seanhogge/faraday-hot_mock
82
+ source_code_uri: https://github.com/seanhogge/faraday-hot_mock
83
+ changelog_uri: https://github.com/seanhogge/faraday-hot_mock/CHANGELOG.md
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '3.2'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubygems_version: 3.6.8
99
+ specification_version: 4
100
+ summary: Faraday middleware for simple mocking of Faraday requests per environment.
101
+ test_files: []