committee 3.2.0 → 4.2.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 +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 +2 -3
- 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 +3 -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 +71 -18
- data/test/middleware/request_validation_test.rb +32 -0
- data/test/middleware/response_validation_open_api_3_test.rb +95 -20
- data/test/middleware/response_validation_test.rb +22 -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 +12 -10
- data/test/schema_validator/open_api_3/request_validator_test.rb +3 -0
- 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: 43984e56c905ff9e141e1ed49af5c9e51b07c39bda8bc268d195dc5799809d89
|
|
4
|
+
data.tar.gz: 76a6269ac7cc8237a63b2ae6c69ac512a60cecabaed7564dee88cd3adfa9328e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f79ef24531c7b81489d12ea59e9da42e570236554a84c064c8478625e29167c3fef7245196a2c48d2a0a31ab33639417d47527321b321172f32c5f80fce5f46b
|
|
7
|
+
data.tar.gz: 68c8ad83aa2392ba1d31d440edb54b1301b6c37e093f7d466c0a9f406510a0efbdf6c9ea8aacf1ddf051fae31c03d2bd777accd90101bd321037dfdafd0affbf
|
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
|
|
@@ -8,13 +8,12 @@ module Committee
|
|
|
8
8
|
def initialize(app, options = {})
|
|
9
9
|
super
|
|
10
10
|
@validate_success_only = @schema.validator_option.validate_success_only
|
|
11
|
-
@ignore_error = options.fetch(:ignore_error, false)
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def handle(request)
|
|
15
|
-
|
|
16
|
-
status, headers, response = @app.call(request.env)
|
|
14
|
+
status, headers, response = @app.call(request.env)
|
|
17
15
|
|
|
16
|
+
begin
|
|
18
17
|
v = build_schema_validator(request)
|
|
19
18
|
v.response_validate(status, headers, response) if v.link_exist? && self.class.validate?(status, validate_success_only)
|
|
20
19
|
|
|
@@ -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.
|
|
@@ -116,7 +116,9 @@ module Committee
|
|
|
116
116
|
content_type = headers['Content-Type'].to_s.split(";").first.to_s
|
|
117
117
|
|
|
118
118
|
# bad performance because when we coerce value, same check
|
|
119
|
-
|
|
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)
|
|
120
122
|
rescue => e
|
|
121
123
|
raise Committee::InvalidRequest.new(e.message)
|
|
122
124
|
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,65 @@ 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
|
-
|
|
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
|
|
457
|
+
end
|
|
458
|
+
end
|
|
413
459
|
|
|
414
|
-
|
|
460
|
+
it 'does not suppress application error' do
|
|
461
|
+
@app = new_rack_app_with_lambda(lambda { |_|
|
|
462
|
+
JSON.load('-') # invalid json
|
|
463
|
+
}, schema: open_api_3_schema, raise: true)
|
|
415
464
|
|
|
416
|
-
|
|
465
|
+
assert_raises(JSON::ParserError) do
|
|
466
|
+
get "/error", nil
|
|
417
467
|
end
|
|
418
468
|
end
|
|
419
469
|
|
|
@@ -426,6 +476,9 @@ describe Committee::Middleware::RequestValidation do
|
|
|
426
476
|
end
|
|
427
477
|
|
|
428
478
|
def new_rack_app_with_lambda(check_lambda, options = {})
|
|
479
|
+
# TODO: delete when 5.0.0 released because default value changed
|
|
480
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
|
481
|
+
|
|
429
482
|
Rack::Builder.new {
|
|
430
483
|
use Committee::Middleware::RequestValidation, options
|
|
431
484
|
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
|
|
@@ -34,6 +34,14 @@ describe Committee::Middleware::ResponseValidation do
|
|
|
34
34
|
assert_equal 200, last_response.status
|
|
35
35
|
end
|
|
36
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
|
+
|
|
37
45
|
it "passes through not definition" do
|
|
38
46
|
@app = new_response_rack(JSON.generate(CHARACTERS_RESPONSE), {}, schema: open_api_3_schema)
|
|
39
47
|
get "/no_data"
|
|
@@ -47,7 +55,7 @@ describe Committee::Middleware::ResponseValidation do
|
|
|
47
55
|
get "/characters"
|
|
48
56
|
}
|
|
49
57
|
|
|
50
|
-
assert_match(/
|
|
58
|
+
assert_match(/expected object, but received Array: /i, e.message)
|
|
51
59
|
end
|
|
52
60
|
|
|
53
61
|
it "passes through a 204 (no content) response" do
|
|
@@ -99,29 +107,59 @@ describe Committee::Middleware::ResponseValidation do
|
|
|
99
107
|
assert_match(/valid JSON/i, last_response.body)
|
|
100
108
|
end
|
|
101
109
|
|
|
102
|
-
describe
|
|
103
|
-
it
|
|
104
|
-
@app = new_response_rack(
|
|
105
|
-
|
|
106
|
-
get "/header"
|
|
107
|
-
|
|
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"
|
|
108
114
|
assert_equal 200, last_response.status
|
|
109
115
|
end
|
|
110
116
|
|
|
111
|
-
it
|
|
112
|
-
@app = new_response_rack({}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
get "/header"
|
|
116
|
-
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
|
|
117
121
|
end
|
|
122
|
+
end
|
|
118
123
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
125
163
|
end
|
|
126
164
|
end
|
|
127
165
|
|
|
@@ -138,7 +176,8 @@ describe Committee::Middleware::ResponseValidation do
|
|
|
138
176
|
e = assert_raises(Committee::InvalidResponse) do
|
|
139
177
|
get "/characters"
|
|
140
178
|
end
|
|
141
|
-
|
|
179
|
+
|
|
180
|
+
assert_match(/but received String: 1/i, e.message)
|
|
142
181
|
end
|
|
143
182
|
|
|
144
183
|
it "detects an invalid response status code with validate_success_only=true" do
|
|
@@ -156,9 +195,45 @@ describe Committee::Middleware::ResponseValidation do
|
|
|
156
195
|
end
|
|
157
196
|
end
|
|
158
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
|
+
|
|
218
|
+
it 'does not suppress application error' do
|
|
219
|
+
@app = Rack::Builder.new {
|
|
220
|
+
use Committee::Middleware::ResponseValidation, {schema: open_api_3_schema, raise: true}
|
|
221
|
+
run lambda { |_|
|
|
222
|
+
JSON.load('-') # invalid json
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
assert_raises(JSON::ParserError) do
|
|
227
|
+
get "/error", nil
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
159
231
|
private
|
|
160
232
|
|
|
161
233
|
def new_response_rack(response, headers = {}, options = {}, rack_options = {})
|
|
234
|
+
# TODO: delete when 5.0.0 released because default value changed
|
|
235
|
+
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
|
|
236
|
+
|
|
162
237
|
status = rack_options[:status] || 200
|
|
163
238
|
headers = {
|
|
164
239
|
"Content-Type" => "application/json"
|
|
@@ -162,9 +162,31 @@ describe Committee::Middleware::ResponseValidation do
|
|
|
162
162
|
assert_match(/valid JSON/i, last_response.body)
|
|
163
163
|
end
|
|
164
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
|
+
|
|
165
184
|
private
|
|
166
185
|
|
|
167
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
|
+
|
|
168
190
|
headers = {
|
|
169
191
|
"Content-Type" => "application/json"
|
|
170
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,7 @@ 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)
|
|
147
149
|
end
|
|
148
150
|
end
|
|
149
151
|
|
|
@@ -72,6 +72,9 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
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
|
+
|
|
75
78
|
Rack::Builder.new {
|
|
76
79
|
use Committee::Middleware::RequestValidation, options
|
|
77
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.2.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-08-26 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.
|