openapi_first 1.4.3 → 2.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/CHANGELOG.md +43 -1
- data/README.md +105 -28
- data/lib/openapi_first/body_parser.rb +8 -11
- data/lib/openapi_first/builder.rb +81 -0
- data/lib/openapi_first/configuration.rb +24 -3
- data/lib/openapi_first/definition.rb +44 -100
- data/lib/openapi_first/error_response.rb +2 -2
- data/lib/openapi_first/error_responses/default.rb +73 -0
- data/lib/openapi_first/error_responses/jsonapi.rb +59 -0
- data/lib/openapi_first/errors.rb +26 -4
- data/lib/openapi_first/failure.rb +29 -26
- data/lib/openapi_first/json_refs.rb +1 -3
- data/lib/openapi_first/middlewares/request_validation.rb +2 -2
- data/lib/openapi_first/middlewares/response_validation.rb +4 -3
- data/lib/openapi_first/request.rb +92 -0
- data/lib/openapi_first/request_parser.rb +35 -0
- data/lib/openapi_first/request_validator.rb +25 -0
- data/lib/openapi_first/response.rb +57 -0
- data/lib/openapi_first/response_parser.rb +49 -0
- data/lib/openapi_first/response_validator.rb +27 -0
- data/lib/openapi_first/router/find_content.rb +17 -0
- data/lib/openapi_first/router/find_response.rb +45 -0
- data/lib/openapi_first/{definition → router}/path_template.rb +9 -1
- data/lib/openapi_first/router.rb +100 -0
- data/lib/openapi_first/schema/validation_error.rb +16 -10
- data/lib/openapi_first/schema/validation_result.rb +8 -6
- data/lib/openapi_first/schema.rb +4 -8
- data/lib/openapi_first/test/methods.rb +21 -0
- data/lib/openapi_first/test.rb +19 -0
- data/lib/openapi_first/validated_request.rb +81 -0
- data/lib/openapi_first/validated_response.rb +33 -0
- data/lib/openapi_first/validators/request_body.rb +39 -0
- data/lib/openapi_first/validators/request_parameters.rb +61 -0
- data/lib/openapi_first/validators/response_body.rb +30 -0
- data/lib/openapi_first/validators/response_headers.rb +25 -0
- data/lib/openapi_first/version.rb +1 -1
- data/lib/openapi_first.rb +40 -21
- metadata +25 -20
- data/lib/openapi_first/definition/operation.rb +0 -197
- data/lib/openapi_first/definition/path_item.rb +0 -40
- data/lib/openapi_first/definition/request_body.rb +0 -46
- data/lib/openapi_first/definition/response.rb +0 -32
- data/lib/openapi_first/definition/responses.rb +0 -87
- data/lib/openapi_first/plugins/default/error_response.rb +0 -74
- data/lib/openapi_first/plugins/default.rb +0 -11
- data/lib/openapi_first/plugins/jsonapi/error_response.rb +0 -60
- data/lib/openapi_first/plugins/jsonapi.rb +0 -11
- data/lib/openapi_first/plugins.rb +0 -25
- data/lib/openapi_first/request_validation/request_body_validator.rb +0 -41
- data/lib/openapi_first/request_validation/validator.rb +0 -82
- data/lib/openapi_first/response_validation/validator.rb +0 -98
- data/lib/openapi_first/runtime_request.rb +0 -166
- data/lib/openapi_first/runtime_response.rb +0 -124
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../failure'
|
4
|
-
|
5
|
-
module OpenapiFirst
|
6
|
-
module RequestValidation
|
7
|
-
class RequestBodyValidator # :nodoc:
|
8
|
-
def initialize(operation)
|
9
|
-
@operation = operation
|
10
|
-
end
|
11
|
-
|
12
|
-
def validate!(parsed_request_body, request_content_type)
|
13
|
-
request_body = operation.request_body
|
14
|
-
schema = request_body.schema_for(request_content_type)
|
15
|
-
unless schema
|
16
|
-
Failure.fail!(:unsupported_media_type,
|
17
|
-
message: "Unsupported Media Type '#{request_content_type}'")
|
18
|
-
end
|
19
|
-
|
20
|
-
if request_body.required? && parsed_request_body.nil?
|
21
|
-
Failure.fail!(:invalid_body,
|
22
|
-
message: 'Request body is not defined')
|
23
|
-
end
|
24
|
-
|
25
|
-
validate_body!(parsed_request_body, schema)
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
attr_reader :operation
|
31
|
-
|
32
|
-
def validate_body!(parsed_request_body, schema)
|
33
|
-
request_body_schema = schema
|
34
|
-
return unless request_body_schema
|
35
|
-
|
36
|
-
validation = request_body_schema.validate(parsed_request_body)
|
37
|
-
Failure.fail!(:invalid_body, errors: validation.errors) if validation.error?
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../failure'
|
4
|
-
require_relative 'request_body_validator'
|
5
|
-
|
6
|
-
module OpenapiFirst
|
7
|
-
module RequestValidation
|
8
|
-
# Validates a RuntimeRequest against an Operation.
|
9
|
-
class Validator
|
10
|
-
def initialize(operation)
|
11
|
-
@operation = operation
|
12
|
-
end
|
13
|
-
|
14
|
-
def validate(runtime_request)
|
15
|
-
catch Failure::FAILURE do
|
16
|
-
validate_defined(runtime_request)
|
17
|
-
validate_parameters!(runtime_request)
|
18
|
-
validate_request_body!(runtime_request)
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
attr_reader :operation, :raw_path_params
|
26
|
-
|
27
|
-
def validate_defined(request)
|
28
|
-
return if request.known?
|
29
|
-
return Failure.fail!(:not_found) unless request.known_path?
|
30
|
-
|
31
|
-
Failure.fail!(:method_not_allowed) unless request.known_request_method?
|
32
|
-
end
|
33
|
-
|
34
|
-
def validate_parameters!(request)
|
35
|
-
validate_query_params!(request)
|
36
|
-
validate_path_params!(request)
|
37
|
-
validate_cookie_params!(request)
|
38
|
-
validate_header_params!(request)
|
39
|
-
end
|
40
|
-
|
41
|
-
def validate_path_params!(request)
|
42
|
-
schema = operation.path_parameters_schema
|
43
|
-
return unless schema
|
44
|
-
|
45
|
-
validation = schema.validate(request.path_parameters)
|
46
|
-
Failure.fail!(:invalid_path, errors: validation.errors) if validation.error?
|
47
|
-
end
|
48
|
-
|
49
|
-
def validate_query_params!(request)
|
50
|
-
schema = operation.query_parameters_schema
|
51
|
-
return unless schema
|
52
|
-
|
53
|
-
validation = schema.validate(request.query)
|
54
|
-
Failure.fail!(:invalid_query, errors: validation.errors) if validation.error?
|
55
|
-
end
|
56
|
-
|
57
|
-
def validate_cookie_params!(request)
|
58
|
-
schema = operation.cookie_parameters_schema
|
59
|
-
return unless schema
|
60
|
-
|
61
|
-
validation = schema.validate(request.cookies)
|
62
|
-
Failure.fail!(:invalid_cookie, errors: validation.errors) if validation.error?
|
63
|
-
end
|
64
|
-
|
65
|
-
def validate_header_params!(request)
|
66
|
-
schema = operation.header_parameters_schema
|
67
|
-
return unless schema
|
68
|
-
|
69
|
-
validation = schema.validate(request.headers)
|
70
|
-
Failure.fail!(:invalid_header, errors: validation.errors) if validation.error?
|
71
|
-
end
|
72
|
-
|
73
|
-
def validate_request_body!(request)
|
74
|
-
return unless operation.request_body
|
75
|
-
|
76
|
-
RequestBodyValidator.new(operation).validate!(request.body, request.content_type)
|
77
|
-
rescue ParseError => e
|
78
|
-
Failure.fail!(:invalid_body, message: e.message)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../failure'
|
4
|
-
|
5
|
-
module OpenapiFirst
|
6
|
-
module ResponseValidation
|
7
|
-
# Validates a RuntimeResponse against an Operation.
|
8
|
-
class Validator
|
9
|
-
def initialize(operation)
|
10
|
-
@operation = operation
|
11
|
-
end
|
12
|
-
|
13
|
-
def validate(runtime_response)
|
14
|
-
return unless operation
|
15
|
-
|
16
|
-
catch Failure::FAILURE do
|
17
|
-
validate_defined(runtime_response)
|
18
|
-
response_definition = runtime_response.response_definition
|
19
|
-
validate_response_body(response_definition.content_schema, runtime_response)
|
20
|
-
validate_response_headers(response_definition.headers, runtime_response.headers)
|
21
|
-
nil
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
attr_reader :operation
|
28
|
-
|
29
|
-
def validate_defined(runtime_response)
|
30
|
-
return if runtime_response.known?
|
31
|
-
|
32
|
-
unless runtime_response.known_status?
|
33
|
-
message = "Response status '#{runtime_response.status}' not found for '#{runtime_response.name}'"
|
34
|
-
Failure.fail!(:response_not_found, message:)
|
35
|
-
end
|
36
|
-
|
37
|
-
content_type = runtime_response.content_type
|
38
|
-
if content_type.nil? || content_type.empty?
|
39
|
-
message = "Content-Type for '#{runtime_response.name}' must not be empty"
|
40
|
-
Failure.fail!(:invalid_response_header, message:)
|
41
|
-
end
|
42
|
-
|
43
|
-
message = "Content-Type '#{content_type}' is not defined for '#{runtime_response.name}'"
|
44
|
-
Failure.fail!(:invalid_response_header, message:)
|
45
|
-
end
|
46
|
-
|
47
|
-
def validate_response_body(schema, runtime_response)
|
48
|
-
return unless schema
|
49
|
-
|
50
|
-
begin
|
51
|
-
parsed_body = runtime_response.body
|
52
|
-
rescue ParseError => e
|
53
|
-
Failure.fail!(:invalid_response_body, message: e.message)
|
54
|
-
end
|
55
|
-
|
56
|
-
validation = schema.validate(parsed_body)
|
57
|
-
Failure.fail!(:invalid_response_body, errors: validation.errors) if validation.error?
|
58
|
-
end
|
59
|
-
|
60
|
-
def validate_response_headers(response_header_definitions, unpacked_headers)
|
61
|
-
return unless response_header_definitions
|
62
|
-
|
63
|
-
response_header_definitions.each do |name, definition|
|
64
|
-
next if name == 'Content-Type'
|
65
|
-
|
66
|
-
validate_response_header(name, definition, unpacked_headers, openapi_version: operation.openapi_version)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def validate_response_header(name, definition, unpacked_headers, openapi_version:)
|
71
|
-
unless unpacked_headers.key?(name)
|
72
|
-
if definition['required']
|
73
|
-
Failure.fail!(:invalid_response_header,
|
74
|
-
message: "Required response header '#{name}' is missing")
|
75
|
-
end
|
76
|
-
|
77
|
-
return
|
78
|
-
end
|
79
|
-
|
80
|
-
return unless definition.key?('schema')
|
81
|
-
|
82
|
-
validation = Schema.new(definition['schema'], openapi_version:)
|
83
|
-
value = unpacked_headers[name]
|
84
|
-
validation_result = validation.validate(value)
|
85
|
-
return unless validation_result.error?
|
86
|
-
|
87
|
-
Failure.fail!(:invalid_response_header,
|
88
|
-
errors: validation_result.errors)
|
89
|
-
end
|
90
|
-
|
91
|
-
def load_json(string)
|
92
|
-
MultiJson.load(string)
|
93
|
-
rescue MultiJson::ParseError
|
94
|
-
string
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,166 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
require 'openapi_parameters'
|
5
|
-
require_relative 'runtime_response'
|
6
|
-
require_relative 'body_parser'
|
7
|
-
require_relative 'request_validation/validator'
|
8
|
-
|
9
|
-
module OpenapiFirst
|
10
|
-
# RuntimeRequest represents how an incoming request (Rack::Request) matches a request definition.
|
11
|
-
class RuntimeRequest
|
12
|
-
extend Forwardable
|
13
|
-
|
14
|
-
def initialize(request:, path_item:, operation:, path_params:)
|
15
|
-
@request = request
|
16
|
-
@path_item = path_item
|
17
|
-
@operation = operation
|
18
|
-
@original_path_params = path_params
|
19
|
-
@validated = false
|
20
|
-
end
|
21
|
-
|
22
|
-
def_delegators :@request, :content_type, :media_type, :path
|
23
|
-
def_delegators :@operation, :operation_id, :request_method
|
24
|
-
def_delegator :@path_item, :path, :path_definition
|
25
|
-
|
26
|
-
# Returns the path_item object.
|
27
|
-
# @return [PathItem, nil] The path_item object or nil if this request path is not known.
|
28
|
-
attr_reader :path_item
|
29
|
-
|
30
|
-
# Returns the operation object.
|
31
|
-
# @return [Operation, nil] The operation object or nil if this request method is not known.
|
32
|
-
attr_reader :operation
|
33
|
-
|
34
|
-
# Returns the error object if validation failed.
|
35
|
-
# @return [Failure, nil]
|
36
|
-
attr_accessor :error
|
37
|
-
|
38
|
-
# Checks if the request is valid.
|
39
|
-
# @return [Boolean] true if the request is valid, false otherwise.
|
40
|
-
def valid?
|
41
|
-
validate unless validated?
|
42
|
-
error.nil?
|
43
|
-
end
|
44
|
-
|
45
|
-
# Checks if the path and request method are known.
|
46
|
-
# @return [Boolean] true if the path and request method are known, false otherwise.
|
47
|
-
def known?
|
48
|
-
known_path? && known_request_method?
|
49
|
-
end
|
50
|
-
|
51
|
-
# Checks if the path is known.
|
52
|
-
# @return [Boolean] true if the path is known, false otherwise.
|
53
|
-
def known_path?
|
54
|
-
!!path_item
|
55
|
-
end
|
56
|
-
|
57
|
-
# Checks if the request method is known.
|
58
|
-
# @return [Boolean] true if the request method is known, false otherwise.
|
59
|
-
def known_request_method?
|
60
|
-
!!operation
|
61
|
-
end
|
62
|
-
|
63
|
-
# Returns the merged path and query parameters.
|
64
|
-
# @return [Hash] The merged path and query parameters.
|
65
|
-
def params
|
66
|
-
@params ||= query.merge(path_parameters)
|
67
|
-
end
|
68
|
-
|
69
|
-
# Returns the parsed path parameters of the request.
|
70
|
-
# @return [Hash]
|
71
|
-
def path_parameters
|
72
|
-
return {} unless operation.path_parameters
|
73
|
-
|
74
|
-
@path_parameters ||=
|
75
|
-
OpenapiParameters::Path.new(operation.path_parameters).unpack(@original_path_params) || {}
|
76
|
-
end
|
77
|
-
|
78
|
-
# Returns the parsed query parameters.
|
79
|
-
# This only includes parameters that are defined in the API description.
|
80
|
-
# @note This method is aliased as query_parameters.
|
81
|
-
# @return [Hash]
|
82
|
-
def query
|
83
|
-
return {} unless operation.query_parameters
|
84
|
-
|
85
|
-
@query ||=
|
86
|
-
OpenapiParameters::Query.new(operation.query_parameters).unpack(request.env[Rack::QUERY_STRING]) || {}
|
87
|
-
end
|
88
|
-
|
89
|
-
alias query_parameters query
|
90
|
-
|
91
|
-
# Returns the parsed header parameters.
|
92
|
-
# This only includes parameters that are defined in the API description.
|
93
|
-
# @return [Hash]
|
94
|
-
def headers
|
95
|
-
return {} unless operation.header_parameters
|
96
|
-
|
97
|
-
@headers ||= OpenapiParameters::Header.new(operation.header_parameters).unpack_env(request.env) || {}
|
98
|
-
end
|
99
|
-
|
100
|
-
# Returns the parsed cookie parameters.
|
101
|
-
# This only includes parameters that are defined in the API description.
|
102
|
-
# @return [Hash]
|
103
|
-
def cookies
|
104
|
-
return {} unless operation.cookie_parameters
|
105
|
-
|
106
|
-
@cookies ||=
|
107
|
-
OpenapiParameters::Cookie.new(operation.cookie_parameters).unpack(request.env[Rack::HTTP_COOKIE]) || {}
|
108
|
-
end
|
109
|
-
|
110
|
-
# Returns the parsed request body.
|
111
|
-
# This returns the whole request body with default values applied as defined in the API description.
|
112
|
-
# This does not remove any fields that are not defined in the API description.
|
113
|
-
# @return [Hash, Array, String, nil] The parsed body of the request.
|
114
|
-
def body
|
115
|
-
@body ||= BodyParser.new.parse(request, request.media_type)
|
116
|
-
end
|
117
|
-
|
118
|
-
alias parsed_body body
|
119
|
-
|
120
|
-
# Validates the request.
|
121
|
-
# @return [Failure, nil] The Failure object if validation failed.
|
122
|
-
# @deprecated Please use {Definition#validate_request} instead
|
123
|
-
def validate
|
124
|
-
warn '[DEPRECATION] `validate` is deprecated. Please use ' \
|
125
|
-
"`OpenapiFirst.load('openapi.yaml').validate_request(rack_request)` instead."
|
126
|
-
@error = RequestValidation::Validator.new(operation).validate(self)
|
127
|
-
end
|
128
|
-
|
129
|
-
# Validates the request and raises an error if validation fails.
|
130
|
-
def validate!
|
131
|
-
warn '[DEPRECATION] `validate!` is deprecated. Please use ' \
|
132
|
-
"`OpenapiFirst.load('openapi.yaml').validate_request(rack_request, raise_error: true)` instead."
|
133
|
-
error = validate
|
134
|
-
error&.raise!
|
135
|
-
end
|
136
|
-
|
137
|
-
# Validates the response.
|
138
|
-
# @param rack_response [Rack::Response] The rack response object.
|
139
|
-
# @param raise_error [Boolean] Whether to raise an error if validation fails.
|
140
|
-
# @return [RuntimeResponse] The validated response object.
|
141
|
-
def validate_response(rack_response, raise_error: false)
|
142
|
-
warn '[DEPRECATION] `validate_response!` is deprecated. Please use ' \
|
143
|
-
"`OpenapiFirst.load('openapi.yaml').validate_response(request, response, raise_error: false)` instead."
|
144
|
-
validated = response(rack_response).tap(&:validate)
|
145
|
-
validated.error&.raise! if raise_error
|
146
|
-
validated
|
147
|
-
end
|
148
|
-
|
149
|
-
# Creates a new RuntimeResponse object.
|
150
|
-
# @param rack_response [Rack::Response] The rack response object.
|
151
|
-
# @return [RuntimeResponse] The RuntimeResponse object.
|
152
|
-
def response(rack_response)
|
153
|
-
warn '[DEPRECATION] `response` is deprecated. Please use ' \
|
154
|
-
"`OpenapiFirst.load('openapi.yaml').validate_response(request, response, raise_error: false)` instead."
|
155
|
-
RuntimeResponse.new(operation, rack_response)
|
156
|
-
end
|
157
|
-
|
158
|
-
private
|
159
|
-
|
160
|
-
def validated?
|
161
|
-
defined?(@error)
|
162
|
-
end
|
163
|
-
|
164
|
-
attr_reader :request
|
165
|
-
end
|
166
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
require_relative 'body_parser'
|
5
|
-
require_relative 'response_validation/validator'
|
6
|
-
|
7
|
-
module OpenapiFirst
|
8
|
-
# Represents a response returned by the Rack application and how it relates to the API description.
|
9
|
-
class RuntimeResponse
|
10
|
-
extend Forwardable
|
11
|
-
|
12
|
-
def initialize(operation, rack_response)
|
13
|
-
@operation = operation
|
14
|
-
@rack_response = rack_response
|
15
|
-
end
|
16
|
-
|
17
|
-
# @return [Failure, nil] Error object if validation failed.
|
18
|
-
attr_accessor :error
|
19
|
-
|
20
|
-
# @visibility private
|
21
|
-
attr_accessor :operation
|
22
|
-
|
23
|
-
# @attr_reader [Integer] status The HTTP status code of this response.
|
24
|
-
# @attr_reader [String] content_type The content_type of the Rack::Response.
|
25
|
-
def_delegators :@rack_response, :status, :content_type
|
26
|
-
|
27
|
-
# @return [String] name The name of the operation. Used for generating error messages.
|
28
|
-
def name
|
29
|
-
"#{@operation.name} response status: #{status}"
|
30
|
-
end
|
31
|
-
|
32
|
-
# Checks if the response is valid. Runs the validation unless it has been run before.
|
33
|
-
# @return [Boolean]
|
34
|
-
def valid?
|
35
|
-
validate unless validated?
|
36
|
-
@error.nil?
|
37
|
-
end
|
38
|
-
|
39
|
-
# Checks if the response is defined in the API description.
|
40
|
-
# @return [Boolean] Returns true if the response is known, false otherwise.
|
41
|
-
def known?
|
42
|
-
!!response_definition
|
43
|
-
end
|
44
|
-
|
45
|
-
# Checks if the response status is defined in the API description.
|
46
|
-
# @return [Boolean] Returns true if the response status is known, false otherwise.
|
47
|
-
def known_status?
|
48
|
-
@operation.response_status_defined?(status)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Returns the description of the response definition if available.
|
52
|
-
# @return [String, nil] Returns the description of the response, or nil if not available.
|
53
|
-
def description
|
54
|
-
response_definition&.description
|
55
|
-
end
|
56
|
-
|
57
|
-
# Returns the parsed (JSON) body of the response.
|
58
|
-
# @return [Hash, String] Returns the body of the response.
|
59
|
-
def body
|
60
|
-
@body ||= content_type =~ /json/i ? load_json(original_body) : original_body
|
61
|
-
end
|
62
|
-
|
63
|
-
# Returns the headers of the response as defined in the API description.
|
64
|
-
# This only returns the headers that are defined in the API description.
|
65
|
-
# @return [Hash] Returns the headers of the response.
|
66
|
-
def headers
|
67
|
-
@headers ||= unpack_response_headers
|
68
|
-
end
|
69
|
-
|
70
|
-
# Validates the response.
|
71
|
-
# @return [Failure, nil] Returns the validation error, or nil if the response is valid.
|
72
|
-
# @deprecated Please use {Definition#validate_response} instead
|
73
|
-
def validate
|
74
|
-
warn '[DEPRECATION] `validate` is deprecated. ' \
|
75
|
-
"Please use `OpenapiFirst.load('openapi.yaml').validate_response(rack_request, rack_response)` instead."
|
76
|
-
@error = ResponseValidation::Validator.new(@operation).validate(self)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Validates the response and raises an error if invalid.
|
80
|
-
# @raise [ResponseNotFoundError, ResponseInvalidError] Raises an error if the response is invalid.
|
81
|
-
def validate!
|
82
|
-
error = validate
|
83
|
-
error&.raise!
|
84
|
-
end
|
85
|
-
|
86
|
-
# Returns the response definition associated with the response.
|
87
|
-
# @return [Definition::Response, nil] Returns the response definition, or nil if not found.
|
88
|
-
def response_definition
|
89
|
-
@response_definition ||= @operation.response_for(status, content_type)
|
90
|
-
end
|
91
|
-
|
92
|
-
private
|
93
|
-
|
94
|
-
def validated?
|
95
|
-
defined?(@error)
|
96
|
-
end
|
97
|
-
|
98
|
-
# Usually the body responds to #each, but when using manual response validation without the middleware
|
99
|
-
# in Rails request specs the body is a String. So this code handles both cases.
|
100
|
-
def original_body
|
101
|
-
buffered_body = String.new
|
102
|
-
if @rack_response.body.respond_to?(:each)
|
103
|
-
@rack_response.body.each { |chunk| buffered_body.to_s << chunk }
|
104
|
-
return buffered_body
|
105
|
-
end
|
106
|
-
@rack_response.body
|
107
|
-
end
|
108
|
-
|
109
|
-
def load_json(string)
|
110
|
-
MultiJson.load(string)
|
111
|
-
rescue MultiJson::ParseError
|
112
|
-
raise ParseError, 'Failed to parse response body as JSON'
|
113
|
-
end
|
114
|
-
|
115
|
-
def unpack_response_headers
|
116
|
-
return {} if response_definition&.headers.nil?
|
117
|
-
|
118
|
-
headers_as_parameters = response_definition.headers.map do |name, definition|
|
119
|
-
definition.merge('name' => name, 'in' => 'header')
|
120
|
-
end
|
121
|
-
OpenapiParameters::Header.new(headers_as_parameters).unpack(@rack_response.headers)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|