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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +0 -11
- data/.gitignore +1 -0
- data/.rspec +0 -1
- data/.rubocop.yml +22 -19
- data/.travis.yml +1 -0
- data/CHANGELOG.md +251 -6
- data/LICENSE.txt +3 -1
- data/README.md +47 -81
- data/docs/helpers/body.md +93 -0
- data/docs/helpers/connection.md +19 -0
- data/docs/helpers/headers.md +72 -0
- data/docs/helpers/http_method.md +39 -0
- data/docs/helpers/let.md +14 -0
- data/docs/helpers/logger.md +24 -0
- data/docs/helpers/middleware.md +56 -0
- data/docs/helpers/operation.md +103 -0
- data/docs/helpers/option.md +50 -0
- data/docs/helpers/path.md +37 -0
- data/docs/helpers/query.md +59 -0
- data/docs/helpers/response.md +40 -0
- data/docs/helpers/scope.md +121 -0
- data/docs/helpers/security.md +102 -0
- data/docs/helpers/validate.md +68 -0
- data/docs/index.md +70 -78
- data/docs/license.md +5 -1
- data/docs/rspec.md +96 -0
- data/evil-client.gemspec +10 -8
- data/lib/evil/client.rb +126 -72
- data/lib/evil/client/builder.rb +47 -0
- data/lib/evil/client/builder/operation.rb +40 -0
- data/lib/evil/client/builder/scope.rb +31 -0
- data/lib/evil/client/chaining.rb +17 -0
- data/lib/evil/client/connection.rb +60 -20
- data/lib/evil/client/container.rb +66 -0
- data/lib/evil/client/container/operation.rb +23 -0
- data/lib/evil/client/container/scope.rb +28 -0
- data/lib/evil/client/exceptions/definition_error.rb +15 -0
- data/lib/evil/client/exceptions/name_error.rb +32 -0
- data/lib/evil/client/exceptions/response_error.rb +42 -0
- data/lib/evil/client/exceptions/type_error.rb +29 -0
- data/lib/evil/client/exceptions/validation_error.rb +27 -0
- data/lib/evil/client/formatter.rb +49 -0
- data/lib/evil/client/formatter/form.rb +45 -0
- data/lib/evil/client/formatter/multipart.rb +33 -0
- data/lib/evil/client/formatter/part.rb +66 -0
- data/lib/evil/client/formatter/text.rb +21 -0
- data/lib/evil/client/resolver.rb +84 -0
- data/lib/evil/client/resolver/body.rb +22 -0
- data/lib/evil/client/resolver/format.rb +30 -0
- data/lib/evil/client/resolver/headers.rb +46 -0
- data/lib/evil/client/resolver/http_method.rb +34 -0
- data/lib/evil/client/resolver/middleware.rb +36 -0
- data/lib/evil/client/resolver/query.rb +39 -0
- data/lib/evil/client/resolver/request.rb +96 -0
- data/lib/evil/client/resolver/response.rb +26 -0
- data/lib/evil/client/resolver/security.rb +113 -0
- data/lib/evil/client/resolver/uri.rb +35 -0
- data/lib/evil/client/rspec.rb +127 -0
- data/lib/evil/client/schema.rb +105 -0
- data/lib/evil/client/schema/operation.rb +177 -0
- data/lib/evil/client/schema/scope.rb +73 -0
- data/lib/evil/client/settings.rb +172 -0
- data/lib/evil/client/settings/validator.rb +64 -0
- data/mkdocs.yml +21 -15
- data/spec/features/custom_connection_spec.rb +17 -0
- data/spec/features/operation/middleware_spec.rb +50 -0
- data/spec/features/operation/options_spec.rb +71 -0
- data/spec/features/operation/request_spec.rb +94 -0
- data/spec/features/operation/response_spec.rb +48 -0
- data/spec/features/scope/options_spec.rb +52 -0
- data/spec/fixtures/locales/en.yml +16 -0
- data/spec/fixtures/test_client.rb +76 -0
- data/spec/spec_helper.rb +18 -6
- data/spec/support/fixtures_helper.rb +7 -0
- data/spec/unit/builder/operation_spec.rb +90 -0
- data/spec/unit/builder/scope_spec.rb +84 -0
- data/spec/unit/client_spec.rb +137 -0
- data/spec/unit/connection_spec.rb +78 -0
- data/spec/unit/container/operation_spec.rb +81 -0
- data/spec/unit/container/scope_spec.rb +61 -0
- data/spec/unit/container_spec.rb +107 -0
- data/spec/unit/exceptions/definition_error_spec.rb +15 -0
- data/spec/unit/exceptions/name_error_spec.rb +77 -0
- data/spec/unit/exceptions/response_error_spec.rb +22 -0
- data/spec/unit/exceptions/type_error_spec.rb +71 -0
- data/spec/unit/exceptions/validation_error_spec.rb +13 -0
- data/spec/unit/formatter/form_spec.rb +27 -0
- data/spec/unit/formatter/multipart_spec.rb +23 -0
- data/spec/unit/formatter/part_spec.rb +49 -0
- data/spec/unit/formatter/text_spec.rb +37 -0
- data/spec/unit/formatter_spec.rb +46 -0
- data/spec/unit/resolver/body_spec.rb +65 -0
- data/spec/unit/resolver/format_spec.rb +66 -0
- data/spec/unit/resolver/headers_spec.rb +93 -0
- data/spec/unit/resolver/http_method_spec.rb +67 -0
- data/spec/unit/resolver/middleware_spec.rb +83 -0
- data/spec/unit/resolver/query_spec.rb +85 -0
- data/spec/unit/resolver/request_spec.rb +121 -0
- data/spec/unit/resolver/response_spec.rb +64 -0
- data/spec/unit/resolver/security_spec.rb +156 -0
- data/spec/unit/resolver/uri_spec.rb +117 -0
- data/spec/unit/rspec_spec.rb +342 -0
- data/spec/unit/schema/operation_spec.rb +309 -0
- data/spec/unit/schema/scope_spec.rb +110 -0
- data/spec/unit/schema_spec.rb +157 -0
- data/spec/unit/settings/validator_spec.rb +128 -0
- data/spec/unit/settings_spec.rb +248 -0
- metadata +192 -135
- data/docs/base_url.md +0 -38
- data/docs/documentation.md +0 -9
- data/docs/headers.md +0 -59
- data/docs/http_method.md +0 -31
- data/docs/model.md +0 -173
- data/docs/operation.md +0 -0
- data/docs/overview.md +0 -0
- data/docs/path.md +0 -48
- data/docs/query.md +0 -99
- data/docs/responses.md +0 -66
- data/docs/security.md +0 -102
- data/docs/settings.md +0 -32
- data/lib/evil/client/connection/net_http.rb +0 -57
- data/lib/evil/client/dsl.rb +0 -127
- data/lib/evil/client/dsl/base.rb +0 -26
- data/lib/evil/client/dsl/files.rb +0 -37
- data/lib/evil/client/dsl/headers.rb +0 -16
- data/lib/evil/client/dsl/http_method.rb +0 -24
- data/lib/evil/client/dsl/operation.rb +0 -91
- data/lib/evil/client/dsl/operations.rb +0 -41
- data/lib/evil/client/dsl/path.rb +0 -25
- data/lib/evil/client/dsl/query.rb +0 -16
- data/lib/evil/client/dsl/response.rb +0 -61
- data/lib/evil/client/dsl/responses.rb +0 -29
- data/lib/evil/client/dsl/scope.rb +0 -27
- data/lib/evil/client/dsl/security.rb +0 -57
- data/lib/evil/client/dsl/verifier.rb +0 -35
- data/lib/evil/client/middleware.rb +0 -81
- data/lib/evil/client/middleware/base.rb +0 -11
- data/lib/evil/client/middleware/merge_security.rb +0 -20
- data/lib/evil/client/middleware/normalize_headers.rb +0 -17
- data/lib/evil/client/middleware/stringify_form.rb +0 -40
- data/lib/evil/client/middleware/stringify_json.rb +0 -19
- data/lib/evil/client/middleware/stringify_multipart.rb +0 -36
- data/lib/evil/client/middleware/stringify_multipart/part.rb +0 -36
- data/lib/evil/client/middleware/stringify_query.rb +0 -35
- data/lib/evil/client/operation.rb +0 -34
- data/lib/evil/client/operation/request.rb +0 -26
- data/lib/evil/client/operation/response.rb +0 -39
- data/lib/evil/client/operation/response_error.rb +0 -13
- data/lib/evil/client/operation/unexpected_response_error.rb +0 -19
- data/spec/features/instantiation_spec.rb +0 -68
- data/spec/features/middleware_spec.rb +0 -79
- data/spec/features/operation_with_documentation_spec.rb +0 -41
- data/spec/features/operation_with_files_spec.rb +0 -40
- data/spec/features/operation_with_form_body_spec.rb +0 -158
- data/spec/features/operation_with_headers_spec.rb +0 -99
- data/spec/features/operation_with_http_method_spec.rb +0 -45
- data/spec/features/operation_with_json_body_spec.rb +0 -156
- data/spec/features/operation_with_nested_responses_spec.rb +0 -95
- data/spec/features/operation_with_path_spec.rb +0 -47
- data/spec/features/operation_with_query_spec.rb +0 -84
- data/spec/features/operation_with_security_spec.rb +0 -228
- data/spec/features/scoping_spec.rb +0 -48
- data/spec/support/test_client.rb +0 -15
- data/spec/unit/evil/client/connection/net_http_spec.rb +0 -38
- data/spec/unit/evil/client/dsl/files_spec.rb +0 -37
- data/spec/unit/evil/client/dsl/operation_spec.rb +0 -374
- data/spec/unit/evil/client/dsl/operations_spec.rb +0 -29
- data/spec/unit/evil/client/dsl/scope_spec.rb +0 -32
- data/spec/unit/evil/client/dsl/security_spec.rb +0 -135
- data/spec/unit/evil/client/middleware/merge_security_spec.rb +0 -32
- data/spec/unit/evil/client/middleware/normalize_headers_spec.rb +0 -17
- data/spec/unit/evil/client/middleware/stringify_form_spec.rb +0 -63
- data/spec/unit/evil/client/middleware/stringify_json_spec.rb +0 -61
- data/spec/unit/evil/client/middleware/stringify_multipart/part_spec.rb +0 -59
- data/spec/unit/evil/client/middleware/stringify_multipart_spec.rb +0 -62
- data/spec/unit/evil/client/middleware/stringify_query_spec.rb +0 -40
- data/spec/unit/evil/client/middleware_spec.rb +0 -46
- data/spec/unit/evil/client/operation/request_spec.rb +0 -49
- data/spec/unit/evil/client/operation/response_spec.rb +0 -63
@@ -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
|