evil-client 0.3.3 → 1.0.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.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +0 -11
  3. data/.gitignore +1 -0
  4. data/.rspec +0 -1
  5. data/.rubocop.yml +22 -19
  6. data/.travis.yml +1 -0
  7. data/CHANGELOG.md +251 -6
  8. data/LICENSE.txt +3 -1
  9. data/README.md +47 -81
  10. data/docs/helpers/body.md +93 -0
  11. data/docs/helpers/connection.md +19 -0
  12. data/docs/helpers/headers.md +72 -0
  13. data/docs/helpers/http_method.md +39 -0
  14. data/docs/helpers/let.md +14 -0
  15. data/docs/helpers/logger.md +24 -0
  16. data/docs/helpers/middleware.md +56 -0
  17. data/docs/helpers/operation.md +103 -0
  18. data/docs/helpers/option.md +50 -0
  19. data/docs/helpers/path.md +37 -0
  20. data/docs/helpers/query.md +59 -0
  21. data/docs/helpers/response.md +40 -0
  22. data/docs/helpers/scope.md +121 -0
  23. data/docs/helpers/security.md +102 -0
  24. data/docs/helpers/validate.md +68 -0
  25. data/docs/index.md +70 -78
  26. data/docs/license.md +5 -1
  27. data/docs/rspec.md +96 -0
  28. data/evil-client.gemspec +10 -8
  29. data/lib/evil/client.rb +126 -72
  30. data/lib/evil/client/builder.rb +47 -0
  31. data/lib/evil/client/builder/operation.rb +40 -0
  32. data/lib/evil/client/builder/scope.rb +31 -0
  33. data/lib/evil/client/chaining.rb +17 -0
  34. data/lib/evil/client/connection.rb +60 -20
  35. data/lib/evil/client/container.rb +66 -0
  36. data/lib/evil/client/container/operation.rb +23 -0
  37. data/lib/evil/client/container/scope.rb +28 -0
  38. data/lib/evil/client/exceptions/definition_error.rb +15 -0
  39. data/lib/evil/client/exceptions/name_error.rb +32 -0
  40. data/lib/evil/client/exceptions/response_error.rb +42 -0
  41. data/lib/evil/client/exceptions/type_error.rb +29 -0
  42. data/lib/evil/client/exceptions/validation_error.rb +27 -0
  43. data/lib/evil/client/formatter.rb +49 -0
  44. data/lib/evil/client/formatter/form.rb +45 -0
  45. data/lib/evil/client/formatter/multipart.rb +33 -0
  46. data/lib/evil/client/formatter/part.rb +66 -0
  47. data/lib/evil/client/formatter/text.rb +21 -0
  48. data/lib/evil/client/resolver.rb +84 -0
  49. data/lib/evil/client/resolver/body.rb +22 -0
  50. data/lib/evil/client/resolver/format.rb +30 -0
  51. data/lib/evil/client/resolver/headers.rb +46 -0
  52. data/lib/evil/client/resolver/http_method.rb +34 -0
  53. data/lib/evil/client/resolver/middleware.rb +36 -0
  54. data/lib/evil/client/resolver/query.rb +39 -0
  55. data/lib/evil/client/resolver/request.rb +96 -0
  56. data/lib/evil/client/resolver/response.rb +26 -0
  57. data/lib/evil/client/resolver/security.rb +113 -0
  58. data/lib/evil/client/resolver/uri.rb +35 -0
  59. data/lib/evil/client/rspec.rb +127 -0
  60. data/lib/evil/client/schema.rb +105 -0
  61. data/lib/evil/client/schema/operation.rb +177 -0
  62. data/lib/evil/client/schema/scope.rb +73 -0
  63. data/lib/evil/client/settings.rb +172 -0
  64. data/lib/evil/client/settings/validator.rb +64 -0
  65. data/mkdocs.yml +21 -15
  66. data/spec/features/custom_connection_spec.rb +17 -0
  67. data/spec/features/operation/middleware_spec.rb +50 -0
  68. data/spec/features/operation/options_spec.rb +71 -0
  69. data/spec/features/operation/request_spec.rb +94 -0
  70. data/spec/features/operation/response_spec.rb +48 -0
  71. data/spec/features/scope/options_spec.rb +52 -0
  72. data/spec/fixtures/locales/en.yml +16 -0
  73. data/spec/fixtures/test_client.rb +76 -0
  74. data/spec/spec_helper.rb +18 -6
  75. data/spec/support/fixtures_helper.rb +7 -0
  76. data/spec/unit/builder/operation_spec.rb +90 -0
  77. data/spec/unit/builder/scope_spec.rb +84 -0
  78. data/spec/unit/client_spec.rb +137 -0
  79. data/spec/unit/connection_spec.rb +78 -0
  80. data/spec/unit/container/operation_spec.rb +81 -0
  81. data/spec/unit/container/scope_spec.rb +61 -0
  82. data/spec/unit/container_spec.rb +107 -0
  83. data/spec/unit/exceptions/definition_error_spec.rb +15 -0
  84. data/spec/unit/exceptions/name_error_spec.rb +77 -0
  85. data/spec/unit/exceptions/response_error_spec.rb +22 -0
  86. data/spec/unit/exceptions/type_error_spec.rb +71 -0
  87. data/spec/unit/exceptions/validation_error_spec.rb +13 -0
  88. data/spec/unit/formatter/form_spec.rb +27 -0
  89. data/spec/unit/formatter/multipart_spec.rb +23 -0
  90. data/spec/unit/formatter/part_spec.rb +49 -0
  91. data/spec/unit/formatter/text_spec.rb +37 -0
  92. data/spec/unit/formatter_spec.rb +46 -0
  93. data/spec/unit/resolver/body_spec.rb +65 -0
  94. data/spec/unit/resolver/format_spec.rb +66 -0
  95. data/spec/unit/resolver/headers_spec.rb +93 -0
  96. data/spec/unit/resolver/http_method_spec.rb +67 -0
  97. data/spec/unit/resolver/middleware_spec.rb +83 -0
  98. data/spec/unit/resolver/query_spec.rb +85 -0
  99. data/spec/unit/resolver/request_spec.rb +121 -0
  100. data/spec/unit/resolver/response_spec.rb +64 -0
  101. data/spec/unit/resolver/security_spec.rb +156 -0
  102. data/spec/unit/resolver/uri_spec.rb +117 -0
  103. data/spec/unit/rspec_spec.rb +342 -0
  104. data/spec/unit/schema/operation_spec.rb +309 -0
  105. data/spec/unit/schema/scope_spec.rb +110 -0
  106. data/spec/unit/schema_spec.rb +157 -0
  107. data/spec/unit/settings/validator_spec.rb +128 -0
  108. data/spec/unit/settings_spec.rb +248 -0
  109. metadata +192 -135
  110. data/docs/base_url.md +0 -38
  111. data/docs/documentation.md +0 -9
  112. data/docs/headers.md +0 -59
  113. data/docs/http_method.md +0 -31
  114. data/docs/model.md +0 -173
  115. data/docs/operation.md +0 -0
  116. data/docs/overview.md +0 -0
  117. data/docs/path.md +0 -48
  118. data/docs/query.md +0 -99
  119. data/docs/responses.md +0 -66
  120. data/docs/security.md +0 -102
  121. data/docs/settings.md +0 -32
  122. data/lib/evil/client/connection/net_http.rb +0 -57
  123. data/lib/evil/client/dsl.rb +0 -127
  124. data/lib/evil/client/dsl/base.rb +0 -26
  125. data/lib/evil/client/dsl/files.rb +0 -37
  126. data/lib/evil/client/dsl/headers.rb +0 -16
  127. data/lib/evil/client/dsl/http_method.rb +0 -24
  128. data/lib/evil/client/dsl/operation.rb +0 -91
  129. data/lib/evil/client/dsl/operations.rb +0 -41
  130. data/lib/evil/client/dsl/path.rb +0 -25
  131. data/lib/evil/client/dsl/query.rb +0 -16
  132. data/lib/evil/client/dsl/response.rb +0 -61
  133. data/lib/evil/client/dsl/responses.rb +0 -29
  134. data/lib/evil/client/dsl/scope.rb +0 -27
  135. data/lib/evil/client/dsl/security.rb +0 -57
  136. data/lib/evil/client/dsl/verifier.rb +0 -35
  137. data/lib/evil/client/middleware.rb +0 -81
  138. data/lib/evil/client/middleware/base.rb +0 -11
  139. data/lib/evil/client/middleware/merge_security.rb +0 -20
  140. data/lib/evil/client/middleware/normalize_headers.rb +0 -17
  141. data/lib/evil/client/middleware/stringify_form.rb +0 -40
  142. data/lib/evil/client/middleware/stringify_json.rb +0 -19
  143. data/lib/evil/client/middleware/stringify_multipart.rb +0 -36
  144. data/lib/evil/client/middleware/stringify_multipart/part.rb +0 -36
  145. data/lib/evil/client/middleware/stringify_query.rb +0 -35
  146. data/lib/evil/client/operation.rb +0 -34
  147. data/lib/evil/client/operation/request.rb +0 -26
  148. data/lib/evil/client/operation/response.rb +0 -39
  149. data/lib/evil/client/operation/response_error.rb +0 -13
  150. data/lib/evil/client/operation/unexpected_response_error.rb +0 -19
  151. data/spec/features/instantiation_spec.rb +0 -68
  152. data/spec/features/middleware_spec.rb +0 -79
  153. data/spec/features/operation_with_documentation_spec.rb +0 -41
  154. data/spec/features/operation_with_files_spec.rb +0 -40
  155. data/spec/features/operation_with_form_body_spec.rb +0 -158
  156. data/spec/features/operation_with_headers_spec.rb +0 -99
  157. data/spec/features/operation_with_http_method_spec.rb +0 -45
  158. data/spec/features/operation_with_json_body_spec.rb +0 -156
  159. data/spec/features/operation_with_nested_responses_spec.rb +0 -95
  160. data/spec/features/operation_with_path_spec.rb +0 -47
  161. data/spec/features/operation_with_query_spec.rb +0 -84
  162. data/spec/features/operation_with_security_spec.rb +0 -228
  163. data/spec/features/scoping_spec.rb +0 -48
  164. data/spec/support/test_client.rb +0 -15
  165. data/spec/unit/evil/client/connection/net_http_spec.rb +0 -38
  166. data/spec/unit/evil/client/dsl/files_spec.rb +0 -37
  167. data/spec/unit/evil/client/dsl/operation_spec.rb +0 -374
  168. data/spec/unit/evil/client/dsl/operations_spec.rb +0 -29
  169. data/spec/unit/evil/client/dsl/scope_spec.rb +0 -32
  170. data/spec/unit/evil/client/dsl/security_spec.rb +0 -135
  171. data/spec/unit/evil/client/middleware/merge_security_spec.rb +0 -32
  172. data/spec/unit/evil/client/middleware/normalize_headers_spec.rb +0 -17
  173. data/spec/unit/evil/client/middleware/stringify_form_spec.rb +0 -63
  174. data/spec/unit/evil/client/middleware/stringify_json_spec.rb +0 -61
  175. data/spec/unit/evil/client/middleware/stringify_multipart/part_spec.rb +0 -59
  176. data/spec/unit/evil/client/middleware/stringify_multipart_spec.rb +0 -62
  177. data/spec/unit/evil/client/middleware/stringify_query_spec.rb +0 -40
  178. data/spec/unit/evil/client/middleware_spec.rb +0 -46
  179. data/spec/unit/evil/client/operation/request_spec.rb +0 -49
  180. data/spec/unit/evil/client/operation/response_spec.rb +0 -63
@@ -1,11 +0,0 @@
1
- class Evil::Client::Middleware::Base
2
- def call(env, schema, options)
3
- @app.call(env, schema, options)
4
- end
5
-
6
- private
7
-
8
- def initialize(app)
9
- @app = app
10
- end
11
- end
@@ -1,20 +0,0 @@
1
- class Evil::Client::Middleware
2
- class MergeSecurity < Base
3
- def call(env, schema, options)
4
- super build(env), schema, options
5
- end
6
-
7
- private
8
-
9
- def build(env)
10
- env.dup.tap do |hash|
11
- security = hash.delete(:security).to_h
12
- %i[headers body query].each do |key|
13
- next unless security[key]
14
- hash[key] ||= {}
15
- hash[key].update security[key]
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,17 +0,0 @@
1
- class Evil::Client::Middleware
2
- class NormalizeHeaders < Base
3
- def call(env, schema, options)
4
- super build(env), schema, options
5
- end
6
-
7
- private
8
-
9
- def build(env)
10
- headers = Hash(env[:headers]).each_with_object({}) do |(key, val), hash|
11
- hash[key.to_s.downcase] = val.to_s
12
- end
13
-
14
- env.merge headers: headers
15
- end
16
- end
17
- end
@@ -1,40 +0,0 @@
1
- class Evil::Client::Middleware
2
- class StringifyForm < Base
3
- def call(env, schema, options)
4
- super build(env), schema, options
5
- end
6
-
7
- private
8
-
9
- def build(env)
10
- return env unless env[:format] == "form"
11
- return env if env&.fetch(:body, nil).to_h.empty?
12
-
13
- env.dup.tap do |hash|
14
- hash[:headers] ||= {}
15
- hash[:headers]["content-type"] = "application/x-www-form-urlencoded"
16
- hash[:body_string] = env[:body]
17
- .flat_map { |key, val| normalize(val, key) }
18
- .flat_map { |item| stringify(item) }
19
- .join("&")
20
- end
21
- end
22
-
23
- def stringify(hash)
24
- hash.map do |keys, val|
25
- "#{keys.first}#{keys[1..-1].map { |key| "[#{key}]" }.join}=#{val}"
26
- end
27
- end
28
-
29
- def normalize(value, *keys)
30
- case value
31
- when Hash then
32
- value.flat_map { |key, val| normalize(val, *keys, key) }
33
- when Array then
34
- value.flat_map { |val| normalize(val, *keys, nil) }
35
- else
36
- [{ keys.map { |key| CGI.escape(key.to_s) } => CGI.escape(value.to_s) }]
37
- end
38
- end
39
- end
40
- end
@@ -1,19 +0,0 @@
1
- class Evil::Client::Middleware
2
- class StringifyJson < Base
3
- def call(env, schema, options)
4
- super build(env), schema, options
5
- end
6
-
7
- private
8
-
9
- def build(env)
10
- return env unless env[:format] == "json"
11
-
12
- env.dup.tap do |hash|
13
- hash[:headers] ||= {}
14
- hash[:headers]["content-type"] = "application/json"
15
- hash[:body_string] = JSON.generate(env[:body].to_h)
16
- end
17
- end
18
- end
19
- end
@@ -1,36 +0,0 @@
1
- class Evil::Client::Middleware
2
- class StringifyMultipart < Base
3
- require_relative "stringify_multipart/part"
4
-
5
- def call(env, schema, options)
6
- super build(env), schema, options
7
- end
8
-
9
- private
10
-
11
- def build(env)
12
- return env unless env[:format] == "multipart"
13
-
14
- env.dup.tap do |hash|
15
- bound = SecureRandom.hex(10)
16
- hash[:headers] ||= {}
17
- hash[:headers]["content-type"] = \
18
- "multipart/form-data; boundary=#{bound}"
19
- hash[:body_string] = body_string(hash[:files], bound)
20
- end
21
- end
22
-
23
- def body_string(list, bound)
24
- return if list.empty?
25
- [nil, nil, parts(list, bound), "--#{bound}--", nil].join("\r\n")
26
- end
27
-
28
- def parts(list, bound)
29
- list.map.with_index { |item, index| part(bound, index + 1, item) }
30
- end
31
-
32
- def part(bound, index, data)
33
- "--#{bound}\r\n#{Part.new(name: "AttachedFile#{index}", **data)}"
34
- end
35
- end
36
- end
@@ -1,36 +0,0 @@
1
- class Evil::Client::Middleware::StringifyMultipart
2
- # Takes a file with its options and builds a part of multipart body
3
- class Part
4
- extend Dry::Initializer::Mixin
5
- option :file
6
- option :type, default: proc { MIME::Types["text/plain"].first }
7
- option :charset, default: proc { "utf-8" }
8
- option :name, default: proc { "AttachedFile" }
9
- option :filename, default: proc { default_filename }
10
-
11
- def to_s
12
- [content_disposition, content_type, nil, content].join("\r\n")
13
- end
14
-
15
- private
16
-
17
- def default_filename
18
- return Pathname.new(file.path).basename if file.respond_to? :path
19
- "#{SecureRandom.hex(10)}.#{type.preferred_extension}"
20
- end
21
-
22
- def content_disposition
23
- "Content-Disposition: form-data;" \
24
- " name=\"#{name}\";" \
25
- " filename=\"#{filename}\""
26
- end
27
-
28
- def content_type
29
- "Content-Type: #{type}; charset=#{charset}"
30
- end
31
-
32
- def content
33
- file.respond_to?(:read) ? file.read : file
34
- end
35
- end
36
- end
@@ -1,35 +0,0 @@
1
- class Evil::Client::Middleware
2
- class StringifyQuery < Base
3
- def call(env, schema, options)
4
- super build(env), schema, options
5
- end
6
-
7
- private
8
-
9
- def build(env)
10
- return env if env&.fetch(:query, nil).to_h.empty?
11
- string = env[:query].flat_map { |key, val| normalize(val, key) }
12
- .flat_map { |hash| stringify(hash) }
13
- .join("&")
14
-
15
- env.merge(query_string: string)
16
- end
17
-
18
- def stringify(hash)
19
- hash.map do |keys, val|
20
- "#{keys.first}#{keys[1..-1].map { |key| "[#{key}]" }.join}=#{val}"
21
- end
22
- end
23
-
24
- def normalize(value, *keys)
25
- case value
26
- when Hash then
27
- value.flat_map { |key, val| normalize(val, *keys, key) }
28
- when Array then
29
- value.flat_map { |val| normalize(val, *keys, nil) }
30
- else
31
- [{ keys.map { |key| CGI.escape(key.to_s) } => CGI.escape(value.to_s) }]
32
- end
33
- end
34
- end
35
- end
@@ -1,34 +0,0 @@
1
- class Evil::Client
2
- # Carries a final schema for a single operation along with shared connection,
3
- # and uses it to send requests to the server
4
- class Operation
5
- require_relative "operation/request"
6
- require_relative "operation/response"
7
-
8
- extend Dry::Initializer::Mixin
9
- param :schema
10
- param :connection
11
-
12
- # Builds and sends a request and returns a response proccessed by schema
13
- #
14
- # @param [IO, nil] file
15
- # @param [Hash<Symbol, Object>] options
16
- # @return [Object]
17
- #
18
- def call(**options)
19
- env = request.build(options)
20
- array = connection.call(env, schema, options)
21
- response.handle(array)
22
- end
23
-
24
- private
25
-
26
- def request
27
- @request ||= Request.new(schema)
28
- end
29
-
30
- def response
31
- @response ||= Response.new(schema)
32
- end
33
- end
34
- end
@@ -1,26 +0,0 @@
1
- class Evil::Client::Operation
2
- # Builds a request env from user options by applying schema validations
3
- class Request
4
- extend Dry::Initializer::Mixin
5
- param :schema
6
-
7
- # Builds an env
8
- #
9
- # @param [IO, nil] file (nil)
10
- # @param [Hash<Symbol, Object>] options
11
- # @return [Hash]
12
- #
13
- def build(options)
14
- {
15
- format: schema[:format],
16
- http_method: schema[:method].call(options),
17
- path: schema[:path].call(options),
18
- security: schema[:security]&.call(options),
19
- files: schema[:files]&.call(options),
20
- query: schema[:query]&.new(options).to_h,
21
- body: schema[:body]&.new(options).to_h,
22
- headers: schema[:headers]&.new(options).to_h
23
- }
24
- end
25
- end
26
- end
@@ -1,39 +0,0 @@
1
- class Evil::Client::Operation
2
- require_relative "response_error"
3
- require_relative "unexpected_response_error"
4
-
5
- # Processes rack responses using an operation's schema
6
- class Response
7
- extend Dry::Initializer::Mixin
8
- param :schema
9
-
10
- # Processes rack responses returned by [Dry::Cluent::Connection]
11
- #
12
- # @param [Array] array Rack-compatible array of response data
13
- # @return [Object]
14
- #
15
- # @raise [Evil::Client::ResponseError] when needed by the schema
16
- # @raise [Evil::Client::UnexpectedResponseError]
17
- # when a response cannot be processed
18
- #
19
- def handle(response)
20
- status, _, body = response
21
- body = body.any? ? body.join("\n") : nil
22
-
23
- handlers(status).each do |handler|
24
- data = handler[:coercer][body] rescue next
25
- raise ResponseError.new(schema, status, data) if handler[:raise]
26
- return data
27
- end
28
-
29
- raise UnexpectedResponseError.new(schema, status, body)
30
- end
31
-
32
- private
33
-
34
- def handlers(status)
35
- list = schema[:responses].values.select { |item| item[:status] == status }
36
- list.reject { |item| item[:raise] } + list.select { |item| item[:raise] }
37
- end
38
- end
39
- end
@@ -1,13 +0,0 @@
1
- class Evil::Client::Operation
2
- class ResponseError < RuntimeError
3
- attr_reader :status, :data
4
-
5
- private
6
-
7
- def initialize(schema, status, data)
8
- @status = status
9
- @data = data
10
- super "Response to operation '#{schema[:key]}' has http status #{status}"
11
- end
12
- end
13
- end
@@ -1,19 +0,0 @@
1
- class Evil::Client::Operation
2
- class UnexpectedResponseError < RuntimeError
3
- attr_reader :status, :data
4
-
5
- private
6
-
7
- def initialize(schema, status, data)
8
- @status = status
9
- @data = data
10
-
11
- message = "Response to operation '#{schema[:key]}'" \
12
- " with http status #{status} and body #{data}" \
13
- " cannot be processed."
14
- message << " See #{schema[:doc]} for details." if schema[:doc]
15
-
16
- super message
17
- end
18
- end
19
- end
@@ -1,68 +0,0 @@
1
- RSpec.describe "instantiation" do
2
- # see Test::Client definition in `/spec/support/test_client.rb`
3
- let(:client) { Test::Client.new subdomain, options }
4
- let(:subdomain) { "foo" }
5
- let(:options) { { version: 3, user: "bar", password: "baz", token: "qux" } }
6
-
7
- context "with valid settings:" do
8
- it "is accepted" do
9
- expect(client).to be_kind_of Test::Client
10
- end
11
- end
12
-
13
- context "with settings that still conforms to contract:" do
14
- let(:options) { { user: "bar" } }
15
-
16
- it "is accepted" do
17
- expect(client).to be_kind_of Test::Client
18
- end
19
- end
20
-
21
- context "with unexpected param settings:" do
22
- let(:client) { Test::Client.new(subdomain, subdomain, **options) }
23
-
24
- it "is rejected" do
25
- expect { client }.to raise_error(ArgumentError)
26
- end
27
- end
28
-
29
- context "with missing param settings:" do
30
- let(:client) { Test::Client.new(**options) }
31
-
32
- it "is rejected" do
33
- expect { client }.to raise_error(StandardError)
34
- end
35
- end
36
-
37
- context "with a broken contract for param:" do
38
- let(:subdomain) { 1 }
39
-
40
- it "is rejected" do
41
- expect { client }.to raise_error(TypeError)
42
- end
43
- end
44
-
45
- context "with unexpected option settings:" do
46
- before { options[:foo] = "bar" }
47
-
48
- it "is accepted" do
49
- expect { client }.not_to raise_error
50
- end
51
- end
52
-
53
- context "with missing option settings:" do
54
- before { options.delete :user }
55
-
56
- it "is rejected" do
57
- expect { client }.to raise_error(ArgumentError)
58
- end
59
- end
60
-
61
- context "with a broken contract for option:" do
62
- before { options[:user] = 1 }
63
-
64
- it "is rejected" do
65
- expect { client }.to raise_error(TypeError)
66
- end
67
- end
68
- end
@@ -1,79 +0,0 @@
1
- RSpec.describe "middleware" do
2
- before do
3
- class Test::UpdateRequest
4
- def initialize(app)
5
- @app = app
6
- end
7
-
8
- def call(_env, schema, options)
9
- env = {
10
- path: "data/1",
11
- http_method: "get",
12
- format: "form",
13
- headers: { "baz" => "BAZ" },
14
- query: { "bar" => "baz" },
15
- body: { "qux" => 2 }
16
- }
17
-
18
- @app.call env, schema, options
19
- end
20
- end
21
-
22
- class Test::UpdateResponse
23
- def initialize(app)
24
- @app = app
25
- end
26
-
27
- def call(env, *params)
28
- response = @app.call(env, *params)
29
- response[2] = ["Hi!"]
30
- response
31
- end
32
- end
33
-
34
- class Test::Client < Evil::Client
35
- connection do |settings|
36
- run Test::UpdateRequest
37
- run Test::UpdateResponse if settings.version > 2
38
- end
39
-
40
- operation :find do
41
- path { "some" }
42
- http_method :post
43
- response :success, 200, format: :plain
44
- end
45
- end
46
-
47
- stub_request(:any, //)
48
- end
49
-
50
- it "updates requests" do
51
- request = a_request(:get, "https://foo.example.com/api/v3/data/1?bar=baz")
52
- .with do |req|
53
- expect(req.body).to eq "qux=2"
54
- expect(req.headers).to include "Baz" => "BAZ"
55
- end
56
-
57
- Test::Client.new("foo", version: 3, user: "bar").operations[:find].call
58
-
59
- expect(request).to have_been_made
60
- end
61
-
62
- it "updates responses" do
63
- response = \
64
- Test::Client.new("foo", version: 3, user: "bar")
65
- .operations[:find]
66
- .call
67
-
68
- expect(response).to eq "Hi!"
69
- end
70
-
71
- it "depends on settings" do
72
- response = \
73
- Test::Client.new("foo", version: 1, user: "bar")
74
- .operations[:find]
75
- .call
76
-
77
- expect(response).to be_nil
78
- end
79
- end