committee 3.1.1 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/committee/drivers.rb +5 -5
- data/lib/committee/middleware/base.rb +3 -1
- data/lib/committee/middleware/request_validation.rb +17 -19
- data/lib/committee/middleware/response_validation.rb +15 -12
- data/lib/committee/schema_validator/hyper_schema.rb +8 -1
- data/lib/committee/schema_validator/open_api_3.rb +8 -1
- data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +7 -1
- data/lib/committee/schema_validator/open_api_3/request_validator.rb +11 -1
- data/lib/committee/schema_validator/open_api_3/response_validator.rb +0 -1
- data/lib/committee/schema_validator/option.rb +8 -1
- data/test/bin/committee_stub_test.rb +5 -1
- data/test/middleware/base_test.rb +9 -3
- data/test/middleware/request_validation_open_api_3_test.rb +63 -20
- data/test/middleware/request_validation_test.rb +32 -0
- data/test/middleware/response_validation_open_api_3_test.rb +90 -20
- data/test/middleware/response_validation_test.rb +28 -0
- data/test/middleware/stub_test.rb +4 -0
- data/test/request_unpacker_test.rb +12 -3
- data/test/schema_validator/hyper_schema/router_test.rb +4 -0
- data/test/schema_validator/open_api_3/operation_wrapper_test.rb +28 -10
- data/test/schema_validator/open_api_3/request_validator_test.rb +29 -3
- data/test/schema_validator/open_api_3/response_validator_test.rb +8 -3
- data/test/test/methods_new_version_test.rb +3 -0
- data/test/test/methods_test.rb +12 -8
- data/test/test_helper.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bef22bebc103d1bee78ba294078cd56e34e37da3e92b5cb89aba683a2361c74
|
4
|
+
data.tar.gz: 76f012e3f28bd5275af941a372563f00b3bf68e1c0332d0e78affc18cbac9f2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da601220eca1ea05bb829a61a65bf6928262be27c73647de756f44b07329752efe6818be1a79b95bb51ad2e00025d08ff5fbb5410acfdc670d43f6816c6614f1
|
7
|
+
data.tar.gz: c0fad32bef922020708c194065d0de90fccc9d33d00354b4c8a4f3208e18b4720030e01810e798107894e6f503e8145fef11fd12afa1ba1f0b5b017f3b58eeda
|
data/lib/committee/drivers.rb
CHANGED
@@ -21,14 +21,14 @@ module Committee
|
|
21
21
|
# @param [String] schema_path
|
22
22
|
# @return [Committee::Driver]
|
23
23
|
def self.load_from_json(schema_path)
|
24
|
-
load_from_data(JSON.parse(File.read(schema_path)))
|
24
|
+
load_from_data(JSON.parse(File.read(schema_path)), schema_path)
|
25
25
|
end
|
26
26
|
|
27
27
|
# load and build drive from YAML file
|
28
28
|
# @param [String] schema_path
|
29
29
|
# @return [Committee::Driver]
|
30
30
|
def self.load_from_yaml(schema_path)
|
31
|
-
load_from_data(YAML.load_file(schema_path))
|
31
|
+
load_from_data(YAML.load_file(schema_path), schema_path)
|
32
32
|
end
|
33
33
|
|
34
34
|
# load and build drive from file
|
@@ -48,10 +48,10 @@ module Committee
|
|
48
48
|
# load and build drive from Hash object
|
49
49
|
# @param [Hash] hash
|
50
50
|
# @return [Committee::Driver]
|
51
|
-
def self.load_from_data(hash)
|
51
|
+
def self.load_from_data(hash, schema_path = nil)
|
52
52
|
if hash['openapi']&.start_with?('3.0.')
|
53
|
-
|
54
|
-
return Committee::Drivers::OpenAPI3::Driver.new.parse(
|
53
|
+
openapi = OpenAPIParser.parse_with_filepath(hash, schema_path)
|
54
|
+
return Committee::Drivers::OpenAPI3::Driver.new.parse(openapi)
|
55
55
|
end
|
56
56
|
|
57
57
|
driver = if hash['swagger'] == '2.0'
|
@@ -8,17 +8,19 @@ module Committee
|
|
8
8
|
|
9
9
|
@error_class = options.fetch(:error_class, Committee::ValidationError)
|
10
10
|
@error_handler = options[:error_handler]
|
11
|
+
@ignore_error = options.fetch(:ignore_error, false)
|
11
12
|
|
12
13
|
@raise = options[:raise]
|
13
14
|
@schema = self.class.get_schema(options)
|
14
15
|
|
15
16
|
@router = @schema.build_router(options)
|
17
|
+
@accept_request_filter = options[:accept_request_filter] || -> (_) { true }
|
16
18
|
end
|
17
19
|
|
18
20
|
def call(env)
|
19
21
|
request = Rack::Request.new(env)
|
20
22
|
|
21
|
-
if @router.includes_request?(request)
|
23
|
+
if @router.includes_request?(request) && @accept_request_filter.call(request)
|
22
24
|
handle(request)
|
23
25
|
else
|
24
26
|
@app.call(request.env)
|
@@ -13,27 +13,25 @@ module Committee
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def handle(request)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
begin
|
17
|
+
schema_validator = build_schema_validator(request)
|
18
|
+
schema_validator.request_validate(request)
|
19
|
+
|
20
|
+
raise Committee::NotFound, "That request method and path combination isn't defined." if !schema_validator.link_exist? && @strict
|
21
|
+
rescue Committee::BadRequest, Committee::InvalidRequest
|
22
|
+
handle_exception($!, request.env)
|
23
|
+
raise if @raise
|
24
|
+
return @error_class.new(400, :bad_request, $!.message).render unless @ignore_error
|
25
|
+
rescue Committee::NotFound => e
|
26
|
+
raise if @raise
|
27
|
+
return @error_class.new(404, :not_found, e.message).render unless @ignore_error
|
28
|
+
rescue JSON::ParserError
|
29
|
+
handle_exception($!, request.env)
|
30
|
+
raise Committee::InvalidRequest if @raise
|
31
|
+
return @error_class.new(400, :bad_request, "Request body wasn't valid JSON.").render unless @ignore_error
|
32
|
+
end
|
20
33
|
|
21
34
|
@app.call(request.env)
|
22
|
-
rescue Committee::BadRequest, Committee::InvalidRequest
|
23
|
-
handle_exception($!, request.env)
|
24
|
-
raise if @raise
|
25
|
-
@error_class.new(400, :bad_request, $!.message).render
|
26
|
-
rescue Committee::NotFound => e
|
27
|
-
raise if @raise
|
28
|
-
@error_class.new(
|
29
|
-
404,
|
30
|
-
:not_found,
|
31
|
-
e.message
|
32
|
-
).render
|
33
|
-
rescue JSON::ParserError
|
34
|
-
handle_exception($!, request.env)
|
35
|
-
raise Committee::InvalidRequest if @raise
|
36
|
-
@error_class.new(400, :bad_request, "Request body wasn't valid JSON.").render
|
37
35
|
end
|
38
36
|
|
39
37
|
private
|
@@ -11,22 +11,25 @@ module Committee
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def handle(request)
|
14
|
-
|
14
|
+
begin
|
15
|
+
status, headers, response = @app.call(request.env)
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
v = build_schema_validator(request)
|
18
|
+
v.response_validate(status, headers, response) if v.link_exist? && self.class.validate?(status, validate_success_only)
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
rescue Committee::InvalidResponse
|
21
|
+
handle_exception($!, request.env)
|
22
|
+
|
23
|
+
raise if @raise
|
24
|
+
return @error_class.new(500, :invalid_response, $!.message).render unless @ignore_error
|
25
|
+
rescue JSON::ParserError
|
26
|
+
handle_exception($!, request.env)
|
22
27
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
handle_exception($!, request.env)
|
28
|
+
raise Committee::InvalidResponse if @raise
|
29
|
+
return @error_class.new(500, :invalid_response, "Response wasn't valid JSON.").render unless @ignore_error
|
30
|
+
end
|
27
31
|
|
28
|
-
|
29
|
-
@error_class.new(500, :invalid_response, "Response wasn't valid JSON.").render
|
32
|
+
[status, headers, response]
|
30
33
|
end
|
31
34
|
|
32
35
|
class << self
|
@@ -35,7 +35,14 @@ module Committee
|
|
35
35
|
response.each do |chunk|
|
36
36
|
full_body << chunk
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
|
+
data = {}
|
40
|
+
unless full_body.empty?
|
41
|
+
parse_to_json = !validator_option.parse_response_by_content_type ||
|
42
|
+
headers.fetch('Content-Type', nil)&.start_with?('application/json')
|
43
|
+
data = JSON.parse(full_body) if parse_to_json
|
44
|
+
end
|
45
|
+
|
39
46
|
Committee::SchemaValidator::HyperSchema::ResponseValidator.new(link, validate_success_only: validator_option.validate_success_only).call(status, headers, data)
|
40
47
|
end
|
41
48
|
|
@@ -30,7 +30,14 @@ module Committee
|
|
30
30
|
response.each do |chunk|
|
31
31
|
full_body << chunk
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
|
+
parse_to_json = !validator_option.parse_response_by_content_type ||
|
35
|
+
headers.fetch('Content-Type', nil)&.start_with?('application/json')
|
36
|
+
data = if parse_to_json
|
37
|
+
full_body.empty? ? {} : JSON.parse(full_body)
|
38
|
+
else
|
39
|
+
full_body
|
40
|
+
end
|
34
41
|
|
35
42
|
strict = test_method
|
36
43
|
Committee::SchemaValidator::OpenAPI3::ResponseValidator.
|
@@ -64,6 +64,10 @@ module Committee
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
def request_content_types
|
68
|
+
request_operation.operation_object&.request_body&.content&.keys || []
|
69
|
+
end
|
70
|
+
|
67
71
|
private
|
68
72
|
|
69
73
|
attr_reader :request_operation
|
@@ -112,7 +116,9 @@ module Committee
|
|
112
116
|
content_type = headers['Content-Type'].to_s.split(";").first.to_s
|
113
117
|
|
114
118
|
# bad performance because when we coerce value, same check
|
115
|
-
|
119
|
+
schema_validator_options = build_openapi_parser_post_option(validator_option)
|
120
|
+
request_operation.validate_request_parameter(params, headers, schema_validator_options)
|
121
|
+
request_operation.validate_request_body(content_type, params, schema_validator_options)
|
116
122
|
rescue => e
|
117
123
|
raise Committee::InvalidRequest.new(e.message)
|
118
124
|
end
|
@@ -25,7 +25,17 @@ module Committee
|
|
25
25
|
return true unless request.post? || request.put? || request.patch?
|
26
26
|
return true if @operation_object.valid_request_content_type?(content_type)
|
27
27
|
|
28
|
-
|
28
|
+
message = if valid_content_types.size > 1
|
29
|
+
types = valid_content_types.map {|x| %{"#{x}"} }.join(', ')
|
30
|
+
%{"Content-Type" request header must be set to any of the following: [#{types}].}
|
31
|
+
else
|
32
|
+
%{"Content-Type" request header must be set to "#{valid_content_types.first}".}
|
33
|
+
end
|
34
|
+
raise Committee::InvalidRequest, message
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid_content_types
|
38
|
+
@operation_object&.request_content_types
|
29
39
|
end
|
30
40
|
end
|
31
41
|
end
|
@@ -17,7 +17,6 @@ module Committee
|
|
17
17
|
def call(status, headers, response_data, strict)
|
18
18
|
return unless Committee::Middleware::ResponseValidation.validate?(status, validate_success_only)
|
19
19
|
|
20
|
-
#content_type = headers['Content-Type'].to_s.split(";").first.to_s
|
21
20
|
operation_wrapper.validate_response_params(status, headers, response_data, strict, check_header)
|
22
21
|
end
|
23
22
|
|
@@ -15,7 +15,8 @@ module Committee
|
|
15
15
|
:coerce_query_params,
|
16
16
|
:coerce_recursive,
|
17
17
|
:optimistic_json,
|
18
|
-
:validate_success_only
|
18
|
+
:validate_success_only,
|
19
|
+
:parse_response_by_content_type
|
19
20
|
|
20
21
|
# Non-boolean options:
|
21
22
|
attr_reader :headers_key,
|
@@ -35,6 +36,12 @@ module Committee
|
|
35
36
|
@check_header = options.fetch(:check_header, true)
|
36
37
|
@coerce_recursive = options.fetch(:coerce_recursive, true)
|
37
38
|
@optimistic_json = options.fetch(:optimistic_json, false)
|
39
|
+
@parse_response_by_content_type = if options[:parse_response_by_content_type].nil?
|
40
|
+
Committee.warn_deprecated('Committee: please set parse_response_by_content_type = false because we\'ll change default value in next major version.')
|
41
|
+
false
|
42
|
+
else
|
43
|
+
options.fetch(:parse_response_by_content_type)
|
44
|
+
end
|
38
45
|
|
39
46
|
# Boolean options and have a different value by default
|
40
47
|
@allow_get_body = options.fetch(:allow_get_body, schema.driver.default_allow_get_body)
|
@@ -43,7 +43,11 @@ describe Committee::Bin::CommitteeStub, "app" do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def app
|
46
|
-
|
46
|
+
options = {}
|
47
|
+
# TODO: delete when 5.0.0 released because default value changed
|
48
|
+
options[:parse_response_by_content_type] = false
|
49
|
+
|
50
|
+
@bin.get_app(hyper_schema, options)
|
47
51
|
end
|
48
52
|
|
49
53
|
it "defaults to a 404" do
|
@@ -103,17 +103,20 @@ describe Committee::Middleware::Base do
|
|
103
103
|
|
104
104
|
describe 'initialize option' do
|
105
105
|
it "schema_path option with hyper-schema" do
|
106
|
-
|
106
|
+
# TODO: delete when 5.0.0 released because default value changed
|
107
|
+
b = Committee::Middleware::Base.new(nil, schema_path: hyper_schema_schema_path, parse_response_by_content_type: false)
|
107
108
|
assert_kind_of Committee::Drivers::HyperSchema::Schema, b.instance_variable_get(:@schema)
|
108
109
|
end
|
109
110
|
|
110
111
|
it "schema_path option with OpenAPI2" do
|
111
|
-
|
112
|
+
# TODO: delete when 5.0.0 released because default value changed
|
113
|
+
b = Committee::Middleware::Base.new(nil, schema_path: open_api_2_schema_path, parse_response_by_content_type: false)
|
112
114
|
assert_kind_of Committee::Drivers::OpenAPI2::Schema, b.instance_variable_get(:@schema)
|
113
115
|
end
|
114
116
|
|
115
117
|
it "schema_path option with OpenAPI3" do
|
116
|
-
|
118
|
+
# TODO: delete when 5.0.0 released because default value changed
|
119
|
+
b = Committee::Middleware::Base.new(nil, schema_path: open_api_3_schema_path, parse_response_by_content_type: false)
|
117
120
|
assert_kind_of Committee::Drivers::OpenAPI3::Schema, b.instance_variable_get(:@schema)
|
118
121
|
end
|
119
122
|
end
|
@@ -121,6 +124,9 @@ describe Committee::Middleware::Base do
|
|
121
124
|
private
|
122
125
|
|
123
126
|
def new_rack_app(options = {})
|
127
|
+
# TODO: delete when 5.0.0 released because default value changed
|
128
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
129
|
+
|
124
130
|
Rack::Builder.new {
|
125
131
|
use Committee::Middleware::RequestValidation, options
|
126
132
|
run lambda { |_|
|
@@ -249,8 +249,7 @@ describe Committee::Middleware::RequestValidation do
|
|
249
249
|
}
|
250
250
|
post "/characters", JSON.generate(params)
|
251
251
|
assert_equal 400, last_response.status
|
252
|
-
|
253
|
-
assert_match(/1 class is #{1.class}/i, last_response.body)
|
252
|
+
assert_match(/expected string, but received Integer:/i, last_response.body)
|
254
253
|
end
|
255
254
|
|
256
255
|
it "rescues JSON errors" do
|
@@ -279,7 +278,7 @@ describe Committee::Middleware::RequestValidation do
|
|
279
278
|
header "Content-Type", "application/json"
|
280
279
|
post "/v1/characters", JSON.generate(params)
|
281
280
|
assert_equal 400, last_response.status
|
282
|
-
assert_match(/
|
281
|
+
assert_match(/expected string, but received Integer: /i, last_response.body)
|
283
282
|
end
|
284
283
|
|
285
284
|
it "ignores paths outside the prefix" do
|
@@ -321,7 +320,7 @@ describe Committee::Middleware::RequestValidation do
|
|
321
320
|
get "/validate", nil
|
322
321
|
end
|
323
322
|
|
324
|
-
assert_match(/required parameters query_string
|
323
|
+
assert_match(/missing required parameters: query_string/i, e.message)
|
325
324
|
end
|
326
325
|
|
327
326
|
it "raises error when required path parameter is invalid" do
|
@@ -332,7 +331,7 @@ describe Committee::Middleware::RequestValidation do
|
|
332
331
|
get "/coerce_path_params/#{not_an_integer}", nil
|
333
332
|
end
|
334
333
|
|
335
|
-
assert_match(/
|
334
|
+
assert_match(/expected integer, but received String: abc/i, e.message)
|
336
335
|
end
|
337
336
|
|
338
337
|
it "optionally raises an error" do
|
@@ -356,7 +355,7 @@ describe Committee::Middleware::RequestValidation do
|
|
356
355
|
get "/string_params_coercer", {"integer_1" => "1"}
|
357
356
|
|
358
357
|
assert_equal 400, last_response.status
|
359
|
-
assert_match(/
|
358
|
+
assert_match(/expected integer, but received String:/i, last_response.body)
|
360
359
|
end
|
361
360
|
|
362
361
|
it "passes through a valid request for OpenAPI3" do
|
@@ -375,7 +374,14 @@ describe Committee::Middleware::RequestValidation do
|
|
375
374
|
get "/characters?limit=foo"
|
376
375
|
|
377
376
|
assert_equal 400, last_response.status
|
378
|
-
assert_match(/foo
|
377
|
+
assert_match(/expected integer, but received String: foo/i, last_response.body)
|
378
|
+
end
|
379
|
+
|
380
|
+
it "ignores errors when ignore_error: true" do
|
381
|
+
@app = new_rack_app(schema: open_api_3_schema, ignore_error: true)
|
382
|
+
get "/characters?limit=foo"
|
383
|
+
|
384
|
+
assert_equal 200, last_response.status
|
379
385
|
end
|
380
386
|
|
381
387
|
it "coerce string to integer" do
|
@@ -399,21 +405,55 @@ describe Committee::Middleware::RequestValidation do
|
|
399
405
|
end
|
400
406
|
|
401
407
|
describe 'check header' do
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
408
|
+
[
|
409
|
+
{ check_header: true, description: 'valid value', value: 1, expected: { status: 200 } },
|
410
|
+
{ check_header: true, description: 'missing value', value: nil, expected: { status: 400, error: 'missing required parameters: integer' } },
|
411
|
+
{ check_header: true, description: 'invalid value', value: 'x', expected: { status: 400, error: 'expected integer, but received String: x' } },
|
412
|
+
|
413
|
+
{ check_header: false, description: 'valid value', value: 1, expected: { status: 200 } },
|
414
|
+
{ check_header: false, description: 'missing value', value: nil, expected: { status: 200 } },
|
415
|
+
{ check_header: false, description: 'invalid value', value: 'x', expected: { status: 200 } },
|
416
|
+
].each do |h|
|
417
|
+
check_header = h[:check_header]
|
418
|
+
description = h[:description]
|
419
|
+
value = h[:value]
|
420
|
+
expected = h[:expected]
|
421
|
+
describe "when #{check_header}" do
|
422
|
+
%w(get post put patch delete).each do |method|
|
423
|
+
describe method do
|
424
|
+
describe description do
|
425
|
+
it (expected[:error].nil? ? 'should pass' : 'should fail') do
|
426
|
+
@app = new_rack_app(schema: open_api_3_schema, check_header: check_header)
|
427
|
+
|
428
|
+
header 'integer', value
|
429
|
+
send(method, "/header")
|
430
|
+
|
431
|
+
assert_equal expected[:status], last_response.status
|
432
|
+
assert_match(expected[:error], last_response.body) if expected[:error]
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
409
438
|
end
|
439
|
+
end
|
410
440
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
441
|
+
describe ':accept_request_filter' do
|
442
|
+
[
|
443
|
+
{ description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 400 } },
|
444
|
+
{ description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/c') }, expected: { status: 400 } },
|
445
|
+
{ description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
|
446
|
+
].each do |h|
|
447
|
+
description = h[:description]
|
448
|
+
accept_request_filter = h[:accept_request_filter]
|
449
|
+
expected = h[:expected]
|
450
|
+
it description do
|
451
|
+
@app = new_rack_app(prefix: '/v1', schema: open_api_3_schema, accept_request_filter: accept_request_filter)
|
452
|
+
|
453
|
+
post 'v1/characters', JSON.generate(string_post_1: 1)
|
454
|
+
|
455
|
+
assert_equal expected[:status], last_response.status
|
456
|
+
end
|
417
457
|
end
|
418
458
|
end
|
419
459
|
|
@@ -426,6 +466,9 @@ describe Committee::Middleware::RequestValidation do
|
|
426
466
|
end
|
427
467
|
|
428
468
|
def new_rack_app_with_lambda(check_lambda, options = {})
|
469
|
+
# TODO: delete when 5.0.0 released because default value changed
|
470
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
471
|
+
|
429
472
|
Rack::Builder.new {
|
430
473
|
use Committee::Middleware::RequestValidation, options
|
431
474
|
run check_lambda
|
@@ -296,6 +296,16 @@ describe Committee::Middleware::RequestValidation do
|
|
296
296
|
assert_match(/invalid request/i, last_response.body)
|
297
297
|
end
|
298
298
|
|
299
|
+
it "ignores errors when ignore_error: true" do
|
300
|
+
@app = new_rack_app(schema: hyper_schema, ignore_error: true)
|
301
|
+
header "Content-Type", "application/json"
|
302
|
+
params = {
|
303
|
+
"name" => 1
|
304
|
+
}
|
305
|
+
post "/apps", JSON.generate(params)
|
306
|
+
assert_equal 200, last_response.status
|
307
|
+
end
|
308
|
+
|
299
309
|
it "calls error_handler (has a arg) when request is invalid" do
|
300
310
|
called_err = nil
|
301
311
|
pr = ->(e) { called_err = e }
|
@@ -480,6 +490,25 @@ describe Committee::Middleware::RequestValidation do
|
|
480
490
|
assert_equal 200, last_response.status
|
481
491
|
end
|
482
492
|
|
493
|
+
describe ':accept_request_filter' do
|
494
|
+
[
|
495
|
+
{ description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 400 } },
|
496
|
+
{ description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/a') }, expected: { status: 400 } },
|
497
|
+
{ description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
|
498
|
+
].each do |h|
|
499
|
+
description = h[:description]
|
500
|
+
accept_request_filter = h[:accept_request_filter]
|
501
|
+
expected = h[:expected]
|
502
|
+
it description do
|
503
|
+
@app = new_rack_app(prefix: '/v1', schema: hyper_schema, accept_request_filter: accept_request_filter)
|
504
|
+
|
505
|
+
post '/v1/apps', '{x:y}'
|
506
|
+
|
507
|
+
assert_equal expected[:status], last_response.status
|
508
|
+
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
483
512
|
private
|
484
513
|
|
485
514
|
def new_rack_app(options = {})
|
@@ -490,6 +519,9 @@ describe Committee::Middleware::RequestValidation do
|
|
490
519
|
|
491
520
|
|
492
521
|
def new_rack_app_with_lambda(check_lambda, options = {})
|
522
|
+
# TODO: delete when 5.0.0 released because default value changed
|
523
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
524
|
+
|
493
525
|
Rack::Builder.new {
|
494
526
|
use Committee::Middleware::RequestValidation, options
|
495
527
|
run check_lambda
|
@@ -26,6 +26,22 @@ describe Committee::Middleware::ResponseValidation do
|
|
26
26
|
assert_equal "{\"id\":\"invalid_response\",\"message\":\"Response wasn't valid JSON.\"}", last_response.body
|
27
27
|
end
|
28
28
|
|
29
|
+
it "passes through a invalid json with ignore_error option" do
|
30
|
+
@app = new_response_rack("not_json", {}, schema: open_api_3_schema, ignore_error: true)
|
31
|
+
|
32
|
+
get "/characters"
|
33
|
+
|
34
|
+
assert_equal 200, last_response.status
|
35
|
+
end
|
36
|
+
|
37
|
+
it "passes through a invalid json with parse_response_by_content_type option" do
|
38
|
+
@app = new_response_rack("csv response", { "Content-Type" => "test/csv"}, schema: open_api_3_schema, parse_response_by_content_type: true)
|
39
|
+
|
40
|
+
get "/csv"
|
41
|
+
|
42
|
+
assert_equal 200, last_response.status
|
43
|
+
end
|
44
|
+
|
29
45
|
it "passes through not definition" do
|
30
46
|
@app = new_response_rack(JSON.generate(CHARACTERS_RESPONSE), {}, schema: open_api_3_schema)
|
31
47
|
get "/no_data"
|
@@ -39,7 +55,7 @@ describe Committee::Middleware::ResponseValidation do
|
|
39
55
|
get "/characters"
|
40
56
|
}
|
41
57
|
|
42
|
-
assert_match(/
|
58
|
+
assert_match(/expected object, but received Array: /i, e.message)
|
43
59
|
end
|
44
60
|
|
45
61
|
it "passes through a 204 (no content) response" do
|
@@ -91,29 +107,59 @@ describe Committee::Middleware::ResponseValidation do
|
|
91
107
|
assert_match(/valid JSON/i, last_response.body)
|
92
108
|
end
|
93
109
|
|
94
|
-
describe
|
95
|
-
it
|
96
|
-
@app = new_response_rack(
|
97
|
-
|
98
|
-
get "/header"
|
99
|
-
|
110
|
+
describe "remote schema $ref" do
|
111
|
+
it "passes through a valid response" do
|
112
|
+
@app = new_response_rack(JSON.generate({ "sample" => "value" }), {}, schema: open_api_3_schema)
|
113
|
+
get "/ref-sample"
|
100
114
|
assert_equal 200, last_response.status
|
101
115
|
end
|
102
116
|
|
103
|
-
it
|
104
|
-
@app = new_response_rack({}
|
105
|
-
|
106
|
-
|
107
|
-
get "/header"
|
108
|
-
end
|
117
|
+
it "detects a invalid response" do
|
118
|
+
@app = new_response_rack("{}", {}, schema: open_api_3_schema)
|
119
|
+
get "/ref-sample"
|
120
|
+
assert_equal 500, last_response.status
|
109
121
|
end
|
122
|
+
end
|
110
123
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
124
|
+
describe 'check header' do
|
125
|
+
[
|
126
|
+
{ check_header: true, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
|
127
|
+
{ check_header: true, description: 'missing value', header: { 'integer' => nil }, expected: { error: 'headers/integer/schema does not allow null values' } },
|
128
|
+
{ check_header: true, description: 'invalid value', header: { 'integer' => 'x' }, expected: { error: 'headers/integer/schema expected integer, but received String: x' } },
|
129
|
+
|
130
|
+
{ check_header: false, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
|
131
|
+
{ check_header: false, description: 'missing value', header: { 'integer' => nil }, expected: { status: 200 } },
|
132
|
+
{ check_header: false, description: 'invalid value', header: { 'integer' => 'x' }, expected: { status: 200 } },
|
133
|
+
].each do |h|
|
134
|
+
check_header = h[:check_header]
|
135
|
+
description = h[:description]
|
136
|
+
header = h[:header]
|
137
|
+
expected = h[:expected]
|
138
|
+
describe "when #{check_header}" do
|
139
|
+
%w(get post put patch delete).each do |method|
|
140
|
+
describe method do
|
141
|
+
describe description do
|
142
|
+
if expected[:error].nil?
|
143
|
+
it 'should pass' do
|
144
|
+
@app = new_response_rack({}.to_json, header, schema: open_api_3_schema, raise: true, check_header: check_header)
|
145
|
+
|
146
|
+
send(method, "/header")
|
147
|
+
assert_equal expected[:status], last_response.status
|
148
|
+
end
|
149
|
+
else
|
150
|
+
it 'should fail' do
|
151
|
+
@app = new_response_rack({}.to_json, header, schema: open_api_3_schema, raise: true, check_header: check_header)
|
152
|
+
|
153
|
+
error = assert_raises(Committee::InvalidResponse) do
|
154
|
+
get "/header"
|
155
|
+
end
|
156
|
+
assert_match(expected[:error], error.message)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
117
163
|
end
|
118
164
|
end
|
119
165
|
|
@@ -130,7 +176,8 @@ describe Committee::Middleware::ResponseValidation do
|
|
130
176
|
e = assert_raises(Committee::InvalidResponse) do
|
131
177
|
get "/characters"
|
132
178
|
end
|
133
|
-
|
179
|
+
|
180
|
+
assert_match(/but received String: 1/i, e.message)
|
134
181
|
end
|
135
182
|
|
136
183
|
it "detects an invalid response status code with validate_success_only=true" do
|
@@ -148,9 +195,32 @@ describe Committee::Middleware::ResponseValidation do
|
|
148
195
|
end
|
149
196
|
end
|
150
197
|
|
198
|
+
describe ':accept_request_filter' do
|
199
|
+
[
|
200
|
+
{ description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 500 } },
|
201
|
+
{ description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/c') }, expected: { status: 500 } },
|
202
|
+
{ description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
|
203
|
+
].each do |h|
|
204
|
+
description = h[:description]
|
205
|
+
accept_request_filter = h[:accept_request_filter]
|
206
|
+
expected = h[:expected]
|
207
|
+
|
208
|
+
it description do
|
209
|
+
@app = new_response_rack('not_json', {}, schema: open_api_3_schema, prefix: '/v1', accept_request_filter: accept_request_filter)
|
210
|
+
|
211
|
+
get 'v1/characters'
|
212
|
+
|
213
|
+
assert_equal expected[:status], last_response.status
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
151
218
|
private
|
152
219
|
|
153
220
|
def new_response_rack(response, headers = {}, options = {}, rack_options = {})
|
221
|
+
# TODO: delete when 5.0.0 released because default value changed
|
222
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
223
|
+
|
154
224
|
status = rack_options[:status] || 200
|
155
225
|
headers = {
|
156
226
|
"Content-Type" => "application/json"
|
@@ -38,6 +38,12 @@ describe Committee::Middleware::ResponseValidation do
|
|
38
38
|
assert_match(/{} is not an array/i, last_response.body)
|
39
39
|
end
|
40
40
|
|
41
|
+
it "detects a response invalid due to schema with ignore_error option" do
|
42
|
+
@app = new_rack_app("{}", {}, schema: hyper_schema, ignore_error: true)
|
43
|
+
get "/apps"
|
44
|
+
assert_equal 200, last_response.status
|
45
|
+
end
|
46
|
+
|
41
47
|
it "detects a response invalid due to not being JSON" do
|
42
48
|
@app = new_rack_app("{_}", {}, schema: hyper_schema)
|
43
49
|
get "/apps"
|
@@ -156,9 +162,31 @@ describe Committee::Middleware::ResponseValidation do
|
|
156
162
|
assert_match(/valid JSON/i, last_response.body)
|
157
163
|
end
|
158
164
|
|
165
|
+
describe ':accept_request_filter' do
|
166
|
+
[
|
167
|
+
{ description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 500 } },
|
168
|
+
{ description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/a') }, expected: { status: 500 } },
|
169
|
+
{ description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
|
170
|
+
].each do |h|
|
171
|
+
description = h[:description]
|
172
|
+
accept_request_filter = h[:accept_request_filter]
|
173
|
+
expected = h[:expected]
|
174
|
+
it description do
|
175
|
+
@app = new_rack_app('not_json', {}, schema: hyper_schema, prefix: '/v1', accept_request_filter: accept_request_filter)
|
176
|
+
|
177
|
+
get '/v1/apps'
|
178
|
+
|
179
|
+
assert_equal expected[:status], last_response.status
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
159
184
|
private
|
160
185
|
|
161
186
|
def new_rack_app(response, headers = {}, options = {})
|
187
|
+
# TODO: delete when 5.0.0 released because default value changed
|
188
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
189
|
+
|
162
190
|
headers = {
|
163
191
|
"Content-Type" => "application/json"
|
164
192
|
}.merge(headers)
|
@@ -112,6 +112,10 @@ describe Committee::Middleware::Stub do
|
|
112
112
|
def new_rack_app(options = {})
|
113
113
|
response = options.delete(:response)
|
114
114
|
suppress = options.delete(:suppress)
|
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
|
+
|
115
119
|
Rack::Builder.new {
|
116
120
|
use Committee::Middleware::Stub, options
|
117
121
|
run lambda { |env|
|
@@ -100,7 +100,10 @@ describe Committee::RequestUnpacker do
|
|
100
100
|
}
|
101
101
|
request = Rack::Request.new(env)
|
102
102
|
|
103
|
-
|
103
|
+
options = {}
|
104
|
+
# TODO: delete when 5.0.0 released because default value changed
|
105
|
+
options[:parse_response_by_content_type] = false
|
106
|
+
router = hyper_schema.build_router(options)
|
104
107
|
validator = router.build_schema_validator(request)
|
105
108
|
|
106
109
|
schema = JsonSchema::Schema.new
|
@@ -133,7 +136,10 @@ describe Committee::RequestUnpacker do
|
|
133
136
|
}
|
134
137
|
request = Rack::Request.new(env)
|
135
138
|
|
136
|
-
|
139
|
+
options = {}
|
140
|
+
# TODO: delete when 5.0.0 released because default value changed
|
141
|
+
options[:parse_response_by_content_type] = false
|
142
|
+
router = open_api_3_schema.build_router(options)
|
137
143
|
validator = router.build_schema_validator(request)
|
138
144
|
|
139
145
|
params, _ = Committee::RequestUnpacker.new(
|
@@ -158,7 +164,10 @@ describe Committee::RequestUnpacker do
|
|
158
164
|
}
|
159
165
|
request = Rack::Request.new(env)
|
160
166
|
|
161
|
-
|
167
|
+
options = {}
|
168
|
+
# TODO: delete when 5.0.0 released because default value changed
|
169
|
+
options[:parse_response_by_content_type] = false
|
170
|
+
router = open_api_3_schema.build_router(options)
|
162
171
|
validator = router.build_schema_validator(request)
|
163
172
|
|
164
173
|
params, _ = Committee::RequestUnpacker.new(
|
@@ -69,6 +69,8 @@ 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
|
72
74
|
schema = Committee::Drivers::HyperSchema::Driver.new.parse(hyper_schema_data)
|
73
75
|
validator_option = Committee::SchemaValidator::Option.new(options, schema, :hyper_schema)
|
74
76
|
|
@@ -76,6 +78,8 @@ describe Committee::SchemaValidator::HyperSchema::Router do
|
|
76
78
|
end
|
77
79
|
|
78
80
|
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
|
79
83
|
schema = Committee::Drivers::OpenAPI2::Driver.new.parse(open_api_2_data)
|
80
84
|
validator_option = Committee::SchemaValidator::Option.new(options, schema, :hyper_schema)
|
81
85
|
|
@@ -9,7 +9,12 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
9
9
|
before do
|
10
10
|
@path = '/validate'
|
11
11
|
@method = 'post'
|
12
|
-
|
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)
|
13
18
|
end
|
14
19
|
|
15
20
|
def operation_object
|
@@ -52,8 +57,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
52
57
|
operation_object.validate_request_params({"string" => 1}, HEADER, @validator_option)
|
53
58
|
}
|
54
59
|
|
55
|
-
|
56
|
-
assert e.message.start_with?("1 class is #{1.class} but it's not valid")
|
60
|
+
assert_match(/expected string, but received Integer: 1/i, e.message)
|
57
61
|
end
|
58
62
|
|
59
63
|
it 'support put method' do
|
@@ -64,8 +68,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
64
68
|
operation_object.validate_request_params({"string" => 1}, HEADER, @validator_option)
|
65
69
|
}
|
66
70
|
|
67
|
-
|
68
|
-
assert e.message.start_with?("1 class is #{1.class} but it's not valid")
|
71
|
+
assert_match(/expected string, but received Integer: 1/i, e.message)
|
69
72
|
end
|
70
73
|
|
71
74
|
it 'support patch method' do
|
@@ -76,7 +79,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
76
79
|
operation_object.validate_request_params({"integer" => "str"}, HEADER, @validator_option)
|
77
80
|
}
|
78
81
|
|
79
|
-
|
82
|
+
assert_match(/expected integer, but received String: str/i, e.message)
|
80
83
|
end
|
81
84
|
|
82
85
|
it 'unknown param' do
|
@@ -109,7 +112,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
109
112
|
operation_object.validate_request_params({"query_integer_list" => [1, 2]}, HEADER, @validator_option)
|
110
113
|
}
|
111
114
|
|
112
|
-
|
115
|
+
assert_match(/missing required parameters: query_string/i, e.message)
|
113
116
|
end
|
114
117
|
|
115
118
|
it 'invalid type' do
|
@@ -121,8 +124,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
121
124
|
)
|
122
125
|
}
|
123
126
|
|
124
|
-
|
125
|
-
assert e.message.start_with?("1 class is #{1.class} but")
|
127
|
+
assert_match(/expected string, but received Integer: 1/i, e.message)
|
126
128
|
end
|
127
129
|
end
|
128
130
|
|
@@ -143,7 +145,23 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
|
|
143
145
|
operation_object.validate_request_params({"limit" => "a"}, HEADER, @validator_option)
|
144
146
|
}
|
145
147
|
|
146
|
-
|
148
|
+
assert_match(/expected integer, but received String: a/i, e.message)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe '#content_types' do
|
153
|
+
it 'returns supported content types' do
|
154
|
+
@path = '/validate_content_types'
|
155
|
+
@method = 'post'
|
156
|
+
|
157
|
+
assert_equal ["application/json", "application/binary"], operation_object.request_content_types
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'returns an empty array when the content of requestBody does not exist' do
|
161
|
+
@path = '/characters'
|
162
|
+
@method = 'get'
|
163
|
+
|
164
|
+
assert_equal [], operation_object.request_content_types
|
147
165
|
end
|
148
166
|
end
|
149
167
|
end
|
@@ -10,7 +10,7 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
|
|
10
10
|
@app
|
11
11
|
end
|
12
12
|
|
13
|
-
it "skip
|
13
|
+
it "skip validation when link does not exist" do
|
14
14
|
@app = new_rack_app(schema: open_api_3_schema)
|
15
15
|
params = {}
|
16
16
|
header "Content-Type", "application/json"
|
@@ -21,11 +21,34 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
|
|
21
21
|
it "optionally content_type check" do
|
22
22
|
@app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
|
23
23
|
params = {
|
24
|
-
|
24
|
+
"string_post_1" => "cloudnasium"
|
25
25
|
}
|
26
26
|
header "Content-Type", "text/html"
|
27
27
|
post "/characters", JSON.generate(params)
|
28
28
|
assert_equal 400, last_response.status
|
29
|
+
|
30
|
+
body = JSON.parse(last_response.body)
|
31
|
+
message =
|
32
|
+
%{"Content-Type" request header must be set to "application/json".}
|
33
|
+
|
34
|
+
assert_equal "bad_request", body['id']
|
35
|
+
assert_equal message, body['message']
|
36
|
+
end
|
37
|
+
|
38
|
+
it "validates content_type" do
|
39
|
+
@app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
|
40
|
+
params = {
|
41
|
+
"string_post_1" => "cloudnasium"
|
42
|
+
}
|
43
|
+
header "Content-Type", "text/html"
|
44
|
+
post "/validate_content_types", JSON.generate(params)
|
45
|
+
assert_equal 400, last_response.status
|
46
|
+
|
47
|
+
body = JSON.parse(last_response.body)
|
48
|
+
message =
|
49
|
+
%{"Content-Type" request header must be set to any of the following: ["application/json", "application/binary"].}
|
50
|
+
|
51
|
+
assert_equal message, body['message']
|
29
52
|
end
|
30
53
|
|
31
54
|
it "optionally skip content_type check" do
|
@@ -38,7 +61,7 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
|
|
38
61
|
assert_equal 200, last_response.status
|
39
62
|
end
|
40
63
|
|
41
|
-
it "if not exist
|
64
|
+
it "if not exist requestBody definition, skip content_type check" do
|
42
65
|
@app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
|
43
66
|
params = {
|
44
67
|
"string_post_1" => "cloudnasium"
|
@@ -49,6 +72,9 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
|
|
49
72
|
end
|
50
73
|
|
51
74
|
def new_rack_app(options = {})
|
75
|
+
# TODO: delete when 5.0.0 released because default value changed
|
76
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
77
|
+
|
52
78
|
Rack::Builder.new {
|
53
79
|
use Committee::Middleware::RequestValidation, options
|
54
80
|
run lambda { |_|
|
@@ -12,7 +12,12 @@ describe Committee::SchemaValidator::OpenAPI3::ResponseValidator do
|
|
12
12
|
|
13
13
|
@path = '/validate'
|
14
14
|
@method = 'post'
|
15
|
-
|
15
|
+
|
16
|
+
# TODO: delete when 5.0.0 released because default value changed
|
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
21
|
end
|
17
22
|
|
18
23
|
it "passes through a valid response" do
|
@@ -29,7 +34,7 @@ describe Committee::SchemaValidator::OpenAPI3::ResponseValidator do
|
|
29
34
|
call_response_validator
|
30
35
|
end
|
31
36
|
|
32
|
-
it "
|
37
|
+
it "raises InvalidResponse when a valid response with no registered body with strict option" do
|
33
38
|
@headers = { "Content-Type" => "application/xml" }
|
34
39
|
assert_raises(Committee::InvalidResponse) {
|
35
40
|
call_response_validator(true)
|
@@ -41,7 +46,7 @@ describe Committee::SchemaValidator::OpenAPI3::ResponseValidator do
|
|
41
46
|
call_response_validator
|
42
47
|
end
|
43
48
|
|
44
|
-
it "
|
49
|
+
it "raises InvalidResponse when a valid response with no Content-Type headers with strict option" do
|
45
50
|
@headers = {}
|
46
51
|
assert_raises(Committee::InvalidResponse) {
|
47
52
|
call_response_validator(true)
|
@@ -30,6 +30,9 @@ 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
|
33
36
|
end
|
34
37
|
|
35
38
|
describe "#assert_schema_conform" do
|
data/test/test/methods_test.rb
CHANGED
@@ -28,7 +28,10 @@ describe Committee::Test::Methods do
|
|
28
28
|
# our purposes here in testing the module.
|
29
29
|
@committee_router = nil
|
30
30
|
@committee_schema = nil
|
31
|
-
@committee_options =
|
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
|
32
35
|
end
|
33
36
|
|
34
37
|
describe "Hyper-Schema" do
|
@@ -36,7 +39,7 @@ describe Committee::Test::Methods do
|
|
36
39
|
sc = JsonSchema.parse!(hyper_schema_data)
|
37
40
|
sc.expand_references!
|
38
41
|
s = Committee::Drivers::HyperSchema::Driver.new.parse(sc)
|
39
|
-
@committee_options
|
42
|
+
@committee_options.merge!({schema: s})
|
40
43
|
end
|
41
44
|
|
42
45
|
describe "#assert_schema_conform" do
|
@@ -120,7 +123,7 @@ describe Committee::Test::Methods do
|
|
120
123
|
|
121
124
|
describe "OpenAPI3" do
|
122
125
|
before do
|
123
|
-
@committee_options
|
126
|
+
@committee_options.merge!({schema: open_api_3_schema})
|
124
127
|
|
125
128
|
@correct_response = { string_1: :honoka }
|
126
129
|
end
|
@@ -138,7 +141,7 @@ describe Committee::Test::Methods do
|
|
138
141
|
e = assert_raises(Committee::InvalidResponse) do
|
139
142
|
assert_schema_conform
|
140
143
|
end
|
141
|
-
assert_match(/
|
144
|
+
assert_match(/response definition does not exist/i, e.message)
|
142
145
|
end
|
143
146
|
|
144
147
|
it "detects an invalid response status code" do
|
@@ -149,7 +152,7 @@ describe Committee::Test::Methods do
|
|
149
152
|
e = assert_raises(Committee::InvalidResponse) do
|
150
153
|
assert_schema_conform
|
151
154
|
end
|
152
|
-
assert_match(/
|
155
|
+
assert_match(/status code definition does not exist/i, e.message)
|
153
156
|
end
|
154
157
|
|
155
158
|
it "outputs deprecation warning" do
|
@@ -175,7 +178,8 @@ describe Committee::Test::Methods do
|
|
175
178
|
e = assert_raises(Committee::InvalidRequest) do
|
176
179
|
assert_request_schema_confirm
|
177
180
|
end
|
178
|
-
|
181
|
+
|
182
|
+
assert_match(/missing required parameters: query_string/i, e.message)
|
179
183
|
end
|
180
184
|
|
181
185
|
it "path undefined in schema" do
|
@@ -201,7 +205,7 @@ describe Committee::Test::Methods do
|
|
201
205
|
e = assert_raises(Committee::InvalidResponse) do
|
202
206
|
assert_response_schema_confirm
|
203
207
|
end
|
204
|
-
assert_match(/
|
208
|
+
assert_match(/response definition does not exist/i, e.message)
|
205
209
|
end
|
206
210
|
|
207
211
|
it "detects an invalid response status code" do
|
@@ -212,7 +216,7 @@ describe Committee::Test::Methods do
|
|
212
216
|
e = assert_raises(Committee::InvalidResponse) do
|
213
217
|
assert_response_schema_confirm
|
214
218
|
end
|
215
|
-
assert_match(/
|
219
|
+
assert_match(/status code definition does not exist/i, e.message)
|
216
220
|
end
|
217
221
|
|
218
222
|
it "path undefined in schema" do
|
data/test/test_helper.rb
CHANGED
@@ -56,7 +56,7 @@ def open_api_2_schema
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def open_api_3_schema
|
59
|
-
@open_api_3_schema ||= Committee::Drivers.
|
59
|
+
@open_api_3_schema ||= Committee::Drivers.load_from_file(open_api_3_schema_path)
|
60
60
|
end
|
61
61
|
|
62
62
|
# Don't cache this because we'll often manipulate the created hash in tests.
|
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:
|
4
|
+
version: 4.1.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: 2020-06-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json_schema
|
@@ -52,14 +52,14 @@ dependencies:
|
|
52
52
|
requirements:
|
53
53
|
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 0.
|
55
|
+
version: 0.11.1
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
58
|
version_requirements: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
60
|
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0.
|
62
|
+
version: 0.11.1
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: minitest
|
65
65
|
requirement: !ruby/object:Gem::Requirement
|
@@ -282,14 +282,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
282
282
|
requirements:
|
283
283
|
- - ">="
|
284
284
|
- !ruby/object:Gem::Version
|
285
|
-
version: 2.
|
285
|
+
version: 2.4.0
|
286
286
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
287
287
|
requirements:
|
288
288
|
- - ">="
|
289
289
|
- !ruby/object:Gem::Version
|
290
290
|
version: '0'
|
291
291
|
requirements: []
|
292
|
-
rubygems_version: 3.
|
292
|
+
rubygems_version: 3.1.2
|
293
293
|
signing_key:
|
294
294
|
specification_version: 4
|
295
295
|
summary: A collection of Rack middleware to support JSON Schema.
|