committee 5.6.1 → 5.6.2

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/committee/drivers/open_api_3/driver.rb +5 -0
  3. data/lib/committee/drivers.rb +2 -3
  4. data/lib/committee/errors.rb +11 -0
  5. data/lib/committee/middleware/base.rb +11 -5
  6. data/lib/committee/middleware/options/base.rb +107 -0
  7. data/lib/committee/middleware/options/request_validation.rb +80 -0
  8. data/lib/committee/middleware/options/response_validation.rb +46 -0
  9. data/lib/committee/middleware/options.rb +12 -0
  10. data/lib/committee/middleware/request_validation.rb +7 -1
  11. data/lib/committee/middleware/response_validation.rb +6 -2
  12. data/lib/committee/middleware.rb +1 -0
  13. data/lib/committee/schema_validator/hyper_schema/response_generator.rb +1 -3
  14. data/lib/committee/schema_validator/hyper_schema/response_validator.rb +14 -1
  15. data/lib/committee/schema_validator/hyper_schema/router.rb +1 -1
  16. data/lib/committee/schema_validator/hyper_schema.rb +2 -13
  17. data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +43 -13
  18. data/lib/committee/schema_validator/open_api_3/parameter_deserializer.rb +495 -0
  19. data/lib/committee/schema_validator/open_api_3/response_validator.rb +16 -2
  20. data/lib/committee/schema_validator/open_api_3.rb +18 -12
  21. data/lib/committee/schema_validator/option.rb +6 -17
  22. data/lib/committee/schema_validator.rb +5 -1
  23. data/lib/committee/test/except_parameter.rb +416 -0
  24. data/lib/committee/test/methods.rb +27 -2
  25. data/lib/committee/version.rb +1 -1
  26. data/lib/committee.rb +1 -1
  27. data/test/drivers/open_api_2/driver_test.rb +4 -16
  28. data/test/drivers/open_api_2/parameter_schema_builder_test.rb +4 -50
  29. data/test/drivers_test.rb +35 -21
  30. data/test/middleware/options/base_test.rb +120 -0
  31. data/test/middleware/options/request_validation_test.rb +177 -0
  32. data/test/middleware/options/response_validation_test.rb +121 -0
  33. data/test/middleware/request_validation_open_api_3_test.rb +113 -80
  34. data/test/middleware/request_validation_test.rb +13 -70
  35. data/test/middleware/response_validation_open_api_3_test.rb +33 -17
  36. data/test/middleware/response_validation_test.rb +3 -14
  37. data/test/request_unpacker_test.rb +2 -10
  38. data/test/schema_validator/hyper_schema/parameter_coercer_test.rb +1 -37
  39. data/test/schema_validator/hyper_schema/request_validator_test.rb +6 -30
  40. data/test/schema_validator/hyper_schema/router_test.rb +5 -0
  41. data/test/schema_validator/hyper_schema/string_params_coercer_test.rb +1 -37
  42. data/test/schema_validator/open_api_3/operation_wrapper_test.rb +40 -43
  43. data/test/schema_validator/open_api_3/parameter_deserializer_test.rb +457 -0
  44. data/test/schema_validator/open_api_3/request_validator_test.rb +1 -2
  45. data/test/schema_validator/open_api_3/response_validator_test.rb +3 -11
  46. data/test/schema_validator_test.rb +8 -0
  47. data/test/test/methods_test.rb +222 -105
  48. data/test/test/schema_coverage_test.rb +8 -155
  49. metadata +12 -2
@@ -20,4 +20,12 @@ describe Committee::SchemaValidator do
20
20
  media_type = Committee::SchemaValidator.request_media_type(request)
21
21
  assert_equal 'multipart/form-data', media_type
22
22
  end
23
+
24
+ it "builds prefix regexp with a path segment boundary" do
25
+ regexp = Committee::SchemaValidator.build_prefix_regexp("/v1")
26
+
27
+ assert regexp.match?("/v1")
28
+ assert regexp.match?("/v1/characters")
29
+ refute regexp.match?("/v11/characters")
30
+ end
23
31
  end
@@ -169,6 +169,225 @@ describe Committee::Test::Methods do
169
169
  end
170
170
  assert_match(/`GET \/undefined` undefined in schema/i, e.message)
171
171
  end
172
+
173
+ describe "with except option" do
174
+ it "passes validation when required query parameter is excepted" do
175
+ @app = new_rack_app
176
+ # Missing required 'data' parameter, but except it
177
+ get "/get_endpoint_with_required_parameter"
178
+ assert_request_schema_confirm(except: { query: ['data'] })
179
+ end
180
+
181
+ it "still validates other parameters when some are excepted" do
182
+ @app = new_rack_app
183
+ # Missing required 'data' parameter, but except it
184
+ # This test verifies that the except option works
185
+ get "/get_endpoint_with_required_parameter"
186
+ assert_request_schema_confirm(except: { query: ['data'] })
187
+ end
188
+
189
+ it "works without except option (backward compatibility)" do
190
+ @app = new_rack_app
191
+ get "/characters"
192
+ assert_request_schema_confirm
193
+ end
194
+
195
+ it "supports multiple parameter types" do
196
+ @app = new_rack_app
197
+ # Can except headers, query, and body parameters
198
+ get "/get_endpoint_with_required_parameter"
199
+ assert_request_schema_confirm(except: { headers: ['authorization'], query: ['data'] })
200
+ end
201
+
202
+ it "supports multiple parameters in each type" do
203
+ @app = new_rack_app
204
+ # Can except multiple parameters in each type simultaneously
205
+ get "/get_endpoint_with_required_parameter"
206
+ assert_request_schema_confirm(except: { headers: ['content-type', 'authorization', 'accept'], query: ['data', 'page', 'limit'] })
207
+ end
208
+
209
+ it "raises error when non-excepted required parameter is missing" do
210
+ @app = new_rack_app
211
+ # Except only 'required_param_a', but 'required_param_b' is also required and missing
212
+ # This should raise an error for 'required_param_b'
213
+ get "/test_except_validation"
214
+
215
+ e = assert_raises(Committee::InvalidRequest) do
216
+ assert_request_schema_confirm(except: { query: ['required_param_a'] })
217
+ end
218
+ # Verify error is about the non-excepted missing parameter
219
+ assert_match(/required_param_b/i, e.message)
220
+ end
221
+
222
+ describe "with body params" do
223
+ it "passes validation when required string body param is excepted" do
224
+ @app = new_rack_app
225
+ post "/test_except_body_params", JSON.generate({ "required_integer" => 1 }), { "CONTENT_TYPE" => "application/json" }
226
+ assert_request_schema_confirm(except: { body: ['required_string'] })
227
+ end
228
+
229
+ it "passes validation when required integer body param is excepted" do
230
+ @app = new_rack_app
231
+ post "/test_except_body_params", JSON.generate({ "required_string" => "foo" }), { "CONTENT_TYPE" => "application/json" }
232
+ assert_request_schema_confirm(except: { body: ['required_integer'] })
233
+ end
234
+
235
+ it "passes validation when all required body params are excepted" do
236
+ @app = new_rack_app
237
+ post "/test_except_body_params", nil, { "CONTENT_TYPE" => "application/json" }
238
+ assert_request_schema_confirm(except: { body: ['required_string', 'required_integer'] })
239
+ end
240
+
241
+ it "raises error when non-excepted required body param is missing" do
242
+ @app = new_rack_app
243
+ post "/test_except_body_params", nil, { "CONTENT_TYPE" => "application/json" }
244
+ e = assert_raises(Committee::InvalidRequest) do
245
+ assert_request_schema_confirm(except: { body: ['required_string'] })
246
+ end
247
+ assert_match(/required_integer/i, e.message)
248
+ end
249
+
250
+ describe "non-string types and format constraints" do
251
+ it "passes validation when required integer query param is excepted" do
252
+ @app = new_rack_app
253
+ get "/get_endpoint_with_required_integer_query"
254
+ assert_request_schema_confirm(except: { query: ['count'] })
255
+ end
256
+
257
+ it "passes validation when required integer header is excepted" do
258
+ @app = new_rack_app
259
+ get "/header"
260
+ assert_request_schema_confirm(except: { headers: ['integer'] })
261
+ end
262
+
263
+ it "passes validation when required enum body param is excepted" do
264
+ @app = new_rack_app
265
+ post "/test_except_body_with_constraints", JSON.generate({ "created_at" => "2024-01-01T00:00:00Z" }), { "CONTENT_TYPE" => "application/json" }
266
+ assert_request_schema_confirm(except: { body: ['status'] })
267
+ end
268
+
269
+ it "passes validation when required date-time format body param is excepted" do
270
+ @app = new_rack_app
271
+ post "/test_except_body_with_constraints", JSON.generate({ "status" => "active" }), { "CONTENT_TYPE" => "application/json" }
272
+ assert_request_schema_confirm(except: { body: ['created_at'] })
273
+ end
274
+ end
275
+
276
+ describe "with form-encoded body params" do
277
+ it "passes validation when required string form param is excepted" do
278
+ @app = new_rack_app
279
+ post "/test_except_form_params", "required_integer=1", { "CONTENT_TYPE" => "application/x-www-form-urlencoded" }
280
+ assert_request_schema_confirm(except: { body: ['required_string'] })
281
+ end
282
+
283
+ it "passes validation when required integer form param is excepted" do
284
+ @app = new_rack_app
285
+ post "/test_except_form_params", "required_string=foo", { "CONTENT_TYPE" => "application/x-www-form-urlencoded" }
286
+ assert_request_schema_confirm(except: { body: ['required_integer'] })
287
+ end
288
+
289
+ it "passes validation when all required form params are excepted" do
290
+ @app = new_rack_app
291
+ post "/test_except_form_params", "", { "CONTENT_TYPE" => "application/x-www-form-urlencoded" }
292
+ assert_request_schema_confirm(except: { body: ['required_string', 'required_integer'] })
293
+ end
294
+
295
+ it "raises error when non-excepted required form param is missing" do
296
+ @app = new_rack_app
297
+ post "/test_except_form_params", "", { "CONTENT_TYPE" => "application/x-www-form-urlencoded" }
298
+ e = assert_raises(Committee::InvalidRequest) do
299
+ assert_request_schema_confirm(except: { body: ['required_string'] })
300
+ end
301
+ assert_match(/required_integer/i, e.message)
302
+ end
303
+ end
304
+
305
+ describe "with special rack headers" do
306
+ it "passes validation when required Content-Type header is excepted" do
307
+ @app = new_rack_app
308
+ post "/test_except_content_type_header", nil
309
+ assert_request_schema_confirm(except: { headers: ['Content-Type'] })
310
+ end
311
+ end
312
+
313
+ describe "does not overwrite existing values" do
314
+ it "leaves an existing query param value unchanged when it is excepted" do
315
+ @app = new_rack_app
316
+ get "/get_endpoint_with_required_parameter", "data" => "existing_value"
317
+ before_value = last_request.GET["data"]
318
+ assert_request_schema_confirm(except: { query: ['data'] })
319
+ assert_equal before_value, last_request.GET["data"]
320
+ end
321
+ end
322
+
323
+ describe "with vnd.api+json content type" do
324
+ it "treats application/vnd.api+json body as JSON and injects dummy values" do
325
+ @app = new_rack_app
326
+ post "/test_except_vnd_json_body", JSON.generate({}), { "CONTENT_TYPE" => "application/vnd.api+json" }
327
+ assert_request_schema_confirm(except: { body: ['required_string'] })
328
+ end
329
+ end
330
+
331
+ describe "with schema_path option" do
332
+ before do
333
+ @committee_options = { schema_path: open_api_3_schema_path }
334
+ end
335
+
336
+ it "passes validation when required integer query param is excepted" do
337
+ @app = new_rack_app
338
+ get "/get_endpoint_with_required_integer_query"
339
+ assert_request_schema_confirm(except: { query: ['count'] })
340
+ end
341
+ end
342
+
343
+ describe "with path item-level parameters" do
344
+ it "passes validation when required integer query param declared at path level is excepted" do
345
+ @app = new_rack_app
346
+ get "/test_path_level_required_integer"
347
+ assert_request_schema_confirm(except: { query: ['count'] })
348
+ end
349
+ end
350
+
351
+ describe "with multiple content-type body" do
352
+ it "uses the correct schema for form-urlencoded when excepting a body param" do
353
+ @app = new_rack_app
354
+ post "/test_multi_content_type_body", "", "CONTENT_TYPE" => "application/x-www-form-urlencoded"
355
+ assert_request_schema_confirm(except: { body: ['status'] })
356
+ end
357
+ end
358
+
359
+ describe "with non-hash JSON body" do
360
+ it "raises BadRequest when JSON body is an array" do
361
+ @app = new_rack_app
362
+ post "/test_except_body_params", "[1,2,3]", "CONTENT_TYPE" => "application/json"
363
+ assert_raises(Committee::BadRequest) do
364
+ assert_request_schema_confirm(except: { body: ['required_string'] })
365
+ end
366
+ end
367
+ end
368
+
369
+ describe "error recovery" do
370
+ it "restores partially-applied params when JSON body parsing raises mid-apply" do
371
+ # Scenario: HeaderHandler injects a dummy header, then BodyHandler fails
372
+ # to parse an invalid JSON body (JSON::ParserError). With apply() outside
373
+ # the ensure block the injected header would not be restored. This test
374
+ # verifies that all side-effects from apply() are rolled back even when
375
+ # apply() itself raises.
376
+ @app = new_rack_app
377
+ post "/test_except_body_params", 'invalid-json', { "CONTENT_TYPE" => "application/json" }
378
+
379
+ assert_nil last_request.env['HTTP_AUTHORIZATION']
380
+
381
+ assert_raises(JSON::ParserError) do
382
+ assert_request_schema_confirm(except: { headers: ['authorization'], body: ['required_string'] })
383
+ end
384
+
385
+ assert_nil last_request.env['HTTP_AUTHORIZATION']
386
+ end
387
+ end
388
+
389
+ end
390
+ end
172
391
  end
173
392
 
174
393
  describe "#assert_response_schema_confirm" do
@@ -227,122 +446,20 @@ describe Committee::Test::Methods do
227
446
  it 'records openapi coverage' do
228
447
  get "/posts"
229
448
  assert_response_schema_confirm(200)
230
- assert_equal({
231
- '/threads/{id}' => {
232
- 'get' => {
233
- 'responses' => {
234
- '200' => false,
235
- },
236
- },
237
- },
238
- '/posts' => {
239
- 'get' => {
240
- 'responses' => {
241
- '200' => true,
242
- '404' => false,
243
- 'default' => false,
244
- },
245
- },
246
- 'post' => {
247
- 'responses' => {
248
- '200' => false,
249
- },
250
- },
251
- },
252
- '/likes' => {
253
- 'post' => {
254
- 'responses' => {
255
- '200' => false,
256
- },
257
- },
258
- 'delete' => {
259
- 'responses' => {
260
- '200' => false,
261
- },
262
- },
263
- },
264
- }, @schema_coverage.report)
449
+ assert_equal({ '/threads/{id}' => { 'get' => { 'responses' => { '200' => false, }, }, }, '/posts' => { 'get' => { 'responses' => { '200' => true, '404' => false, 'default' => false, }, }, 'post' => { 'responses' => { '200' => false, }, }, }, '/likes' => { 'post' => { 'responses' => { '200' => false, }, }, 'delete' => { 'responses' => { '200' => false, }, }, }, }, @schema_coverage.report)
265
450
  end
266
451
 
267
452
  it 'can record openapi coverage correctly when prefix is set' do
268
453
  @committee_options.merge!(prefix: '/api')
269
454
  post "/api/likes"
270
455
  assert_response_schema_confirm(200)
271
- assert_equal({
272
- '/threads/{id}' => {
273
- 'get' => {
274
- 'responses' => {
275
- '200' => false,
276
- },
277
- },
278
- },
279
- '/posts' => {
280
- 'get' => {
281
- 'responses' => {
282
- '200' => false,
283
- '404' => false,
284
- 'default' => false,
285
- },
286
- },
287
- 'post' => {
288
- 'responses' => {
289
- '200' => false,
290
- },
291
- },
292
- },
293
- '/likes' => {
294
- 'post' => {
295
- 'responses' => {
296
- '200' => true,
297
- },
298
- },
299
- 'delete' => {
300
- 'responses' => {
301
- '200' => false,
302
- },
303
- },
304
- },
305
- }, @schema_coverage.report)
456
+ assert_equal({ '/threads/{id}' => { 'get' => { 'responses' => { '200' => false, }, }, }, '/posts' => { 'get' => { 'responses' => { '200' => false, '404' => false, 'default' => false, }, }, 'post' => { 'responses' => { '200' => false, }, }, }, '/likes' => { 'post' => { 'responses' => { '200' => true, }, }, 'delete' => { 'responses' => { '200' => false, }, }, }, }, @schema_coverage.report)
306
457
  end
307
458
 
308
459
  it 'records openapi coverage correctly with path param' do
309
460
  get "/threads/asd"
310
461
  assert_response_schema_confirm(200)
311
- assert_equal({
312
- '/threads/{id}' => {
313
- 'get' => {
314
- 'responses' => {
315
- '200' => true,
316
- },
317
- },
318
- },
319
- '/posts' => {
320
- 'get' => {
321
- 'responses' => {
322
- '200' => false,
323
- '404' => false,
324
- 'default' => false,
325
- },
326
- },
327
- 'post' => {
328
- 'responses' => {
329
- '200' => false,
330
- },
331
- },
332
- },
333
- '/likes' => {
334
- 'post' => {
335
- 'responses' => {
336
- '200' => false,
337
- },
338
- },
339
- 'delete' => {
340
- 'responses' => {
341
- '200' => false,
342
- },
343
- },
344
- },
345
- }, @schema_coverage.report)
462
+ assert_equal({ '/threads/{id}' => { 'get' => { 'responses' => { '200' => true, }, }, }, '/posts' => { 'get' => { 'responses' => { '200' => false, '404' => false, 'default' => false, }, }, 'post' => { 'responses' => { '200' => false, }, }, }, '/likes' => { 'post' => { 'responses' => { '200' => false, }, }, 'delete' => { 'responses' => { '200' => false, }, }, }, }, @schema_coverage.report)
346
463
  end
347
464
  end
348
465
  end
@@ -22,182 +22,35 @@ describe Committee::Test::SchemaCoverage do
22
22
  it 'can record and report coverage properly' do
23
23
  @schema_coverage.update_response_coverage!('/posts', 'get', '200')
24
24
  assert_equal(['/posts get 200',], covered_responses)
25
- assert_equal([
26
- '/threads/{id} get 200',
27
- '/posts get 404',
28
- '/posts get default',
29
- '/posts post 200',
30
- '/likes post 200',
31
- '/likes delete 200',
32
- ], uncovered_responses)
25
+ assert_equal(['/threads/{id} get 200', '/posts get 404', '/posts get default', '/posts post 200', '/likes post 200', '/likes delete 200',], uncovered_responses)
33
26
 
34
27
  @schema_coverage.update_response_coverage!('/likes', 'post', '200')
35
28
  assert_equal(['/posts get 200', '/likes post 200',], covered_responses)
36
- assert_equal([
37
- '/threads/{id} get 200',
38
- '/posts get 404',
39
- '/posts get default',
40
- '/posts post 200',
41
- '/likes delete 200',
42
- ], uncovered_responses)
29
+ assert_equal(['/threads/{id} get 200', '/posts get 404', '/posts get default', '/posts post 200', '/likes delete 200',], uncovered_responses)
43
30
 
44
31
  @schema_coverage.update_response_coverage!('/likes', 'delete', '200')
45
32
  assert_equal(['/posts get 200', '/likes post 200', '/likes delete 200',], covered_responses)
46
- assert_equal([
47
- '/threads/{id} get 200',
48
- '/posts get 404',
49
- '/posts get default',
50
- '/posts post 200',
51
- ], uncovered_responses)
33
+ assert_equal(['/threads/{id} get 200', '/posts get 404', '/posts get default', '/posts post 200',], uncovered_responses)
52
34
 
53
35
  @schema_coverage.update_response_coverage!('/posts', 'get', '422')
54
- assert_equal([
55
- '/posts get 200',
56
- '/posts get default',
57
- '/likes post 200',
58
- '/likes delete 200',
59
- ], covered_responses)
36
+ assert_equal(['/posts get 200', '/posts get default', '/likes post 200', '/likes delete 200',], covered_responses)
60
37
  assert_equal(['/threads/{id} get 200', '/posts get 404', '/posts post 200',], uncovered_responses)
61
38
 
62
- assert_equal({
63
- '/threads/{id}' => {
64
- 'get' => {
65
- 'responses' => {
66
- '200' => false,
67
- },
68
- },
69
- },
70
- '/posts' => {
71
- 'get' => {
72
- 'responses' => {
73
- '200' => true,
74
- '404' => false,
75
- 'default' => true,
76
- },
77
- },
78
- 'post' => {
79
- 'responses' => {
80
- '200' => false,
81
- },
82
- },
83
- },
84
- '/likes' => {
85
- 'post' => {
86
- 'responses' => {
87
- '200' => true,
88
- },
89
- },
90
- 'delete' => {
91
- 'responses' => {
92
- '200' => true,
93
- },
94
- },
95
- },
96
- }, @schema_coverage.report)
39
+ assert_equal({ '/threads/{id}' => { 'get' => { 'responses' => { '200' => false, }, }, }, '/posts' => { 'get' => { 'responses' => { '200' => true, '404' => false, 'default' => true, }, }, 'post' => { 'responses' => { '200' => false, }, }, }, '/likes' => { 'post' => { 'responses' => { '200' => true, }, }, 'delete' => { 'responses' => { '200' => true, }, }, }, }, @schema_coverage.report)
97
40
 
98
41
  @schema_coverage.update_response_coverage!('/posts', 'post', '200')
99
42
  @schema_coverage.update_response_coverage!('/posts', 'get', '404')
100
43
  @schema_coverage.update_response_coverage!('/threads/{id}', 'get', '200')
101
- assert_equal([
102
- '/threads/{id} get 200',
103
- '/posts get 200',
104
- '/posts get 404',
105
- '/posts get default',
106
- '/posts post 200',
107
- '/likes post 200',
108
- '/likes delete 200',
109
- ], covered_responses)
44
+ assert_equal(['/threads/{id} get 200', '/posts get 200', '/posts get 404', '/posts get default', '/posts post 200', '/likes post 200', '/likes delete 200',], covered_responses)
110
45
  assert_equal([], uncovered_responses)
111
46
  end
112
47
  end
113
48
 
114
49
  describe '.merge_report' do
115
50
  it 'can merge 2 coverage reports together' do
116
- report = Committee::Test::SchemaCoverage.merge_report(
117
- {
118
- '/posts' => {
119
- 'get' => {
120
- 'responses' => {
121
- '200' => true,
122
- '404' => false,
123
- },
124
- },
125
- 'post' => {
126
- 'responses' => {
127
- '200' => false,
128
- },
129
- },
130
- },
131
- '/likes' => {
132
- 'post' => {
133
- 'responses' => {
134
- '200' => true,
135
- },
136
- },
137
- },
138
- },
139
- {
140
- '/posts' => {
141
- 'get' => {
142
- 'responses' => {
143
- '200' => true,
144
- '404' => true,
145
- },
146
- },
147
- 'post' => {
148
- 'responses' => {
149
- '200' => false,
150
- },
151
- },
152
- },
153
- '/likes' => {
154
- 'post' => {
155
- 'responses' => {
156
- '200' => false,
157
- '400' => false,
158
- },
159
- },
160
- },
161
- '/users' => {
162
- 'get' => {
163
- 'responses' => {
164
- '200' => true,
165
- },
166
- },
167
- },
168
- },
169
- )
51
+ report = Committee::Test::SchemaCoverage.merge_report({ '/posts' => { 'get' => { 'responses' => { '200' => true, '404' => false, }, }, 'post' => { 'responses' => { '200' => false, }, }, }, '/likes' => { 'post' => { 'responses' => { '200' => true, }, }, }, }, { '/posts' => { 'get' => { 'responses' => { '200' => true, '404' => true, }, }, 'post' => { 'responses' => { '200' => false, }, }, }, '/likes' => { 'post' => { 'responses' => { '200' => false, '400' => false, }, }, }, '/users' => { 'get' => { 'responses' => { '200' => true, }, }, }, },)
170
52
 
171
- assert_equal({
172
- '/posts' => {
173
- 'get' => {
174
- 'responses' => {
175
- '200' => true,
176
- '404' => true,
177
- },
178
- },
179
- 'post' => {
180
- 'responses' => {
181
- '200' => false,
182
- },
183
- },
184
- },
185
- '/likes' => {
186
- 'post' => {
187
- 'responses' => {
188
- '200' => true,
189
- '400' => false,
190
- },
191
- },
192
- },
193
- '/users' => {
194
- 'get' => {
195
- 'responses' => {
196
- '200' => true,
197
- },
198
- },
199
- },
200
- }, report)
53
+ assert_equal({ '/posts' => { 'get' => { 'responses' => { '200' => true, '404' => true, }, }, 'post' => { 'responses' => { '200' => false, }, }, }, '/likes' => { 'post' => { 'responses' => { '200' => true, '400' => false, }, }, }, '/users' => { 'get' => { 'responses' => { '200' => true, }, }, }, }, report)
201
54
  end
202
55
  end
203
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: committee
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.1
4
+ version: 5.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandur
@@ -189,6 +189,10 @@ files:
189
189
  - lib/committee/errors.rb
190
190
  - lib/committee/middleware.rb
191
191
  - lib/committee/middleware/base.rb
192
+ - lib/committee/middleware/options.rb
193
+ - lib/committee/middleware/options/base.rb
194
+ - lib/committee/middleware/options/request_validation.rb
195
+ - lib/committee/middleware/options/response_validation.rb
192
196
  - lib/committee/middleware/request_validation.rb
193
197
  - lib/committee/middleware/response_validation.rb
194
198
  - lib/committee/middleware/stub.rb
@@ -203,10 +207,12 @@ files:
203
207
  - lib/committee/schema_validator/hyper_schema/string_params_coercer.rb
204
208
  - lib/committee/schema_validator/open_api_3.rb
205
209
  - lib/committee/schema_validator/open_api_3/operation_wrapper.rb
210
+ - lib/committee/schema_validator/open_api_3/parameter_deserializer.rb
206
211
  - lib/committee/schema_validator/open_api_3/request_validator.rb
207
212
  - lib/committee/schema_validator/open_api_3/response_validator.rb
208
213
  - lib/committee/schema_validator/open_api_3/router.rb
209
214
  - lib/committee/schema_validator/option.rb
215
+ - lib/committee/test/except_parameter.rb
210
216
  - lib/committee/test/methods.rb
211
217
  - lib/committee/test/schema_coverage.rb
212
218
  - lib/committee/utils.rb
@@ -224,6 +230,9 @@ files:
224
230
  - test/drivers/open_api_3/driver_test.rb
225
231
  - test/drivers_test.rb
226
232
  - test/middleware/base_test.rb
233
+ - test/middleware/options/base_test.rb
234
+ - test/middleware/options/request_validation_test.rb
235
+ - test/middleware/options/response_validation_test.rb
227
236
  - test/middleware/request_validation_open_api_3_test.rb
228
237
  - test/middleware/request_validation_test.rb
229
238
  - test/middleware/response_validation_open_api_3_test.rb
@@ -237,6 +246,7 @@ files:
237
246
  - test/schema_validator/hyper_schema/router_test.rb
238
247
  - test/schema_validator/hyper_schema/string_params_coercer_test.rb
239
248
  - test/schema_validator/open_api_3/operation_wrapper_test.rb
249
+ - test/schema_validator/open_api_3/parameter_deserializer_test.rb
240
250
  - test/schema_validator/open_api_3/request_validator_test.rb
241
251
  - test/schema_validator/open_api_3/response_validator_test.rb
242
252
  - test/schema_validator_test.rb
@@ -267,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
277
  - !ruby/object:Gem::Version
268
278
  version: '0'
269
279
  requirements: []
270
- rubygems_version: 3.6.9
280
+ rubygems_version: 4.0.3
271
281
  specification_version: 4
272
282
  summary: A collection of Rack middleware to support JSON Schema.
273
283
  test_files: []