openapi-ruby 3.1.0 → 3.1.1
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/README.md +0 -1
- data/lib/generators/openapi_ruby/install/templates/initializer.rb.tt +0 -3
- data/lib/openapi_ruby/adapters/minitest.rb +1 -1
- data/lib/openapi_ruby/adapters/rspec.rb +43 -6
- data/lib/openapi_ruby/configuration.rb +22 -17
- data/lib/openapi_ruby/generator/schema_writer.rb +7 -2
- data/lib/openapi_ruby/middleware/schema_resolver.rb +8 -4
- data/lib/openapi_ruby/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 953f7f56ecdec3d8ee0f1f1261e49328e53d0aab5041b43f47a6e1138a2e880f
|
|
4
|
+
data.tar.gz: bec8a51340348604307f17791824d9327e7ceee7b58a8f35533ef7036c12156f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c62b49da036fe1dbb27b3f7ce2937a044427ea89ded288bdab1c33dab6fc041e31c89ecb75fd2e2419731cd0f803428baed9ed5152cdf01d7cd77b42b004642e
|
|
7
|
+
data.tar.gz: 5e2bbbcf02c286120207fc06a9f86c66b2618c9766a78b4b94c215641d0c2a5173aa4c45705e4fd2e6ed909271c63000a65182d159f22f3d716a4742dcbc6bae
|
data/README.md
CHANGED
|
@@ -63,7 +63,6 @@ OpenapiRuby.configure do |config|
|
|
|
63
63
|
config.camelize_keys = true
|
|
64
64
|
config.schema_output_dir = "swagger"
|
|
65
65
|
config.schema_output_format = :yaml
|
|
66
|
-
config.validate_responses_in_tests = true
|
|
67
66
|
|
|
68
67
|
# Runtime middleware (disabled by default)
|
|
69
68
|
config.request_validation = :disabled # :enabled, :disabled, :warn_only
|
|
@@ -20,9 +20,6 @@ OpenapiRuby.configure do |config|
|
|
|
20
20
|
config.schema_output_dir = "swagger"
|
|
21
21
|
config.schema_output_format = :yaml
|
|
22
22
|
|
|
23
|
-
# Validate response bodies in tests against defined schemas
|
|
24
|
-
config.validate_responses_in_tests = true
|
|
25
|
-
|
|
26
23
|
# Runtime request/response validation middleware
|
|
27
24
|
# Options: :disabled, :enabled, :warn_only
|
|
28
25
|
config.request_validation = :disabled
|
|
@@ -87,7 +87,7 @@ module OpenapiRuby
|
|
|
87
87
|
assert_equal expected_status, response.status,
|
|
88
88
|
"Expected status #{expected_status}, got #{response.status}\nResponse body: #{response.body}"
|
|
89
89
|
|
|
90
|
-
if
|
|
90
|
+
if response_ctx.schema_definition
|
|
91
91
|
validator = Testing::ResponseValidator.new
|
|
92
92
|
body_data = parse_response_body
|
|
93
93
|
errors = validator.validate(
|
|
@@ -144,6 +144,12 @@ module OpenapiRuby
|
|
|
144
144
|
accept = resolve_let(:Accept)
|
|
145
145
|
headers["Accept"] = accept || "application/json"
|
|
146
146
|
|
|
147
|
+
# Always append query params to the URL so the middleware sees them
|
|
148
|
+
# (Rails sends params as request body for non-GET methods).
|
|
149
|
+
if params.any?
|
|
150
|
+
path = "#{path}?#{Rack::Utils.build_nested_query(params)}"
|
|
151
|
+
end
|
|
152
|
+
|
|
147
153
|
if body
|
|
148
154
|
content_type = operation&.request_body_definition&.dig("content")&.keys&.first || "application/json"
|
|
149
155
|
request_args = if content_type.include?("form-data") || content_type.include?("x-www-form-urlencoded")
|
|
@@ -154,13 +160,8 @@ module OpenapiRuby
|
|
|
154
160
|
headers: headers.merge("Content-Type" => content_type)
|
|
155
161
|
}
|
|
156
162
|
end
|
|
157
|
-
# Append query params to path when body is present
|
|
158
|
-
if params.any?
|
|
159
|
-
query_string = params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
|
|
160
|
-
path = "#{path}?#{query_string}"
|
|
161
|
-
end
|
|
162
163
|
else
|
|
163
|
-
request_args = {
|
|
164
|
+
request_args = {headers: headers}
|
|
164
165
|
end
|
|
165
166
|
|
|
166
167
|
send(method.to_sym, path, **request_args)
|
|
@@ -177,6 +178,19 @@ module OpenapiRuby
|
|
|
177
178
|
"Expected status #{expected_status}, got #{actual_status}\n" \
|
|
178
179
|
"Response body: #{response.body}"
|
|
179
180
|
end
|
|
181
|
+
|
|
182
|
+
if response_ctx.schema_definition
|
|
183
|
+
schema_name = find_in_metadata(metadata, :openapi_schema_name)
|
|
184
|
+
validator = Testing::ResponseValidator.new(OpenapiRuby::Adapters::RSpec.validation_document_for(schema_name))
|
|
185
|
+
errors = validator.validate(
|
|
186
|
+
response_body: parsed_response_body,
|
|
187
|
+
status_code: response.status,
|
|
188
|
+
response_context: response_ctx
|
|
189
|
+
)
|
|
190
|
+
unless errors.empty?
|
|
191
|
+
raise "Response body validation failed:\n#{errors.join("\n")}\nResponse body: #{response.body}"
|
|
192
|
+
end
|
|
193
|
+
end
|
|
180
194
|
end
|
|
181
195
|
|
|
182
196
|
private
|
|
@@ -269,6 +283,29 @@ module OpenapiRuby
|
|
|
269
283
|
end
|
|
270
284
|
end
|
|
271
285
|
|
|
286
|
+
# Build the OpenAPI document hash for a given schema name and cache it.
|
|
287
|
+
# Used by response body validation so $ref schemas can be resolved.
|
|
288
|
+
def self.validation_document_for(schema_name)
|
|
289
|
+
return nil unless schema_name
|
|
290
|
+
|
|
291
|
+
key = schema_name.to_sym
|
|
292
|
+
@validation_documents ||= {}
|
|
293
|
+
@validation_documents[key] ||= begin
|
|
294
|
+
config = OpenapiRuby.configuration
|
|
295
|
+
schema_config = config.schemas[key] || config.schemas[schema_name.to_s]
|
|
296
|
+
return nil unless schema_config
|
|
297
|
+
|
|
298
|
+
builder = OpenapiRuby::Core::DocumentBuilder.new(schema_config)
|
|
299
|
+
OpenapiRuby::DSL::MetadataStore.contexts_for(schema_name).each do |context|
|
|
300
|
+
builder.add_path(context.path_template, context.to_openapi)
|
|
301
|
+
end
|
|
302
|
+
scope = schema_config[:component_scope]
|
|
303
|
+
loader = OpenapiRuby::Components::Loader.new(scope: scope)
|
|
304
|
+
builder.merge_components(loader.to_openapi_hash)
|
|
305
|
+
builder.build.data
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
272
309
|
def self.install!
|
|
273
310
|
::RSpec.configure do |config|
|
|
274
311
|
config.extend ExampleGroupHelpers, type: :openapi
|
|
@@ -9,46 +9,51 @@ module OpenapiRuby
|
|
|
9
9
|
# Components
|
|
10
10
|
attr_accessor :component_paths
|
|
11
11
|
attr_accessor :component_scope_paths
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
attr_accessor :
|
|
12
|
+
|
|
13
|
+
# Output / formatting
|
|
14
|
+
attr_accessor :camelize_keys, :schema_output_format, :schema_output_dir
|
|
15
15
|
attr_accessor :auto_validation_error_response
|
|
16
16
|
attr_accessor :validation_error_schema
|
|
17
17
|
|
|
18
18
|
# Middleware (runtime validation)
|
|
19
|
-
attr_accessor :request_validation
|
|
19
|
+
attr_accessor :request_validation, :response_validation, :coerce_params
|
|
20
20
|
|
|
21
|
-
#
|
|
22
|
-
|
|
21
|
+
# OpenAPI meta-schema validation of generated specs and middleware-loaded
|
|
22
|
+
# documents. One of :disabled, :enabled (raise on errors), :warn_only
|
|
23
|
+
# (default, log warnings). Boolean values are accepted for backwards
|
|
24
|
+
# compatibility: `true` → :warn_only, `false` → :disabled.
|
|
25
|
+
attr_reader :strict_reference_validation
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
def strict_reference_validation=(value)
|
|
28
|
+
@strict_reference_validation = case value
|
|
29
|
+
when true, :warn_only then :warn_only
|
|
30
|
+
when false, :disabled then :disabled
|
|
31
|
+
when :enabled then :enabled
|
|
32
|
+
else
|
|
33
|
+
raise ConfigurationError,
|
|
34
|
+
"strict_reference_validation must be :disabled, :enabled, :warn_only, or a boolean"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
26
37
|
|
|
27
|
-
#
|
|
28
|
-
attr_accessor :
|
|
38
|
+
# UI (optional)
|
|
39
|
+
attr_accessor :ui_enabled, :ui_path, :ui_config
|
|
29
40
|
|
|
30
41
|
def initialize
|
|
31
42
|
@schemas = {}
|
|
32
43
|
@component_paths = ["app/api_components"]
|
|
33
44
|
@component_scope_paths = {}
|
|
34
45
|
@camelize_keys = true
|
|
35
|
-
@key_transform = nil
|
|
36
46
|
@request_validation = :disabled
|
|
37
47
|
@response_validation = :disabled
|
|
38
|
-
@strict_query_params = false
|
|
39
48
|
@coerce_params = true
|
|
40
|
-
@error_handler = nil
|
|
41
49
|
@schema_output_dir = "swagger"
|
|
42
50
|
@schema_output_format = :yaml
|
|
43
|
-
@validate_responses_in_tests = true
|
|
44
51
|
@ui_enabled = false
|
|
45
52
|
@ui_path = "/api-docs"
|
|
46
53
|
@ui_config = {}
|
|
47
|
-
@strict_reference_validation =
|
|
54
|
+
@strict_reference_validation = :warn_only
|
|
48
55
|
@auto_validation_error_response = true
|
|
49
56
|
@validation_error_schema = nil
|
|
50
|
-
@coverage_enabled = false
|
|
51
|
-
@coverage_report_path = "tmp/openapi_coverage.json"
|
|
52
57
|
end
|
|
53
58
|
|
|
54
59
|
def validate!
|
|
@@ -23,7 +23,7 @@ module OpenapiRuby
|
|
|
23
23
|
|
|
24
24
|
def write!
|
|
25
25
|
document = build_document
|
|
26
|
-
validate_document!(document)
|
|
26
|
+
validate_document!(document) unless OpenapiRuby.configuration.strict_reference_validation == :disabled
|
|
27
27
|
output_path = File.join(output_dir, filename)
|
|
28
28
|
FileUtils.mkdir_p(output_dir)
|
|
29
29
|
File.write(output_path, format_output(document))
|
|
@@ -63,7 +63,12 @@ module OpenapiRuby
|
|
|
63
63
|
return if errors.empty?
|
|
64
64
|
|
|
65
65
|
error_messages = errors.first(10).map { |e| e["error"] || e.to_s }
|
|
66
|
-
|
|
66
|
+
message = "[openapi_ruby] Generated schema '#{@schema_name}' has validation errors:\n#{error_messages.join("\n")}"
|
|
67
|
+
if OpenapiRuby.configuration.strict_reference_validation == :enabled
|
|
68
|
+
raise OpenapiRuby::ConfigurationError, message
|
|
69
|
+
else
|
|
70
|
+
warn message
|
|
71
|
+
end
|
|
67
72
|
end
|
|
68
73
|
|
|
69
74
|
def format_output(document)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module OpenapiRuby
|
|
4
4
|
module Middleware
|
|
5
5
|
class SchemaResolver
|
|
6
|
-
def initialize(spec_path: nil, document: nil, strict_reference_validation:
|
|
6
|
+
def initialize(spec_path: nil, document: nil, strict_reference_validation: :warn_only)
|
|
7
7
|
@spec_path = spec_path
|
|
8
8
|
@document = document
|
|
9
9
|
@strict_reference_validation = strict_reference_validation
|
|
@@ -41,15 +41,19 @@ module OpenapiRuby
|
|
|
41
41
|
private
|
|
42
42
|
|
|
43
43
|
def validate_document!(doc)
|
|
44
|
-
return
|
|
44
|
+
return if @strict_reference_validation == :disabled
|
|
45
45
|
|
|
46
46
|
schemer = JSONSchemer.openapi(doc)
|
|
47
47
|
errors = schemer.validate.to_a
|
|
48
48
|
return if errors.empty?
|
|
49
49
|
|
|
50
50
|
error_messages = errors.first(5).map { |e| e["error"] || e.to_s }
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
message = "OpenAPI document validation failed:\n#{error_messages.join("\n")}"
|
|
52
|
+
if @strict_reference_validation == :enabled
|
|
53
|
+
raise OpenapiRuby::ConfigurationError, message
|
|
54
|
+
else
|
|
55
|
+
warn message
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
58
|
|
|
55
59
|
def load_document
|
data/lib/openapi_ruby/version.rb
CHANGED