committee 3.2.1 → 3.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2af076998ef23743c239df64c5517e3e334422a3523f09e6f8baa4f1a9f1ef77
4
- data.tar.gz: a5ae6eca5d34310a69e1c33ca6f11a807e19316c8fad9123521ecf835cfe091c
3
+ metadata.gz: 0c35304cf9026ae20062ea312cdca6b43af486c4c2e5e7c952b35bbad811ce4e
4
+ data.tar.gz: d9a96cd2c6c15b9de26fb95ef0b4d59216c999f8589329d6ee6b21b41e2511d9
5
5
  SHA512:
6
- metadata.gz: 65e65734251a25cb3a3735081c8a3e2e6973b93d1e14b66261d3978e7dac3ea5a9081fe7a530625cf9407d3ac25bc8941d6bea064d07f546186b6a2ebd043fa6
7
- data.tar.gz: 7dee370a2748aa7b67d1e360e86aacb204d16a5a68d18ac879ececc3633d6d92f5ad9b49ba36ac8851e1a04f2322fec2269b8926f30f061d1524bf284af90848
6
+ metadata.gz: 42ffc889dcc301c9de500417390454f4723bf049f0336b9de92b94fcaa2d67f53a7f5c4c9ad5a3a56bd2e9fff70d06ebe7c7279729c616b45ab33625c2a33572
7
+ data.tar.gz: d3c7ca273497b2eb4444fcdb6eb43f49fed866335d1a627f806586f6755557b8a956b43eb5c9448b7cf19176b9e2a4705c78bf6045dde2e98b19fd55211e0070
@@ -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
- schema_validator = build_schema_validator(request)
17
- schema_validator.request_validate(request)
18
-
19
- raise Committee::NotFound, "That request method and path combination isn't defined." if !schema_validator.link_exist? && @strict
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,7 +8,6 @@ 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)
@@ -379,6 +379,13 @@ describe Committee::Middleware::RequestValidation do
379
379
  assert_match(/expected integer, but received String: foo/i, last_response.body)
380
380
  end
381
381
 
382
+ it "ignores errors when ignore_error: true" do
383
+ @app = new_rack_app(schema: open_api_3_schema, ignore_error: true)
384
+ get "/characters?limit=foo"
385
+
386
+ assert_equal 200, last_response.status
387
+ end
388
+
382
389
  it "coerce string to integer" do
383
390
  check_parameter_string = lambda { |env|
384
391
  assert env['committee.params']['integer'].is_a?(Integer)
@@ -429,6 +436,22 @@ describe Committee::Middleware::RequestValidation do
429
436
  end
430
437
  end
431
438
 
439
+ describe ':accept_request_filter' do
440
+ [
441
+ { description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 400 } },
442
+ { description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/c') }, expected: { status: 400 } },
443
+ { description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
444
+ ].each do |description:, accept_request_filter:, expected:|
445
+ it description do
446
+ @app = new_rack_app(prefix: '/v1', schema: open_api_3_schema, accept_request_filter: accept_request_filter)
447
+
448
+ post 'v1/characters', JSON.generate(string_post_1: 1)
449
+
450
+ assert_equal expected[:status], last_response.status
451
+ end
452
+ end
453
+ end
454
+
432
455
  private
433
456
 
434
457
  def new_rack_app(options = {})
@@ -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,22 @@ 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 |description:, accept_request_filter:, expected:|
499
+ it description do
500
+ @app = new_rack_app(prefix: '/v1', schema: hyper_schema, accept_request_filter: accept_request_filter)
501
+
502
+ post '/v1/apps', '{x:y}'
503
+
504
+ assert_equal expected[:status], last_response.status
505
+ end
506
+ end
507
+ end
508
+
483
509
  private
484
510
 
485
511
  def new_rack_app(options = {})
@@ -100,29 +100,41 @@ describe Committee::Middleware::ResponseValidation do
100
100
  end
101
101
 
102
102
  describe 'check header' do
103
- it 'valid type header' do
104
- @app = new_response_rack({}.to_json, {'x-limit' => 1}, schema: open_api_3_schema, raise: true)
105
-
106
- get "/header"
107
-
108
- assert_equal 200, last_response.status
109
- end
110
-
111
- it 'invalid type header' do
112
- @app = new_response_rack({}.to_json, {'x-limit' => '1'}, schema: open_api_3_schema, raise: true)
113
-
114
- assert_raises(Committee::InvalidResponse) do
115
- get "/header"
103
+ [
104
+ { check_header: true, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
105
+ { check_header: true, description: 'missing value', header: { 'integer' => nil }, expected: { error: 'headers/integer/schema does not allow null values' } },
106
+ { check_header: true, description: 'invalid value', header: { 'integer' => 'x' }, expected: { error: 'headers/integer/schema expected integer, but received String: x' } },
107
+
108
+ { check_header: false, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
109
+ { check_header: false, description: 'missing value', header: { 'integer' => nil }, expected: { status: 200 } },
110
+ { check_header: false, description: 'invalid value', header: { 'integer' => 'x' }, expected: { status: 200 } },
111
+ ].each do |check_header:, description:, header:, expected:|
112
+ describe "when #{check_header}" do
113
+ %w(get post put patch delete).each do |method|
114
+ describe method do
115
+ describe description do
116
+ if expected[:error].nil?
117
+ it 'should pass' do
118
+ @app = new_response_rack({}.to_json, header, schema: open_api_3_schema, raise: true, check_header: check_header)
119
+
120
+ send(method, "/header")
121
+ assert_equal expected[:status], last_response.status
122
+ end
123
+ else
124
+ it 'should fail' do
125
+ @app = new_response_rack({}.to_json, header, schema: open_api_3_schema, raise: true, check_header: check_header)
126
+
127
+ error = assert_raises(Committee::InvalidResponse) do
128
+ get "/header"
129
+ end
130
+ assert_match(expected[:error], error.message)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
116
136
  end
117
137
  end
118
-
119
- it 'invalid type but not check' do
120
- @app = new_response_rack({}.to_json, {'x-limit' => '1'}, schema: open_api_3_schema, raise: true, check_header: false)
121
-
122
- get "/header"
123
-
124
- assert_equal 200, last_response.status
125
- end
126
138
  end
127
139
 
128
140
  describe 'validate error option' do
@@ -157,6 +169,22 @@ describe Committee::Middleware::ResponseValidation do
157
169
  end
158
170
  end
159
171
 
172
+ describe ':accept_request_filter' do
173
+ [
174
+ { description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 500 } },
175
+ { description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/c') }, expected: { status: 500 } },
176
+ { description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
177
+ ].each do |description:, accept_request_filter:, expected:|
178
+ it description do
179
+ @app = new_response_rack('not_json', {}, schema: open_api_3_schema, prefix: '/v1', accept_request_filter: accept_request_filter)
180
+
181
+ get 'v1/characters'
182
+
183
+ assert_equal expected[:status], last_response.status
184
+ end
185
+ end
186
+ end
187
+
160
188
  private
161
189
 
162
190
  def new_response_rack(response, headers = {}, options = {}, rack_options = {})
@@ -162,6 +162,22 @@ 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 |description:, accept_request_filter:, expected:|
171
+ it description do
172
+ @app = new_rack_app('not_json', {}, schema: hyper_schema, prefix: '/v1', accept_request_filter: accept_request_filter)
173
+
174
+ get '/v1/apps'
175
+
176
+ assert_equal expected[:status], last_response.status
177
+ end
178
+ end
179
+ end
180
+
165
181
  private
166
182
 
167
183
  def new_rack_app(response, headers = {}, options = {})
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: 3.2.1
4
+ version: 3.3.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: 2019-10-13 00:00:00.000000000 Z
13
+ date: 2019-11-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json_schema