committee 5.0.0 → 5.5.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/lib/committee/drivers.rb +29 -7
- data/lib/committee/middleware/request_validation.rb +2 -1
- data/lib/committee/request_unpacker.rb +6 -1
- data/lib/committee/schema_validator/hyper_schema/response_validator.rb +14 -4
- data/lib/committee/schema_validator/hyper_schema.rb +1 -1
- data/lib/committee/schema_validator/open_api_3/request_validator.rb +2 -2
- data/lib/committee/schema_validator/open_api_3.rb +2 -2
- data/lib/committee/schema_validator/option.rb +29 -20
- data/lib/committee/version.rb +1 -1
- data/lib/committee.rb +1 -1
- data/test/bin/committee_stub_test.rb +0 -2
- data/test/committee_test.rb +8 -6
- data/test/drivers_test.rb +43 -0
- data/test/middleware/base_test.rb +0 -3
- data/test/middleware/request_validation_open_api_3_test.rb +3 -6
- data/test/middleware/request_validation_test.rb +0 -3
- data/test/middleware/response_validation_open_api_3_test.rb +0 -3
- data/test/middleware/response_validation_test.rb +23 -11
- data/test/middleware/stub_test.rb +0 -3
- data/test/schema_validator/hyper_schema/router_test.rb +0 -4
- data/test/schema_validator/open_api_3/operation_wrapper_test.rb +1 -6
- data/test/schema_validator/open_api_3/request_validator_test.rb +7 -3
- data/test/schema_validator/open_api_3/response_validator_test.rb +1 -5
- data/test/test/methods_new_version_test.rb +0 -3
- data/test/test/methods_test.rb +7 -10
- data/test/test_helper.rb +12 -1
- metadata +24 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 426a690ac272e53e30d9572a33564ea8cb7f2e92617e9dcd11b8061e32936b2f
|
4
|
+
data.tar.gz: c335a7d5bb6fe299d6584bf5838ac7972f9be312f431d15db8942cdd3c473cf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e83410d227c6704e208c0bbac5e452a34887921fee1b3f9dbe5c082bbc5861533e49882428e94bb78140d647550047f57b990e7896583a6f18d8ee76d6fdb17
|
7
|
+
data.tar.gz: 610c2002488ee37be624df996fbfbfb9609c416a911583ed3177a0917061908c0efa71324d56b7b90e77ea538b8f6e00c8785c210bd2d8e67c8398177e3269fd
|
data/lib/committee/drivers.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'digest'
|
4
|
+
|
3
5
|
module Committee
|
4
6
|
module Drivers
|
5
7
|
# Gets a driver instance from the specified name. Raises ArgumentError for
|
@@ -36,13 +38,16 @@ module Committee
|
|
36
38
|
# @param [String] schema_path
|
37
39
|
# @return [Committee::Driver]
|
38
40
|
def self.load_from_file(schema_path, parser_options: {})
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
@__load_from_file_cache ||= {}
|
42
|
+
@__load_from_file_cache[cache_key(schema_path, parser_options)] ||= begin
|
43
|
+
case File.extname(schema_path)
|
44
|
+
when '.json'
|
45
|
+
load_from_json(schema_path, parser_options: parser_options)
|
46
|
+
when '.yaml', '.yml'
|
47
|
+
load_from_yaml(schema_path, parser_options: parser_options)
|
48
|
+
else
|
49
|
+
raise "Committee only supports the following file extensions: '.json', '.yaml', '.yml'"
|
50
|
+
end
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
@@ -65,6 +70,12 @@ module Committee
|
|
65
70
|
return Committee::Drivers::OpenAPI3::Driver.new.parse(openapi)
|
66
71
|
end
|
67
72
|
|
73
|
+
if (version = hash['openapi'])
|
74
|
+
if Gem::Version.new(version) >= Gem::Version.new("3.1")
|
75
|
+
raise OpenAPI3Unsupported.new('Committee does not support OpenAPI 3.1+ yet')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
68
79
|
driver = if hash['swagger'] == '2.0'
|
69
80
|
Committee::Drivers::OpenAPI2::Driver.new
|
70
81
|
else
|
@@ -74,6 +85,17 @@ module Committee
|
|
74
85
|
# TODO: in the future, pass `opts` here and allow optionality in other drivers?
|
75
86
|
driver.parse(hash)
|
76
87
|
end
|
88
|
+
|
89
|
+
class << self
|
90
|
+
private
|
91
|
+
|
92
|
+
def cache_key(schema_path, parser_options)
|
93
|
+
[
|
94
|
+
File.exist?(schema_path) ? Digest::MD5.hexdigest(File.read(schema_path)) : nil,
|
95
|
+
parser_options.hash,
|
96
|
+
].join('_')
|
97
|
+
end
|
98
|
+
end
|
77
99
|
end
|
78
100
|
end
|
79
101
|
|
@@ -6,7 +6,7 @@ module Committee
|
|
6
6
|
def initialize(app, options={})
|
7
7
|
super
|
8
8
|
|
9
|
-
@strict
|
9
|
+
@strict = options[:strict]
|
10
10
|
end
|
11
11
|
|
12
12
|
def handle(request)
|
@@ -20,6 +20,7 @@ module Committee
|
|
20
20
|
raise if @raise
|
21
21
|
return @error_class.new(400, :bad_request, $!.message, request).render unless @ignore_error
|
22
22
|
rescue Committee::NotFound => e
|
23
|
+
handle_exception($!, request.env)
|
23
24
|
raise if @raise
|
24
25
|
return @error_class.new(404, :not_found, e.message, request).render unless @ignore_error
|
25
26
|
rescue JSON::ParserError
|
@@ -46,7 +46,11 @@ module Committee
|
|
46
46
|
if @allow_form_params && %w[application/x-www-form-urlencoded multipart/form-data].include?(request.media_type)
|
47
47
|
# Actually, POST means anything in the request body, could be from
|
48
48
|
# PUT or PATCH too. Silly Rack.
|
49
|
-
|
49
|
+
begin
|
50
|
+
return [request.POST, true] if request.POST
|
51
|
+
ensure
|
52
|
+
request.body.rewind
|
53
|
+
end
|
50
54
|
end
|
51
55
|
|
52
56
|
[{}, false]
|
@@ -73,6 +77,7 @@ module Committee
|
|
73
77
|
def parse_json(request)
|
74
78
|
return nil if request.request_method == "GET" && !@allow_get_body
|
75
79
|
|
80
|
+
return nil if request.body.nil?
|
76
81
|
body = request.body.read
|
77
82
|
# if request body is empty, we just have empty params
|
78
83
|
return nil if body.length == 0
|
@@ -4,11 +4,12 @@ module Committee
|
|
4
4
|
module SchemaValidator
|
5
5
|
class HyperSchema
|
6
6
|
class ResponseValidator
|
7
|
-
attr_reader :validate_success_only
|
7
|
+
attr_reader :allow_blank_structures, :validate_success_only
|
8
8
|
|
9
9
|
def initialize(link, options = {})
|
10
10
|
@link = link
|
11
11
|
@validate_success_only = options[:validate_success_only]
|
12
|
+
@allow_blank_structures = options[:allow_blank_structures]
|
12
13
|
|
13
14
|
@validator = JsonSchema::Validator.new(target_schema(link))
|
14
15
|
end
|
@@ -39,9 +40,18 @@ module Committee
|
|
39
40
|
return if data == nil
|
40
41
|
end
|
41
42
|
|
42
|
-
if Committee::
|
43
|
-
|
44
|
-
|
43
|
+
if allow_blank_structures && @link.is_a?(Committee::Drivers::OpenAPI2::Link) && !@link.target_schema
|
44
|
+
return if data.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
if Committee::Middleware::ResponseValidation.validate?(status, validate_success_only) && !@validator.validate(data)
|
49
|
+
errors = JsonSchema::SchemaError.aggregate(@validator.errors).join("\n")
|
50
|
+
raise InvalidResponse, "Invalid response.\n\n#{errors}"
|
51
|
+
end
|
52
|
+
rescue => e
|
53
|
+
raise InvalidResponse, "Invalid response.\n\nschema is undefined" if /undefined method .all_of. for nil/ =~ e.message
|
54
|
+
raise e
|
45
55
|
end
|
46
56
|
end
|
47
57
|
|
@@ -33,7 +33,7 @@ module Committee
|
|
33
33
|
data = JSON.parse(full_body) if parse_to_json
|
34
34
|
end
|
35
35
|
|
36
|
-
Committee::SchemaValidator::HyperSchema::ResponseValidator.new(link, validate_success_only: validator_option.validate_success_only).call(status, headers, data)
|
36
|
+
Committee::SchemaValidator::HyperSchema::ResponseValidator.new(link, validate_success_only: validator_option.validate_success_only, allow_blank_structures: validator_option.allow_blank_structures).call(status, headers, data)
|
37
37
|
end
|
38
38
|
|
39
39
|
def link_exist?
|
@@ -21,8 +21,8 @@ module Committee
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def check_content_type(request, content_type)
|
24
|
-
# support post, put, patch only
|
25
|
-
return true unless request.post? || request.put? || request.patch?
|
24
|
+
# support post, put, patch, options only
|
25
|
+
return true unless request.post? || request.put? || request.patch? || request.options?
|
26
26
|
return true if @operation_object.valid_request_content_type?(content_type)
|
27
27
|
return true if @operation_object.optional_body? && empty_request?(request)
|
28
28
|
|
@@ -87,7 +87,7 @@ module Committee
|
|
87
87
|
|
88
88
|
request.env[validator_option.headers_key] = unpacker.unpack_headers(request)
|
89
89
|
|
90
|
-
request_param,
|
90
|
+
request_param, _is_form_params = unpacker.unpack_request_params(request)
|
91
91
|
request.env[validator_option.request_body_hash_key] = request_param
|
92
92
|
request.env[validator_option.path_hash_key] = coerce_path_params
|
93
93
|
|
@@ -97,7 +97,7 @@ module Committee
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def copy_coerced_data_to_params(request)
|
100
|
-
order = if validator_option.
|
100
|
+
order = if validator_option.parameter_overwrite_by_rails_rule
|
101
101
|
# (high priority) path_hash_key -> query_param -> request_body_hash
|
102
102
|
[validator_option.request_body_hash_key, validator_option.query_hash_key, validator_option.path_hash_key]
|
103
103
|
else
|
@@ -4,7 +4,8 @@ module Committee
|
|
4
4
|
module SchemaValidator
|
5
5
|
class Option
|
6
6
|
# Boolean Options
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :allow_blank_structures,
|
8
|
+
:allow_form_params,
|
8
9
|
:allow_get_body,
|
9
10
|
:allow_query_params,
|
10
11
|
:check_content_type,
|
@@ -17,7 +18,7 @@ module Committee
|
|
17
18
|
:optimistic_json,
|
18
19
|
:validate_success_only,
|
19
20
|
:parse_response_by_content_type,
|
20
|
-
:
|
21
|
+
:parameter_overwrite_by_rails_rule
|
21
22
|
|
22
23
|
# Non-boolean options:
|
23
24
|
attr_reader :headers_key,
|
@@ -29,30 +30,38 @@ module Committee
|
|
29
30
|
|
30
31
|
def initialize(options, schema, schema_type)
|
31
32
|
# Non-boolean options
|
32
|
-
@headers_key
|
33
|
-
@params_key
|
34
|
-
@query_hash_key
|
35
|
-
@path_hash_key
|
33
|
+
@headers_key = options[:headers_key] || "committee.headers"
|
34
|
+
@params_key = options[:params_key] || "committee.params"
|
35
|
+
@query_hash_key = options[:query_hash_key] || "committee.query_hash"
|
36
|
+
@path_hash_key = options[:path_hash_key] || "committee.path_hash"
|
36
37
|
@request_body_hash_key = options[:request_body_hash_key] || "committee.request_body_hash"
|
37
38
|
|
38
|
-
@prefix
|
39
|
+
@prefix = options[:prefix]
|
39
40
|
|
40
41
|
# Boolean options and have a common value by default
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@
|
45
|
-
@
|
46
|
-
@
|
47
|
-
@
|
48
|
-
@
|
42
|
+
@allow_blank_structures = options.fetch(:allow_blank_structures, false)
|
43
|
+
@allow_form_params = options.fetch(:allow_form_params, true)
|
44
|
+
@allow_query_params = options.fetch(:allow_query_params, true)
|
45
|
+
@check_content_type = options.fetch(:check_content_type, true)
|
46
|
+
@check_header = options.fetch(:check_header, true)
|
47
|
+
@coerce_recursive = options.fetch(:coerce_recursive, true)
|
48
|
+
@optimistic_json = options.fetch(:optimistic_json, false)
|
49
|
+
@parse_response_by_content_type = options.fetch(:parse_response_by_content_type, true)
|
50
|
+
|
51
|
+
@parameter_overwrite_by_rails_rule =
|
52
|
+
if options.key?(:parameter_overwite_by_rails_rule)
|
53
|
+
Committee.warn_deprecated_until_6(true, "The option `parameter_overwite_by_rails_rule` is deprecated. Use `parameter_overwrite_by_rails_rule` instead.")
|
54
|
+
options[:parameter_overwite_by_rails_rule]
|
55
|
+
else
|
56
|
+
options.fetch(:parameter_overwrite_by_rails_rule, true)
|
57
|
+
end
|
49
58
|
|
50
59
|
# Boolean options and have a different value by default
|
51
|
-
@allow_get_body
|
52
|
-
@coerce_date_times
|
53
|
-
@coerce_form_params
|
54
|
-
@coerce_path_params
|
55
|
-
@coerce_query_params
|
60
|
+
@allow_get_body = options.fetch(:allow_get_body, schema.driver.default_allow_get_body)
|
61
|
+
@coerce_date_times = options.fetch(:coerce_date_times, schema.driver.default_coerce_date_times)
|
62
|
+
@coerce_form_params = options.fetch(:coerce_form_params, schema.driver.default_coerce_form_params)
|
63
|
+
@coerce_path_params = options.fetch(:coerce_path_params, schema.driver.default_path_params)
|
64
|
+
@coerce_query_params = options.fetch(:coerce_query_params, schema.driver.default_query_params)
|
56
65
|
@validate_success_only = options.fetch(:validate_success_only, schema.driver.default_validate_success_only)
|
57
66
|
end
|
58
67
|
end
|
data/lib/committee/version.rb
CHANGED
data/lib/committee.rb
CHANGED
@@ -22,7 +22,7 @@ module Committee
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.warn_deprecated_until_6(cond, message)
|
25
|
-
raise "remove deprecated!"
|
25
|
+
raise "remove deprecated!" unless Committee::VERSION.start_with?("5")
|
26
26
|
warn("[DEPRECATION] #{message}") if cond
|
27
27
|
end
|
28
28
|
end
|
data/test/committee_test.rb
CHANGED
@@ -19,13 +19,15 @@ describe Committee do
|
|
19
19
|
old_stderr = $stderr
|
20
20
|
$stderr = StringIO.new
|
21
21
|
begin
|
22
|
-
stub(
|
23
|
-
|
24
|
-
|
22
|
+
Committee.stub(:debug?, false) do
|
23
|
+
Committee.log_debug "blah"
|
24
|
+
assert_equal "", $stderr.string
|
25
|
+
end
|
25
26
|
|
26
|
-
stub(
|
27
|
-
|
28
|
-
|
27
|
+
Committee.stub(:debug?, true) do
|
28
|
+
Committee.log_debug "blah"
|
29
|
+
assert_equal "blah\n", $stderr.string
|
30
|
+
end
|
29
31
|
ensure
|
30
32
|
$stderr = old_stderr
|
31
33
|
end
|
data/test/drivers_test.rb
CHANGED
@@ -48,6 +48,13 @@ describe Committee::Drivers do
|
|
48
48
|
assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
|
49
49
|
end
|
50
50
|
|
51
|
+
it 'fails to load OpenAPI 3.1+' do
|
52
|
+
e = assert_raises(Committee::OpenAPI3Unsupported) do
|
53
|
+
Committee::Drivers.load_from_file(open_api_3_1_schema_path, parser_options:{strict_reference_validation: true})
|
54
|
+
end
|
55
|
+
assert_equal 'Committee does not support OpenAPI 3.1+ yet', e.message
|
56
|
+
end
|
57
|
+
|
51
58
|
it 'fails to load OpenAPI 3 with invalid reference' do
|
52
59
|
parser_options = { strict_reference_validation: true }
|
53
60
|
assert_raises(OpenAPIParser::MissingReferenceError) do
|
@@ -67,6 +74,35 @@ describe Committee::Drivers do
|
|
67
74
|
end
|
68
75
|
assert_equal "Committee only supports the following file extensions: '.json', '.yaml', '.yml'", e.message
|
69
76
|
end
|
77
|
+
|
78
|
+
describe 'cache behavior' do
|
79
|
+
describe 'when loading the same file' do
|
80
|
+
it 'returns the same object when the options are identical' do
|
81
|
+
assert_equal(
|
82
|
+
Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
|
83
|
+
Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns different objects if the options are different' do
|
88
|
+
refute_equal(
|
89
|
+
Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
|
90
|
+
Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: false}).object_id,
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'returns different objects if the file contents have changed' do
|
95
|
+
object_id = Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id
|
96
|
+
original_file_contents = File.read(open_api_3_schema_path)
|
97
|
+
File.write(open_api_3_schema_path, original_file_contents + "\n")
|
98
|
+
refute_equal(
|
99
|
+
Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true}).object_id,
|
100
|
+
object_id,
|
101
|
+
)
|
102
|
+
File.write(open_api_3_schema_path, original_file_contents)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
70
106
|
end
|
71
107
|
|
72
108
|
describe 'load_from_json(schema_path)' do
|
@@ -109,6 +145,13 @@ describe Committee::Drivers do
|
|
109
145
|
assert_kind_of Committee::Drivers::Schema, s
|
110
146
|
assert_kind_of Committee::Drivers::HyperSchema::Schema, s
|
111
147
|
end
|
148
|
+
|
149
|
+
it 'fails to load OpenAPI 3.1+' do
|
150
|
+
e = assert_raises(Committee::OpenAPI3Unsupported) do
|
151
|
+
Committee::Drivers.load_from_data(open_api_3_1_data)
|
152
|
+
end
|
153
|
+
assert_equal 'Committee does not support OpenAPI 3.1+ yet', e.message
|
154
|
+
end
|
112
155
|
end
|
113
156
|
end
|
114
157
|
|
@@ -117,9 +117,6 @@ describe Committee::Middleware::Base do
|
|
117
117
|
private
|
118
118
|
|
119
119
|
def new_rack_app(options = {})
|
120
|
-
# TODO: delete when 5.0.0 released because default value changed
|
121
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
122
|
-
|
123
120
|
Rack::Builder.new {
|
124
121
|
use Committee::Middleware::RequestValidation, options
|
125
122
|
run lambda { |_|
|
@@ -419,7 +419,7 @@ describe Committee::Middleware::RequestValidation do
|
|
419
419
|
assert_equal env['committee.query_hash']['integer'], 42
|
420
420
|
#assert_equal env['rack.request.query_hash'][:integer], 42 # this isn't hash indifferent hash because we use rack.request.query_hash
|
421
421
|
[204, {}, []]
|
422
|
-
end, schema: open_api_3_schema,
|
422
|
+
end, schema: open_api_3_schema, parameter_overwrite_by_rails_rule: false)
|
423
423
|
|
424
424
|
header "Content-Type", "application/json"
|
425
425
|
post '/overwrite_same_parameter?integer=42'
|
@@ -434,7 +434,7 @@ describe Committee::Middleware::RequestValidation do
|
|
434
434
|
assert_equal env['committee.request_body_hash'][:integer], 21
|
435
435
|
assert_equal env['committee.query_hash']['integer'], 42
|
436
436
|
[204, {}, []]
|
437
|
-
end, schema: open_api_3_schema,
|
437
|
+
end, schema: open_api_3_schema, parameter_overwrite_by_rails_rule: false)
|
438
438
|
|
439
439
|
params = {integer: 21}
|
440
440
|
|
@@ -454,7 +454,7 @@ describe Committee::Middleware::RequestValidation do
|
|
454
454
|
assert_equal env['committee.query_hash']['integer'], 84 # we can't use query_parameter :(
|
455
455
|
#assert_equal env['rack.request.query_hash'][:integer], 21 # this isn't hash indifferent hash because we use rack.request.query_hash
|
456
456
|
[204, {}, []]
|
457
|
-
end, schema: open_api_3_schema,
|
457
|
+
end, schema: open_api_3_schema, parameter_overwrite_by_rails_rule: false)
|
458
458
|
|
459
459
|
params = {integer: 21}
|
460
460
|
|
@@ -615,9 +615,6 @@ describe Committee::Middleware::RequestValidation do
|
|
615
615
|
end
|
616
616
|
|
617
617
|
def new_rack_app_with_lambda(check_lambda, options = {})
|
618
|
-
# TODO: delete when 5.0.0 released because default value changed
|
619
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
620
|
-
|
621
618
|
Rack::Builder.new {
|
622
619
|
use Committee::Middleware::RequestValidation, options
|
623
620
|
run check_lambda
|
@@ -505,9 +505,6 @@ describe Committee::Middleware::RequestValidation do
|
|
505
505
|
|
506
506
|
|
507
507
|
def new_rack_app_with_lambda(check_lambda, options = {})
|
508
|
-
# TODO: delete when 5.0.0 released because default value changed
|
509
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
510
|
-
|
511
508
|
Rack::Builder.new {
|
512
509
|
use Committee::Middleware::RequestValidation, options
|
513
510
|
run check_lambda
|
@@ -273,9 +273,6 @@ describe Committee::Middleware::ResponseValidation do
|
|
273
273
|
private
|
274
274
|
|
275
275
|
def new_response_rack(response, headers = {}, options = {}, rack_options = {})
|
276
|
-
# TODO: delete when 5.0.0 released because default value changed
|
277
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
278
|
-
|
279
276
|
status = rack_options[:status] || 200
|
280
277
|
content_type = rack_options[:content_type] || "application/json"
|
281
278
|
headers = {
|
@@ -15,14 +15,6 @@ describe Committee::Middleware::ResponseValidation do
|
|
15
15
|
assert_equal 200, last_response.status
|
16
16
|
end
|
17
17
|
|
18
|
-
# TODO: remove 5.0.0
|
19
|
-
it "passes through a valid response" do
|
20
|
-
# will show deprecated message
|
21
|
-
@app = new_rack_app(JSON.generate([ValidApp]), {}, schema: hyper_schema, strict: true)
|
22
|
-
get "/apps"
|
23
|
-
assert_equal 200, last_response.status
|
24
|
-
end
|
25
|
-
|
26
18
|
it "doesn't call error_handler (has a arg) when response is valid" do
|
27
19
|
called = false
|
28
20
|
pr = ->(_e) { called = true }
|
@@ -144,6 +136,29 @@ describe Committee::Middleware::ResponseValidation do
|
|
144
136
|
assert_equal 200, last_response.status
|
145
137
|
end
|
146
138
|
|
139
|
+
it "passes through a valid response for OpenAPI when data=nil, target_schema=empty, allow_blank_structures=true" do
|
140
|
+
@app = new_rack_app("null", {},
|
141
|
+
allow_blank_structures: true, schema: open_api_2_schema)
|
142
|
+
get "/api/pets/cat"
|
143
|
+
assert_equal 200, last_response.status
|
144
|
+
end
|
145
|
+
|
146
|
+
it "invalid responses for OpenAPI when data=nil, target_schema=empty, allow_blank_structures=false" do
|
147
|
+
@app = new_rack_app("null", {},
|
148
|
+
allow_blank_structures: false, schema: open_api_2_schema)
|
149
|
+
get "/api/pets/cat"
|
150
|
+
assert_equal 500, last_response.status
|
151
|
+
assert_match(/Invalid response/i, last_response.body)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "passes through a valid response for OpenAPI when data=nil, target_schema=present, allow_blank_structures=true" do
|
155
|
+
@app = new_rack_app("null", {},
|
156
|
+
allow_blank_structures: true, schema: open_api_2_schema)
|
157
|
+
get "/api/pets/dog"
|
158
|
+
assert_equal 500, last_response.status
|
159
|
+
assert_match(/nil is not an array/i, last_response.body)
|
160
|
+
end
|
161
|
+
|
147
162
|
it "detects an invalid response for OpenAPI" do
|
148
163
|
@app = new_rack_app("{_}", {}, schema: open_api_2_schema)
|
149
164
|
get "/api/pets"
|
@@ -173,9 +188,6 @@ describe Committee::Middleware::ResponseValidation do
|
|
173
188
|
private
|
174
189
|
|
175
190
|
def new_rack_app(response, headers = {}, options = {})
|
176
|
-
# TODO: delete when 5.0.0 released because default value changed
|
177
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
178
|
-
|
179
191
|
headers = {
|
180
192
|
"Content-Type" => "application/json"
|
181
193
|
}.merge(headers)
|
@@ -113,9 +113,6 @@ describe Committee::Middleware::Stub do
|
|
113
113
|
response = options.delete(:response)
|
114
114
|
suppress = options.delete(:suppress)
|
115
115
|
|
116
|
-
# TODO: delete when 5.0.0 released because default value changed
|
117
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
118
|
-
|
119
116
|
Rack::Builder.new {
|
120
117
|
use Committee::Middleware::Stub, options
|
121
118
|
run lambda { |env|
|
@@ -69,8 +69,6 @@ describe Committee::SchemaValidator::HyperSchema::Router do
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def hyper_schema_router(options = {})
|
72
|
-
# TODO: delete when 5.0.0 released because default value changed
|
73
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
74
72
|
schema = Committee::Drivers::HyperSchema::Driver.new.parse(hyper_schema_data)
|
75
73
|
validator_option = Committee::SchemaValidator::Option.new(options, schema, :hyper_schema)
|
76
74
|
|
@@ -78,8 +76,6 @@ describe Committee::SchemaValidator::HyperSchema::Router do
|
|
78
76
|
end
|
79
77
|
|
80
78
|
def open_api_2_router(options = {})
|
81
|
-
# TODO: delete when 5.0.0 released because default value changed
|
82
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
83
79
|
schema = Committee::Drivers::OpenAPI2::Driver.new.parse(open_api_2_data)
|
84
80
|
validator_option = Committee::SchemaValidator::Option.new(options, schema, :hyper_schema)
|
85
81
|
|
@@ -9,12 +9,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
9
9
|
before do
|
10
10
|
@path = '/validate'
|
11
11
|
@method = 'post'
|
12
|
-
|
13
|
-
# TODO: delete when 5.0.0 released because default value changed
|
14
|
-
options = {}
|
15
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
16
|
-
|
17
|
-
@validator_option = Committee::SchemaValidator::Option.new(options, open_api_3_schema, :open_api_3)
|
12
|
+
@validator_option = Committee::SchemaValidator::Option.new({}, open_api_3_schema, :open_api_3)
|
18
13
|
end
|
19
14
|
|
20
15
|
def operation_object
|
@@ -95,10 +95,14 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
|
|
95
95
|
assert_equal 400, last_response.status
|
96
96
|
end
|
97
97
|
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
it "validates content_type for option request" do
|
99
|
+
@app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
|
100
|
+
header "Content-Type", "text/html"
|
101
|
+
options "/validate", "{}"
|
102
|
+
assert_equal 400, last_response.status
|
103
|
+
end
|
101
104
|
|
105
|
+
def new_rack_app(options = {})
|
102
106
|
Rack::Builder.new {
|
103
107
|
use Committee::Middleware::RequestValidation, options
|
104
108
|
run lambda { |_|
|
@@ -13,11 +13,7 @@ describe Committee::SchemaValidator::OpenAPI3::ResponseValidator do
|
|
13
13
|
@path = '/validate'
|
14
14
|
@method = 'post'
|
15
15
|
|
16
|
-
|
17
|
-
options = {}
|
18
|
-
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
19
|
-
|
20
|
-
@validator_option = Committee::SchemaValidator::Option.new(options, open_api_3_schema, :open_api_3)
|
16
|
+
@validator_option = Committee::SchemaValidator::Option.new({}, open_api_3_schema, :open_api_3)
|
21
17
|
end
|
22
18
|
|
23
19
|
it "passes through a valid response" do
|
@@ -30,9 +30,6 @@ describe Committee::Test::Methods do
|
|
30
30
|
@committee_schema = nil
|
31
31
|
|
32
32
|
@committee_options = {schema: hyper_schema}
|
33
|
-
|
34
|
-
# TODO: delete when 5.0.0 released because default value changed
|
35
|
-
@committee_options[:parse_response_by_content_type] = false
|
36
33
|
end
|
37
34
|
|
38
35
|
describe "#assert_schema_conform" do
|
data/test/test/methods_test.rb
CHANGED
@@ -29,9 +29,6 @@ describe Committee::Test::Methods do
|
|
29
29
|
@committee_router = nil
|
30
30
|
@committee_schema = nil
|
31
31
|
@committee_options = {}
|
32
|
-
|
33
|
-
# TODO: delete when 5.0.0 released because default value changed
|
34
|
-
@committee_options[:parse_response_by_content_type] = true
|
35
32
|
end
|
36
33
|
|
37
34
|
describe "Hyper-Schema" do
|
@@ -61,13 +58,13 @@ describe Committee::Test::Methods do
|
|
61
58
|
|
62
59
|
describe "assert_request_schema_confirm" do
|
63
60
|
it "passes through a valid request" do
|
64
|
-
@app = new_rack_app
|
61
|
+
@app = new_rack_app
|
65
62
|
get "/apps"
|
66
63
|
assert_request_schema_confirm
|
67
64
|
end
|
68
65
|
|
69
66
|
it "not exist required" do
|
70
|
-
@app = new_rack_app
|
67
|
+
@app = new_rack_app
|
71
68
|
get "/search/apps", {}
|
72
69
|
e = assert_raises(Committee::InvalidRequest) do
|
73
70
|
assert_request_schema_confirm
|
@@ -76,7 +73,7 @@ describe Committee::Test::Methods do
|
|
76
73
|
end
|
77
74
|
|
78
75
|
it "path undefined in schema" do
|
79
|
-
@app = new_rack_app
|
76
|
+
@app = new_rack_app
|
80
77
|
get "/undefined"
|
81
78
|
e = assert_raises(Committee::InvalidRequest) do
|
82
79
|
assert_request_schema_confirm
|
@@ -149,13 +146,13 @@ describe Committee::Test::Methods do
|
|
149
146
|
|
150
147
|
describe "assert_request_schema_confirm" do
|
151
148
|
it "passes through a valid request" do
|
152
|
-
@app = new_rack_app
|
149
|
+
@app = new_rack_app
|
153
150
|
get "/characters"
|
154
151
|
assert_request_schema_confirm
|
155
152
|
end
|
156
153
|
|
157
154
|
it "not exist required" do
|
158
|
-
@app = new_rack_app
|
155
|
+
@app = new_rack_app
|
159
156
|
get "/validate", {"query_string" => "query", "query_integer_list" => [1, 2]}
|
160
157
|
e = assert_raises(Committee::InvalidRequest) do
|
161
158
|
assert_request_schema_confirm
|
@@ -165,7 +162,7 @@ describe Committee::Test::Methods do
|
|
165
162
|
end
|
166
163
|
|
167
164
|
it "path undefined in schema" do
|
168
|
-
@app = new_rack_app
|
165
|
+
@app = new_rack_app
|
169
166
|
get "/undefined"
|
170
167
|
e = assert_raises(Committee::InvalidRequest) do
|
171
168
|
assert_request_schema_confirm
|
@@ -353,7 +350,7 @@ describe Committee::Test::Methods do
|
|
353
350
|
|
354
351
|
private
|
355
352
|
|
356
|
-
def new_rack_app(response, headers={ "Content-Type" => "application/json" }, status_code = 200)
|
353
|
+
def new_rack_app(response = nil, headers={ "Content-Type" => "application/json" }, status_code = 200)
|
357
354
|
Rack::Builder.new {
|
358
355
|
run lambda { |_|
|
359
356
|
[status_code, headers, [response]]
|
data/test/test_helper.rb
CHANGED
@@ -21,7 +21,6 @@ require "minitest"
|
|
21
21
|
require "minitest/spec"
|
22
22
|
require "minitest/autorun"
|
23
23
|
require "rack/test"
|
24
|
-
require "rr"
|
25
24
|
require "pry"
|
26
25
|
require "stringio"
|
27
26
|
|
@@ -91,6 +90,14 @@ def open_api_3_data
|
|
91
90
|
end
|
92
91
|
end
|
93
92
|
|
93
|
+
def open_api_3_1_data
|
94
|
+
if YAML.respond_to?(:unsafe_load_file)
|
95
|
+
YAML.unsafe_load_file(open_api_3_1_schema_path)
|
96
|
+
else
|
97
|
+
YAML.load_file(open_api_3_1_schema_path)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
94
101
|
def hyper_schema_schema_path
|
95
102
|
"./test/data/hyperschema/paas.json"
|
96
103
|
end
|
@@ -115,6 +122,10 @@ def open_api_3_0_1_schema_path
|
|
115
122
|
"./test/data/openapi3/3_0_1.yaml"
|
116
123
|
end
|
117
124
|
|
125
|
+
def open_api_3_1_schema_path
|
126
|
+
"./test/data/openapi3/3_1.yaml"
|
127
|
+
end
|
128
|
+
|
118
129
|
def open_api_3_invalid_reference_path
|
119
130
|
"./test/data/openapi3/invalid_reference.yaml"
|
120
131
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: committee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandur
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2024-11-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json_schema
|
@@ -39,6 +39,9 @@ dependencies:
|
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '1.5'
|
42
|
+
- - "<"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '3.2'
|
42
45
|
type: :runtime
|
43
46
|
prerelease: false
|
44
47
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -46,20 +49,23 @@ dependencies:
|
|
46
49
|
- - ">="
|
47
50
|
- !ruby/object:Gem::Version
|
48
51
|
version: '1.5'
|
52
|
+
- - "<"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.2'
|
49
55
|
- !ruby/object:Gem::Dependency
|
50
56
|
name: openapi_parser
|
51
57
|
requirement: !ruby/object:Gem::Requirement
|
52
58
|
requirements:
|
53
59
|
- - "~>"
|
54
60
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
61
|
+
version: '2.0'
|
56
62
|
type: :runtime
|
57
63
|
prerelease: false
|
58
64
|
version_requirements: !ruby/object:Gem::Requirement
|
59
65
|
requirements:
|
60
66
|
- - "~>"
|
61
67
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
68
|
+
version: '2.0'
|
63
69
|
- !ruby/object:Gem::Dependency
|
64
70
|
name: minitest
|
65
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,44 +84,30 @@ dependencies:
|
|
78
84
|
name: rack-test
|
79
85
|
requirement: !ruby/object:Gem::Requirement
|
80
86
|
requirements:
|
81
|
-
- - "
|
87
|
+
- - ">="
|
82
88
|
- !ruby/object:Gem::Version
|
83
|
-
version: '0
|
89
|
+
version: '0'
|
84
90
|
type: :development
|
85
91
|
prerelease: false
|
86
92
|
version_requirements: !ruby/object:Gem::Requirement
|
87
93
|
requirements:
|
88
|
-
- - "
|
94
|
+
- - ">="
|
89
95
|
- !ruby/object:Gem::Version
|
90
|
-
version: '0
|
96
|
+
version: '0'
|
91
97
|
- !ruby/object:Gem::Dependency
|
92
98
|
name: rake
|
93
99
|
requirement: !ruby/object:Gem::Requirement
|
94
100
|
requirements:
|
95
101
|
- - "~>"
|
96
102
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
98
|
-
type: :development
|
99
|
-
prerelease: false
|
100
|
-
version_requirements: !ruby/object:Gem::Requirement
|
101
|
-
requirements:
|
102
|
-
- - "~>"
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version: '12.3'
|
105
|
-
- !ruby/object:Gem::Dependency
|
106
|
-
name: rr
|
107
|
-
requirement: !ruby/object:Gem::Requirement
|
108
|
-
requirements:
|
109
|
-
- - "~>"
|
110
|
-
- !ruby/object:Gem::Version
|
111
|
-
version: '1.1'
|
103
|
+
version: '13.1'
|
112
104
|
type: :development
|
113
105
|
prerelease: false
|
114
106
|
version_requirements: !ruby/object:Gem::Requirement
|
115
107
|
requirements:
|
116
108
|
- - "~>"
|
117
109
|
- !ruby/object:Gem::Version
|
118
|
-
version: '
|
110
|
+
version: '13.1'
|
119
111
|
- !ruby/object:Gem::Dependency
|
120
112
|
name: pry
|
121
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,20 +138,6 @@ dependencies:
|
|
146
138
|
version: '0'
|
147
139
|
- !ruby/object:Gem::Dependency
|
148
140
|
name: rubocop
|
149
|
-
requirement: !ruby/object:Gem::Requirement
|
150
|
-
requirements:
|
151
|
-
- - "<"
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
version: 1.13.0
|
154
|
-
type: :development
|
155
|
-
prerelease: false
|
156
|
-
version_requirements: !ruby/object:Gem::Requirement
|
157
|
-
requirements:
|
158
|
-
- - "<"
|
159
|
-
- !ruby/object:Gem::Version
|
160
|
-
version: 1.13.0
|
161
|
-
- !ruby/object:Gem::Dependency
|
162
|
-
name: rubocop-performance
|
163
141
|
requirement: !ruby/object:Gem::Requirement
|
164
142
|
requirements:
|
165
143
|
- - ">="
|
@@ -173,21 +151,7 @@ dependencies:
|
|
173
151
|
- !ruby/object:Gem::Version
|
174
152
|
version: '0'
|
175
153
|
- !ruby/object:Gem::Dependency
|
176
|
-
name: rubocop-
|
177
|
-
requirement: !ruby/object:Gem::Requirement
|
178
|
-
requirements:
|
179
|
-
- - ">="
|
180
|
-
- !ruby/object:Gem::Version
|
181
|
-
version: '0'
|
182
|
-
type: :development
|
183
|
-
prerelease: false
|
184
|
-
version_requirements: !ruby/object:Gem::Requirement
|
185
|
-
requirements:
|
186
|
-
- - ">="
|
187
|
-
- !ruby/object:Gem::Version
|
188
|
-
version: '0'
|
189
|
-
- !ruby/object:Gem::Dependency
|
190
|
-
name: rubocop-rake
|
154
|
+
name: rubocop-performance
|
191
155
|
requirement: !ruby/object:Gem::Requirement
|
192
156
|
requirements:
|
193
157
|
- - ">="
|
@@ -305,7 +269,11 @@ files:
|
|
305
269
|
homepage: https://github.com/interagent/committee
|
306
270
|
licenses:
|
307
271
|
- MIT
|
308
|
-
metadata:
|
272
|
+
metadata:
|
273
|
+
bug_tracker_uri: https://github.com/interagent/committee/issues
|
274
|
+
changelog_uri: https://github.com/interagent/committee/blob/master/CHANGELOG.md
|
275
|
+
rubygems_mfa_required: 'true'
|
276
|
+
source_code_uri: https://github.com/interagent/committee
|
309
277
|
post_install_message:
|
310
278
|
rdoc_options: []
|
311
279
|
require_paths:
|
@@ -314,14 +282,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
314
282
|
requirements:
|
315
283
|
- - ">="
|
316
284
|
- !ruby/object:Gem::Version
|
317
|
-
version: 2.
|
285
|
+
version: 2.7.0
|
318
286
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
319
287
|
requirements:
|
320
288
|
- - ">="
|
321
289
|
- !ruby/object:Gem::Version
|
322
290
|
version: '0'
|
323
291
|
requirements: []
|
324
|
-
rubygems_version: 3.
|
292
|
+
rubygems_version: 3.5.18
|
325
293
|
signing_key:
|
326
294
|
specification_version: 4
|
327
295
|
summary: A collection of Rack middleware to support JSON Schema.
|