committee 3.3.0 → 5.0.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/open_api_2/driver.rb +1 -2
 - data/lib/committee/drivers/open_api_2/parameter_schema_builder.rb +1 -1
 - data/lib/committee/drivers.rb +22 -10
 - data/lib/committee/errors.rb +12 -0
 - data/lib/committee/middleware/base.rb +5 -4
 - data/lib/committee/middleware/request_validation.rb +4 -18
 - data/lib/committee/middleware/response_validation.rb +15 -16
 - data/lib/committee/request_unpacker.rb +46 -60
 - data/lib/committee/schema_validator/hyper_schema/response_validator.rb +8 -2
 - data/lib/committee/schema_validator/hyper_schema.rb +41 -27
 - data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +44 -37
 - data/lib/committee/schema_validator/open_api_3/request_validator.rb +11 -2
 - data/lib/committee/schema_validator/open_api_3/router.rb +3 -1
 - data/lib/committee/schema_validator/open_api_3.rb +52 -26
 - data/lib/committee/schema_validator/option.rb +14 -3
 - data/lib/committee/schema_validator.rb +1 -1
 - data/lib/committee/test/methods.rb +27 -16
 - data/lib/committee/test/schema_coverage.rb +101 -0
 - data/lib/committee/utils.rb +28 -0
 - data/lib/committee/validation_error.rb +3 -2
 - data/lib/committee/version.rb +5 -0
 - data/lib/committee.rb +11 -4
 - data/test/bin/committee_stub_test.rb +5 -1
 - data/test/committee_test.rb +29 -3
 - data/test/drivers/open_api_3/driver_test.rb +1 -1
 - data/test/drivers_test.rb +20 -7
 - data/test/middleware/base_test.rb +9 -10
 - data/test/middleware/request_validation_open_api_3_test.rb +175 -18
 - data/test/middleware/request_validation_test.rb +20 -28
 - data/test/middleware/response_validation_open_api_3_test.rb +96 -7
 - data/test/middleware/response_validation_test.rb +21 -26
 - data/test/middleware/stub_test.rb +4 -0
 - data/test/request_unpacker_test.rb +51 -110
 - data/test/schema_validator/hyper_schema/response_validator_test.rb +10 -0
 - data/test/schema_validator/hyper_schema/router_test.rb +4 -0
 - data/test/schema_validator/hyper_schema/string_params_coercer_test.rb +1 -1
 - data/test/schema_validator/open_api_3/operation_wrapper_test.rb +72 -20
 - data/test/schema_validator/open_api_3/request_validator_test.rb +27 -0
 - data/test/schema_validator/open_api_3/response_validator_test.rb +26 -5
 - data/test/test/methods_new_version_test.rb +17 -5
 - data/test/test/methods_test.rb +155 -31
 - data/test/test/schema_coverage_test.rb +216 -0
 - data/test/test_helper.rb +34 -4
 - metadata +47 -15
 
| 
         @@ -34,11 +34,27 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       34 
34 
     | 
    
         
             
                params = { "datetime_string" => "2016-04-01T16:00:00.000+09:00" }
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                check_parameter = lambda { |env|
         
     | 
| 
      
 37 
     | 
    
         
            +
                  assert_equal DateTime, env['test.query_hash']["datetime_string"].class
         
     | 
| 
      
 38 
     | 
    
         
            +
                  assert_equal String, env['rack.request.query_hash']["datetime_string"].class
         
     | 
| 
      
 39 
     | 
    
         
            +
                  [200, {}, []]
         
     | 
| 
      
 40 
     | 
    
         
            +
                }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                @app = new_rack_app_with_lambda(check_parameter, schema: open_api_3_schema, coerce_date_times: true, query_hash_key: "test.query_hash")
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                get "/string_params_coercer", params
         
     | 
| 
      
 45 
     | 
    
         
            +
                assert_equal 200, last_response.status
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              it "passes given a datetime and with coerce_date_times enabled on GET endpoint overwrite query_hash" do
         
     | 
| 
      
 49 
     | 
    
         
            +
                params = { "datetime_string" => "2016-04-01T16:00:00.000+09:00" }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                check_parameter = lambda { |env|
         
     | 
| 
      
 52 
     | 
    
         
            +
                  assert_nil env['committee.query_hash']
         
     | 
| 
       37 
53 
     | 
    
         
             
                  assert_equal DateTime, env['rack.request.query_hash']["datetime_string"].class
         
     | 
| 
       38 
54 
     | 
    
         
             
                  [200, {}, []]
         
     | 
| 
       39 
55 
     | 
    
         
             
                }
         
     | 
| 
       40 
56 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                @app = new_rack_app_with_lambda(check_parameter, schema: open_api_3_schema, coerce_date_times: true)
         
     | 
| 
      
 57 
     | 
    
         
            +
                @app = new_rack_app_with_lambda(check_parameter, schema: open_api_3_schema, coerce_date_times: true, query_hash_key: "rack.request.query_hash")
         
     | 
| 
       42 
58 
     | 
    
         | 
| 
       43 
59 
     | 
    
         
             
                get "/string_params_coercer", params
         
     | 
| 
       44 
60 
     | 
    
         
             
                assert_equal 200, last_response.status
         
     | 
| 
         @@ -49,7 +65,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       49 
65 
     | 
    
         | 
| 
       50 
66 
     | 
    
         
             
                @app = new_rack_app(schema: open_api_3_schema, allow_get_body: true)
         
     | 
| 
       51 
67 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                get "/ 
     | 
| 
      
 68 
     | 
    
         
            +
                get "/get_endpoint_with_required_parameter", { no_problem: true }, { input: params.to_json }
         
     | 
| 
       53 
69 
     | 
    
         
             
                assert_equal 200, last_response.status
         
     | 
| 
       54 
70 
     | 
    
         
             
              end
         
     | 
| 
       55 
71 
     | 
    
         | 
| 
         @@ -58,7 +74,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       58 
74 
     | 
    
         | 
| 
       59 
75 
     | 
    
         
             
                @app = new_rack_app(schema: open_api_3_schema, allow_get_body: false)
         
     | 
| 
       60 
76 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
                get "/ 
     | 
| 
      
 77 
     | 
    
         
            +
                get "/get_endpoint_with_required_parameter", { no_problem: true }, { input: params.to_json }
         
     | 
| 
       62 
78 
     | 
    
         
             
                assert_equal 400, last_response.status
         
     | 
| 
       63 
79 
     | 
    
         
             
              end
         
     | 
| 
       64 
80 
     | 
    
         | 
| 
         @@ -154,7 +170,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       154 
170 
     | 
    
         
             
                }
         
     | 
| 
       155 
171 
     | 
    
         | 
| 
       156 
172 
     | 
    
         
             
                check_parameter = lambda { |env|
         
     | 
| 
       157 
     | 
    
         
            -
                  hash = env[ 
     | 
| 
      
 173 
     | 
    
         
            +
                  hash = env["committee.query_hash"]
         
     | 
| 
       158 
174 
     | 
    
         
             
                  assert_equal DateTime, hash['nested_array'].first['update_time'].class
         
     | 
| 
       159 
175 
     | 
    
         
             
                  assert_equal 1, hash['nested_array'].first['per_page']
         
     | 
| 
       160 
176 
     | 
    
         | 
| 
         @@ -249,8 +265,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       249 
265 
     | 
    
         
             
                }
         
     | 
| 
       250 
266 
     | 
    
         
             
                post "/characters", JSON.generate(params)
         
     | 
| 
       251 
267 
     | 
    
         
             
                assert_equal 400, last_response.status
         
     | 
| 
       252 
     | 
    
         
            -
                 
     | 
| 
       253 
     | 
    
         
            -
                assert_match(/expected string, but received #{1.class}:/i, last_response.body)
         
     | 
| 
      
 268 
     | 
    
         
            +
                assert_match(/expected string, but received Integer:/i, last_response.body)
         
     | 
| 
       254 
269 
     | 
    
         
             
              end
         
     | 
| 
       255 
270 
     | 
    
         | 
| 
       256 
271 
     | 
    
         
             
              it "rescues JSON errors" do
         
     | 
| 
         @@ -279,8 +294,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       279 
294 
     | 
    
         
             
                header "Content-Type", "application/json"
         
     | 
| 
       280 
295 
     | 
    
         
             
                post "/v1/characters", JSON.generate(params)
         
     | 
| 
       281 
296 
     | 
    
         
             
                assert_equal 400, last_response.status
         
     | 
| 
       282 
     | 
    
         
            -
                 
     | 
| 
       283 
     | 
    
         
            -
                assert_match(/expected string, but received #{1.class}: /i, last_response.body)
         
     | 
| 
      
 297 
     | 
    
         
            +
                assert_match(/expected string, but received Integer: /i, last_response.body)
         
     | 
| 
       284 
298 
     | 
    
         
             
              end
         
     | 
| 
       285 
299 
     | 
    
         | 
| 
       286 
300 
     | 
    
         
             
              it "ignores paths outside the prefix" do
         
     | 
| 
         @@ -333,7 +347,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       333 
347 
     | 
    
         
             
                  get "/coerce_path_params/#{not_an_integer}", nil
         
     | 
| 
       334 
348 
     | 
    
         
             
                end
         
     | 
| 
       335 
349 
     | 
    
         | 
| 
       336 
     | 
    
         
            -
                assert_match(/expected integer, but received String: abc/i, e.message)
         
     | 
| 
      
 350 
     | 
    
         
            +
                assert_match(/expected integer, but received String: \"abc\"/i, e.message)
         
     | 
| 
       337 
351 
     | 
    
         
             
              end
         
     | 
| 
       338 
352 
     | 
    
         | 
| 
       339 
353 
     | 
    
         
             
              it "optionally raises an error" do
         
     | 
| 
         @@ -362,7 +376,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       362 
376 
     | 
    
         | 
| 
       363 
377 
     | 
    
         
             
              it "passes through a valid request for OpenAPI3" do
         
     | 
| 
       364 
378 
     | 
    
         
             
                check_parameter = lambda { |env|
         
     | 
| 
       365 
     | 
    
         
            -
                  assert_equal 3, env[' 
     | 
| 
      
 379 
     | 
    
         
            +
                  assert_equal 3, env['committee.query_hash']['limit'] #5.0.x-
         
     | 
| 
       366 
380 
     | 
    
         
             
                  [200, {}, []]
         
     | 
| 
       367 
381 
     | 
    
         
             
                }
         
     | 
| 
       368 
382 
     | 
    
         | 
| 
         @@ -376,7 +390,7 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       376 
390 
     | 
    
         
             
                get "/characters?limit=foo"
         
     | 
| 
       377 
391 
     | 
    
         | 
| 
       378 
392 
     | 
    
         
             
                assert_equal 400, last_response.status
         
     | 
| 
       379 
     | 
    
         
            -
                assert_match(/expected integer, but received String: foo/i, last_response.body)
         
     | 
| 
      
 393 
     | 
    
         
            +
                assert_match(/expected integer, but received String: \\"foo\\"/i, last_response.body)
         
     | 
| 
       380 
394 
     | 
    
         
             
              end
         
     | 
| 
       381 
395 
     | 
    
         | 
| 
       382 
396 
     | 
    
         
             
              it "ignores errors when ignore_error: true" do
         
     | 
| 
         @@ -396,28 +410,155 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       396 
410 
     | 
    
         
             
                get "/coerce_path_params/1"
         
     | 
| 
       397 
411 
     | 
    
         
             
              end
         
     | 
| 
       398 
412 
     | 
    
         | 
| 
      
 413 
     | 
    
         
            +
              describe "overwrite same parameter (old rule)" do
         
     | 
| 
      
 414 
     | 
    
         
            +
                # (high priority) path_hash_key -> request_body_hash -> query_param
         
     | 
| 
      
 415 
     | 
    
         
            +
                it "set query parameter to committee.params and query hash" do
         
     | 
| 
      
 416 
     | 
    
         
            +
                  @app = new_rack_app_with_lambda(lambda do |env|
         
     | 
| 
      
 417 
     | 
    
         
            +
                    assert_equal env['committee.params']['integer'], 42
         
     | 
| 
      
 418 
     | 
    
         
            +
                    assert_equal env['committee.params'][:integer], 42
         
     | 
| 
      
 419 
     | 
    
         
            +
                    assert_equal env['committee.query_hash']['integer'], 42
         
     | 
| 
      
 420 
     | 
    
         
            +
                    #assert_equal env['rack.request.query_hash'][:integer], 42 # this isn't hash indifferent hash because we use rack.request.query_hash
         
     | 
| 
      
 421 
     | 
    
         
            +
                    [204, {}, []]
         
     | 
| 
      
 422 
     | 
    
         
            +
                  end, schema: open_api_3_schema, parameter_overwite_by_rails_rule: false)
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
                  header "Content-Type", "application/json"
         
     | 
| 
      
 425 
     | 
    
         
            +
                  post '/overwrite_same_parameter?integer=42'
         
     | 
| 
      
 426 
     | 
    
         
            +
                  assert_equal 204, last_response.status
         
     | 
| 
      
 427 
     | 
    
         
            +
                end
         
     | 
| 
      
 428 
     | 
    
         
            +
             
     | 
| 
      
 429 
     | 
    
         
            +
                it "request body precedence over query parameter" do
         
     | 
| 
      
 430 
     | 
    
         
            +
                  @app = new_rack_app_with_lambda(lambda do |env|
         
     | 
| 
      
 431 
     | 
    
         
            +
                    assert_equal env['committee.params']['integer'], 21
         
     | 
| 
      
 432 
     | 
    
         
            +
                    assert_equal env['committee.params'][:integer], 21
         
     | 
| 
      
 433 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash']['integer'], 21
         
     | 
| 
      
 434 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash'][:integer], 21
         
     | 
| 
      
 435 
     | 
    
         
            +
                    assert_equal env['committee.query_hash']['integer'], 42
         
     | 
| 
      
 436 
     | 
    
         
            +
                    [204, {}, []]
         
     | 
| 
      
 437 
     | 
    
         
            +
                  end, schema: open_api_3_schema, parameter_overwite_by_rails_rule: false)
         
     | 
| 
      
 438 
     | 
    
         
            +
             
     | 
| 
      
 439 
     | 
    
         
            +
                  params = {integer: 21}
         
     | 
| 
      
 440 
     | 
    
         
            +
             
     | 
| 
      
 441 
     | 
    
         
            +
                  header "Content-Type", "application/json"
         
     | 
| 
      
 442 
     | 
    
         
            +
                  post '/overwrite_same_parameter?integer=42', JSON.generate(params)
         
     | 
| 
      
 443 
     | 
    
         
            +
                  assert_equal 204, last_response.status
         
     | 
| 
      
 444 
     | 
    
         
            +
                end
         
     | 
| 
      
 445 
     | 
    
         
            +
             
     | 
| 
      
 446 
     | 
    
         
            +
                it "path parameter precedence over request body" do
         
     | 
| 
      
 447 
     | 
    
         
            +
                  @app = new_rack_app_with_lambda(lambda do |env|
         
     | 
| 
      
 448 
     | 
    
         
            +
                    assert_equal env['committee.params']['integer'], 84
         
     | 
| 
      
 449 
     | 
    
         
            +
                    assert_equal env['committee.params'][:integer], 84
         
     | 
| 
      
 450 
     | 
    
         
            +
                    assert_equal env['committee.path_hash']['integer'], 84
         
     | 
| 
      
 451 
     | 
    
         
            +
                    assert_equal env['committee.path_hash'][:integer], 84
         
     | 
| 
      
 452 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash']['integer'], 21
         
     | 
| 
      
 453 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash'][:integer], 21
         
     | 
| 
      
 454 
     | 
    
         
            +
                    assert_equal env['committee.query_hash']['integer'], 84 # we can't use query_parameter :(
         
     | 
| 
      
 455 
     | 
    
         
            +
                    #assert_equal env['rack.request.query_hash'][:integer], 21 # this isn't hash indifferent hash because we use rack.request.query_hash
         
     | 
| 
      
 456 
     | 
    
         
            +
                    [204, {}, []]
         
     | 
| 
      
 457 
     | 
    
         
            +
                  end, schema: open_api_3_schema, parameter_overwite_by_rails_rule: false)
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
                  params = {integer: 21}
         
     | 
| 
      
 460 
     | 
    
         
            +
             
     | 
| 
      
 461 
     | 
    
         
            +
                  header "Content-Type", "application/json"
         
     | 
| 
      
 462 
     | 
    
         
            +
                  post '/overwrite_same_parameter/84?integer=42', JSON.generate(params)
         
     | 
| 
      
 463 
     | 
    
         
            +
                  assert_equal 204, last_response.status
         
     | 
| 
      
 464 
     | 
    
         
            +
                end
         
     | 
| 
      
 465 
     | 
    
         
            +
              end
         
     | 
| 
      
 466 
     | 
    
         
            +
             
     | 
| 
      
 467 
     | 
    
         
            +
              describe "overwrite same parameter (new rule and seme to Rails)" do
         
     | 
| 
      
 468 
     | 
    
         
            +
                # (high priority) path_hash_key -> query_param -> request_body_hash
         
     | 
| 
      
 469 
     | 
    
         
            +
                it "set request body to committee.params and query hash" do
         
     | 
| 
      
 470 
     | 
    
         
            +
                  @app = new_rack_app_with_lambda(lambda do |env|
         
     | 
| 
      
 471 
     | 
    
         
            +
                    assert_equal env['committee.params']['integer'], 21
         
     | 
| 
      
 472 
     | 
    
         
            +
                    assert_equal env['committee.params'][:integer], 21
         
     | 
| 
      
 473 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash']['integer'], 21
         
     | 
| 
      
 474 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash'][:integer], 21
         
     | 
| 
      
 475 
     | 
    
         
            +
                    [204, {}, []]
         
     | 
| 
      
 476 
     | 
    
         
            +
                  end, schema: open_api_3_schema)
         
     | 
| 
      
 477 
     | 
    
         
            +
             
     | 
| 
      
 478 
     | 
    
         
            +
                  params = {integer: 21}
         
     | 
| 
      
 479 
     | 
    
         
            +
             
     | 
| 
      
 480 
     | 
    
         
            +
                  header "Content-Type", "application/json"
         
     | 
| 
      
 481 
     | 
    
         
            +
                  post '/overwrite_same_parameter', JSON.generate(params)
         
     | 
| 
      
 482 
     | 
    
         
            +
                  assert_equal 204, last_response.status
         
     | 
| 
      
 483 
     | 
    
         
            +
                end
         
     | 
| 
      
 484 
     | 
    
         
            +
             
     | 
| 
      
 485 
     | 
    
         
            +
                it "query parameter precedence over request body" do
         
     | 
| 
      
 486 
     | 
    
         
            +
                  @app = new_rack_app_with_lambda(lambda do |env|
         
     | 
| 
      
 487 
     | 
    
         
            +
                    assert_equal env['committee.params']['integer'], 42
         
     | 
| 
      
 488 
     | 
    
         
            +
                    assert_equal env['committee.params'][:integer], 42
         
     | 
| 
      
 489 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash']['integer'], 21
         
     | 
| 
      
 490 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash'][:integer], 21
         
     | 
| 
      
 491 
     | 
    
         
            +
                    assert_equal env['committee.query_hash']['integer'], 42
         
     | 
| 
      
 492 
     | 
    
         
            +
                    [204, {}, []]
         
     | 
| 
      
 493 
     | 
    
         
            +
                  end, schema: open_api_3_schema)
         
     | 
| 
      
 494 
     | 
    
         
            +
             
     | 
| 
      
 495 
     | 
    
         
            +
                  params = {integer: 21}
         
     | 
| 
      
 496 
     | 
    
         
            +
             
     | 
| 
      
 497 
     | 
    
         
            +
                  header "Content-Type", "application/json"
         
     | 
| 
      
 498 
     | 
    
         
            +
                  post '/overwrite_same_parameter?integer=42', JSON.generate(params)
         
     | 
| 
      
 499 
     | 
    
         
            +
                  assert_equal 204, last_response.status
         
     | 
| 
      
 500 
     | 
    
         
            +
                end
         
     | 
| 
      
 501 
     | 
    
         
            +
             
     | 
| 
      
 502 
     | 
    
         
            +
                it "path path parameter precedence over query parameter" do
         
     | 
| 
      
 503 
     | 
    
         
            +
                  @app = new_rack_app_with_lambda(lambda do |env|
         
     | 
| 
      
 504 
     | 
    
         
            +
                    assert_equal env['committee.params']['integer'], 84
         
     | 
| 
      
 505 
     | 
    
         
            +
                    assert_equal env['committee.params'][:integer], 84
         
     | 
| 
      
 506 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash']['integer'], 21
         
     | 
| 
      
 507 
     | 
    
         
            +
                    assert_equal env['committee.request_body_hash'][:integer], 21
         
     | 
| 
      
 508 
     | 
    
         
            +
                    assert_equal env['committee.query_hash']['integer'], 84 # we can't use query_parameter :(
         
     | 
| 
      
 509 
     | 
    
         
            +
                    assert_equal env['committee.path_hash']['integer'], 84
         
     | 
| 
      
 510 
     | 
    
         
            +
                    assert_equal env['committee.path_hash'][:integer], 84
         
     | 
| 
      
 511 
     | 
    
         
            +
                    [204, {}, []]
         
     | 
| 
      
 512 
     | 
    
         
            +
                  end, schema: open_api_3_schema)
         
     | 
| 
      
 513 
     | 
    
         
            +
             
     | 
| 
      
 514 
     | 
    
         
            +
                  params = {integer: 21}
         
     | 
| 
      
 515 
     | 
    
         
            +
             
     | 
| 
      
 516 
     | 
    
         
            +
                  header "Content-Type", "application/json"
         
     | 
| 
      
 517 
     | 
    
         
            +
                  post '/overwrite_same_parameter/84?integer=42', JSON.generate(params)
         
     | 
| 
      
 518 
     | 
    
         
            +
                  assert_equal 204, last_response.status
         
     | 
| 
      
 519 
     | 
    
         
            +
                end
         
     | 
| 
      
 520 
     | 
    
         
            +
              end
         
     | 
| 
      
 521 
     | 
    
         
            +
             
     | 
| 
      
 522 
     | 
    
         
            +
              it "unpacker test" do
         
     | 
| 
      
 523 
     | 
    
         
            +
                @app = new_rack_app_with_lambda(lambda do |env|
         
     | 
| 
      
 524 
     | 
    
         
            +
                  assert_equal '21', env['committee.params']['integer'] # query parameter has precedence
         
     | 
| 
      
 525 
     | 
    
         
            +
                  assert_equal '21', env['committee.params'][:integer]
         
     | 
| 
      
 526 
     | 
    
         
            +
                  assert_equal '21', env['rack.request.query_hash']['integer']
         
     | 
| 
      
 527 
     | 
    
         
            +
                  assert_equal 42, env['committee.request_body_hash']['integer']
         
     | 
| 
      
 528 
     | 
    
         
            +
                  [204, {}, []]
         
     | 
| 
      
 529 
     | 
    
         
            +
                end, schema: open_api_3_schema, raise: true)
         
     | 
| 
      
 530 
     | 
    
         
            +
             
     | 
| 
      
 531 
     | 
    
         
            +
                header "Content-Type", "application/x-www-form-urlencoded"
         
     | 
| 
      
 532 
     | 
    
         
            +
                post '/validate?integer=21', "integer=42"
         
     | 
| 
      
 533 
     | 
    
         
            +
                assert_equal 204, last_response.status
         
     | 
| 
      
 534 
     | 
    
         
            +
              end
         
     | 
| 
      
 535 
     | 
    
         
            +
             
     | 
| 
       399 
536 
     | 
    
         
             
              it "OpenAPI3 raise not support method" do
         
     | 
| 
       400 
537 
     | 
    
         
             
                @app = new_rack_app(schema: open_api_3_schema)
         
     | 
| 
       401 
538 
     | 
    
         | 
| 
       402 
539 
     | 
    
         
             
                e = assert_raises(RuntimeError) {
         
     | 
| 
       403 
     | 
    
         
            -
                   
     | 
| 
      
 540 
     | 
    
         
            +
                  custom_request('TRACE', "/characters")
         
     | 
| 
       404 
541 
     | 
    
         
             
                }
         
     | 
| 
       405 
542 
     | 
    
         | 
| 
       406 
     | 
    
         
            -
                assert_equal 'Committee OpenAPI3 not support  
     | 
| 
       407 
     | 
    
         
            -
              end
         
     | 
| 
      
 543 
     | 
    
         
            +
                assert_equal 'Committee OpenAPI3 not support trace method', e.message
         
     | 
| 
      
 544 
     | 
    
         
            +
              end  
         
     | 
| 
       408 
545 
     | 
    
         | 
| 
       409 
546 
     | 
    
         
             
              describe 'check header' do
         
     | 
| 
       410 
547 
     | 
    
         
             
                [
         
     | 
| 
       411 
548 
     | 
    
         
             
                  { check_header: true, description: 'valid value', value: 1, expected: { status: 200 } },
         
     | 
| 
       412 
549 
     | 
    
         
             
                  { check_header: true, description: 'missing value', value: nil, expected: { status: 400, error: 'missing required parameters: integer' } },
         
     | 
| 
       413 
     | 
    
         
            -
                  { check_header: true, description: 'invalid value', value: 'x', expected: { status: 400, error: 'expected integer, but received String: x' } },
         
     | 
| 
      
 550 
     | 
    
         
            +
                  { check_header: true, description: 'invalid value', value: 'x', expected: { status: 400, error: 'expected integer, but received String: \\"x\\"' } },
         
     | 
| 
       414 
551 
     | 
    
         | 
| 
       415 
552 
     | 
    
         
             
                  { check_header: false, description: 'valid value', value: 1, expected: { status: 200 } },
         
     | 
| 
       416 
553 
     | 
    
         
             
                  { check_header: false, description: 'missing value', value: nil, expected: { status: 200 } },
         
     | 
| 
       417 
554 
     | 
    
         
             
                  { check_header: false, description: 'invalid value', value: 'x', expected: { status: 200 } },
         
     | 
| 
       418 
     | 
    
         
            -
                ].each do | 
     | 
| 
      
 555 
     | 
    
         
            +
                ].each do |h|
         
     | 
| 
      
 556 
     | 
    
         
            +
                  check_header = h[:check_header]
         
     | 
| 
      
 557 
     | 
    
         
            +
                  description = h[:description]
         
     | 
| 
      
 558 
     | 
    
         
            +
                  value = h[:value]
         
     | 
| 
      
 559 
     | 
    
         
            +
                  expected = h[:expected]
         
     | 
| 
       419 
560 
     | 
    
         
             
                  describe "when #{check_header}" do
         
     | 
| 
       420 
     | 
    
         
            -
                    %w(get post put patch delete).each do |method|
         
     | 
| 
      
 561 
     | 
    
         
            +
                    %w(get post put patch delete options).each do |method|
         
     | 
| 
       421 
562 
     | 
    
         
             
                      describe method do
         
     | 
| 
       422 
563 
     | 
    
         
             
                        describe description do
         
     | 
| 
       423 
564 
     | 
    
         
             
                          it (expected[:error].nil? ? 'should pass' : 'should fail') do
         
     | 
| 
         @@ -441,7 +582,10 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       441 
582 
     | 
    
         
             
                  { description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 400 } },
         
     | 
| 
       442 
583 
     | 
    
         
             
                  { description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/c') }, expected: { status: 400 } },
         
     | 
| 
       443 
584 
     | 
    
         
             
                  { description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
         
     | 
| 
       444 
     | 
    
         
            -
                ].each do | 
     | 
| 
      
 585 
     | 
    
         
            +
                ].each do |h|
         
     | 
| 
      
 586 
     | 
    
         
            +
                  description = h[:description]
         
     | 
| 
      
 587 
     | 
    
         
            +
                  accept_request_filter = h[:accept_request_filter]
         
     | 
| 
      
 588 
     | 
    
         
            +
                  expected = h[:expected]
         
     | 
| 
       445 
589 
     | 
    
         
             
                  it description do
         
     | 
| 
       446 
590 
     | 
    
         
             
                    @app = new_rack_app(prefix: '/v1', schema: open_api_3_schema, accept_request_filter: accept_request_filter)
         
     | 
| 
       447 
591 
     | 
    
         | 
| 
         @@ -452,6 +596,16 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       452 
596 
     | 
    
         
             
                end
         
     | 
| 
       453 
597 
     | 
    
         
             
              end
         
     | 
| 
       454 
598 
     | 
    
         | 
| 
      
 599 
     | 
    
         
            +
              it 'does not suppress application error' do
         
     | 
| 
      
 600 
     | 
    
         
            +
                @app = new_rack_app_with_lambda(lambda { |_|
         
     | 
| 
      
 601 
     | 
    
         
            +
                  JSON.load('-') # invalid json
         
     | 
| 
      
 602 
     | 
    
         
            +
                }, schema: open_api_3_schema, raise: true)
         
     | 
| 
      
 603 
     | 
    
         
            +
             
     | 
| 
      
 604 
     | 
    
         
            +
                assert_raises(JSON::ParserError) do
         
     | 
| 
      
 605 
     | 
    
         
            +
                  get "/error", nil
         
     | 
| 
      
 606 
     | 
    
         
            +
                end
         
     | 
| 
      
 607 
     | 
    
         
            +
              end
         
     | 
| 
      
 608 
     | 
    
         
            +
             
     | 
| 
       455 
609 
     | 
    
         
             
              private
         
     | 
| 
       456 
610 
     | 
    
         | 
| 
       457 
611 
     | 
    
         
             
              def new_rack_app(options = {})
         
     | 
| 
         @@ -461,6 +615,9 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       461 
615 
     | 
    
         
             
              end
         
     | 
| 
       462 
616 
     | 
    
         | 
| 
       463 
617 
     | 
    
         
             
              def new_rack_app_with_lambda(check_lambda, options = {})
         
     | 
| 
      
 618 
     | 
    
         
            +
                # TODO: delete when 5.0.0 released because default value changed
         
     | 
| 
      
 619 
     | 
    
         
            +
                options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
         
     | 
| 
      
 620 
     | 
    
         
            +
             
     | 
| 
       464 
621 
     | 
    
         
             
                Rack::Builder.new {
         
     | 
| 
       465 
622 
     | 
    
         
             
                  use Committee::Middleware::RequestValidation, options
         
     | 
| 
       466 
623 
     | 
    
         
             
                  run check_lambda
         
     | 
| 
         @@ -306,21 +306,6 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       306 
306 
     | 
    
         
             
                assert_equal 200, last_response.status
         
     | 
| 
       307 
307 
     | 
    
         
             
              end
         
     | 
| 
       308 
308 
     | 
    
         | 
| 
       309 
     | 
    
         
            -
              it "calls error_handler (has a arg) when request is invalid" do
         
     | 
| 
       310 
     | 
    
         
            -
                called_err = nil
         
     | 
| 
       311 
     | 
    
         
            -
                pr = ->(e) { called_err = e }
         
     | 
| 
       312 
     | 
    
         
            -
                @app = new_rack_app(schema: hyper_schema, error_handler: pr)
         
     | 
| 
       313 
     | 
    
         
            -
                header "Content-Type", "application/json"
         
     | 
| 
       314 
     | 
    
         
            -
                params = {
         
     | 
| 
       315 
     | 
    
         
            -
                  "name" => 1
         
     | 
| 
       316 
     | 
    
         
            -
                }
         
     | 
| 
       317 
     | 
    
         
            -
                _, err = capture_io do
         
     | 
| 
       318 
     | 
    
         
            -
                  post "/apps", JSON.generate(params)
         
     | 
| 
       319 
     | 
    
         
            -
                end
         
     | 
| 
       320 
     | 
    
         
            -
                assert_kind_of Committee::InvalidRequest, called_err
         
     | 
| 
       321 
     | 
    
         
            -
                assert_match(/\[DEPRECATION\]/i, err)
         
     | 
| 
       322 
     | 
    
         
            -
              end
         
     | 
| 
       323 
     | 
    
         
            -
             
     | 
| 
       324 
309 
     | 
    
         
             
              it "calls error_handler (has two args) when request is invalid" do
         
     | 
| 
       325 
310 
     | 
    
         
             
                called_err = nil
         
     | 
| 
       326 
311 
     | 
    
         
             
                pr = ->(e, _env) { called_err = e }
         
     | 
| 
         @@ -341,18 +326,6 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       341 
326 
     | 
    
         
             
                assert_match(/valid json/i, last_response.body)
         
     | 
| 
       342 
327 
     | 
    
         
             
              end
         
     | 
| 
       343 
328 
     | 
    
         | 
| 
       344 
     | 
    
         
            -
              it "calls error_handler (has a arg) when it rescues JSON errors" do
         
     | 
| 
       345 
     | 
    
         
            -
                called_err = nil
         
     | 
| 
       346 
     | 
    
         
            -
                pr = ->(e) { called_err = e }
         
     | 
| 
       347 
     | 
    
         
            -
                @app = new_rack_app(schema: hyper_schema, error_handler: pr)
         
     | 
| 
       348 
     | 
    
         
            -
                header "Content-Type", "application/json"
         
     | 
| 
       349 
     | 
    
         
            -
                _, err = capture_io do
         
     | 
| 
       350 
     | 
    
         
            -
                  post "/apps", "{x:y}"
         
     | 
| 
       351 
     | 
    
         
            -
                end
         
     | 
| 
       352 
     | 
    
         
            -
                assert_kind_of JSON::ParserError, called_err
         
     | 
| 
       353 
     | 
    
         
            -
                assert_match(/\[DEPRECATION\]/i, err)
         
     | 
| 
       354 
     | 
    
         
            -
              end
         
     | 
| 
       355 
     | 
    
         
            -
             
     | 
| 
       356 
329 
     | 
    
         
             
              it "calls error_handler (has two args) when it rescues JSON errors" do
         
     | 
| 
       357 
330 
     | 
    
         
             
                called_err = nil
         
     | 
| 
       358 
331 
     | 
    
         
             
                pr = ->(e, _env) { called_err = e }
         
     | 
| 
         @@ -435,6 +408,19 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       435 
408 
     | 
    
         
             
                assert_equal 200, last_response.status
         
     | 
| 
       436 
409 
     | 
    
         
             
              end
         
     | 
| 
       437 
410 
     | 
    
         | 
| 
      
 411 
     | 
    
         
            +
              it "coerce form params" do
         
     | 
| 
      
 412 
     | 
    
         
            +
                check_parameter = lambda { |env|
         
     | 
| 
      
 413 
     | 
    
         
            +
                  assert_equal 3, env['committee.params']['age']
         
     | 
| 
      
 414 
     | 
    
         
            +
                  assert_equal 3, env['committee.request_body_hash']['age']
         
     | 
| 
      
 415 
     | 
    
         
            +
                  [200, {}, []]
         
     | 
| 
      
 416 
     | 
    
         
            +
                }
         
     | 
| 
      
 417 
     | 
    
         
            +
             
     | 
| 
      
 418 
     | 
    
         
            +
                @app = new_rack_app_with_lambda(check_parameter, schema: open_api_2_form_schema, raise: true, allow_form_params: true, coerce_form_params: true)
         
     | 
| 
      
 419 
     | 
    
         
            +
                header "Content-Type", "application/x-www-form-urlencoded"
         
     | 
| 
      
 420 
     | 
    
         
            +
                post "/api/pets", "age=3&name=ab"
         
     | 
| 
      
 421 
     | 
    
         
            +
                assert_equal 200, last_response.status
         
     | 
| 
      
 422 
     | 
    
         
            +
              end
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
       438 
424 
     | 
    
         
             
              it "detects an invalid request for OpenAPI" do
         
     | 
| 
       439 
425 
     | 
    
         
             
                @app = new_rack_app(schema: open_api_2_schema)
         
     | 
| 
       440 
426 
     | 
    
         
             
                get "/api/pets?limit=foo", nil, { "HTTP_AUTH_TOKEN" => "xxx" }
         
     | 
| 
         @@ -495,7 +481,10 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       495 
481 
     | 
    
         
             
                  { description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 400 } },
         
     | 
| 
       496 
482 
     | 
    
         
             
                  { description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/a') }, expected: { status: 400 } },
         
     | 
| 
       497 
483 
     | 
    
         
             
                  { description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
         
     | 
| 
       498 
     | 
    
         
            -
                ].each do | 
     | 
| 
      
 484 
     | 
    
         
            +
                ].each do |h|
         
     | 
| 
      
 485 
     | 
    
         
            +
                  description = h[:description]
         
     | 
| 
      
 486 
     | 
    
         
            +
                  accept_request_filter = h[:accept_request_filter]
         
     | 
| 
      
 487 
     | 
    
         
            +
                  expected = h[:expected]
         
     | 
| 
       499 
488 
     | 
    
         
             
                  it description do
         
     | 
| 
       500 
489 
     | 
    
         
             
                    @app = new_rack_app(prefix: '/v1', schema: hyper_schema, accept_request_filter: accept_request_filter)
         
     | 
| 
       501 
490 
     | 
    
         | 
| 
         @@ -516,6 +505,9 @@ describe Committee::Middleware::RequestValidation do 
     | 
|
| 
       516 
505 
     | 
    
         | 
| 
       517 
506 
     | 
    
         | 
| 
       518 
507 
     | 
    
         
             
              def new_rack_app_with_lambda(check_lambda, options = {})
         
     | 
| 
      
 508 
     | 
    
         
            +
                # TODO: delete when 5.0.0 released because default value changed
         
     | 
| 
      
 509 
     | 
    
         
            +
                options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
         
     | 
| 
      
 510 
     | 
    
         
            +
             
     | 
| 
       519 
511 
     | 
    
         
             
                Rack::Builder.new {
         
     | 
| 
       520 
512 
     | 
    
         
             
                  use Committee::Middleware::RequestValidation, options
         
     | 
| 
       521 
513 
     | 
    
         
             
                  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"
         
     | 
| 
         @@ -56,6 +64,12 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       56 
64 
     | 
    
         
             
                assert_equal 204, last_response.status
         
     | 
| 
       57 
65 
     | 
    
         
             
              end
         
     | 
| 
       58 
66 
     | 
    
         | 
| 
      
 67 
     | 
    
         
            +
              it "passes through a 304 (not modified) response" do
         
     | 
| 
      
 68 
     | 
    
         
            +
                @app = new_response_rack("", {}, {schema: open_api_3_schema}, {status: 304})
         
     | 
| 
      
 69 
     | 
    
         
            +
                post "/validate"
         
     | 
| 
      
 70 
     | 
    
         
            +
                assert_equal 304, last_response.status
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
       59 
73 
     | 
    
         
             
              it "passes through a valid response with prefix" do
         
     | 
| 
       60 
74 
     | 
    
         
             
                @app = new_response_rack(JSON.generate(CHARACTERS_RESPONSE), {}, schema: open_api_3_schema, prefix: "/v1")
         
     | 
| 
       61 
75 
     | 
    
         
             
                get "/v1/characters"
         
     | 
| 
         @@ -78,7 +92,7 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       78 
92 
     | 
    
         
             
                end
         
     | 
| 
       79 
93 
     | 
    
         
             
              end
         
     | 
| 
       80 
94 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
              it "not parameter  
     | 
| 
      
 95 
     | 
    
         
            +
              it "not parameter request" do
         
     | 
| 
       82 
96 
     | 
    
         
             
                @app = new_response_rack({integer: '1'}.to_json, {}, schema: open_api_3_schema, raise: true)
         
     | 
| 
       83 
97 
     | 
    
         | 
| 
       84 
98 
     | 
    
         
             
                assert_raises(Committee::InvalidResponse) do
         
     | 
| 
         @@ -99,18 +113,36 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       99 
113 
     | 
    
         
             
                assert_match(/valid JSON/i, last_response.body)
         
     | 
| 
       100 
114 
     | 
    
         
             
              end
         
     | 
| 
       101 
115 
     | 
    
         | 
| 
      
 116 
     | 
    
         
            +
              describe "remote schema $ref" do
         
     | 
| 
      
 117 
     | 
    
         
            +
                it "passes through a valid response" do
         
     | 
| 
      
 118 
     | 
    
         
            +
                  @app = new_response_rack(JSON.generate({ "sample" => "value" }), {}, schema: open_api_3_schema)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  get "/ref-sample"
         
     | 
| 
      
 120 
     | 
    
         
            +
                  assert_equal 200, last_response.status
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                it "detects a invalid response" do
         
     | 
| 
      
 124 
     | 
    
         
            +
                  @app = new_response_rack("{}", {}, schema: open_api_3_schema)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  get "/ref-sample"
         
     | 
| 
      
 126 
     | 
    
         
            +
                  assert_equal 500, last_response.status
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
              end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
       102 
130 
     | 
    
         
             
              describe 'check header' do
         
     | 
| 
       103 
131 
     | 
    
         
             
                [
         
     | 
| 
       104 
132 
     | 
    
         
             
                  { check_header: true, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
         
     | 
| 
       105 
133 
     | 
    
         
             
                  { 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' } },
         
     | 
| 
      
 134 
     | 
    
         
            +
                  { check_header: true, description: 'invalid value', header: { 'integer' => 'x' }, expected: { error: 'headers/integer/schema expected integer, but received String: "x"' } },
         
     | 
| 
       107 
135 
     | 
    
         | 
| 
       108 
136 
     | 
    
         
             
                  { check_header: false, description: 'valid value', header: { 'integer' => 1 }, expected: { status: 200 } },
         
     | 
| 
       109 
137 
     | 
    
         
             
                  { check_header: false, description: 'missing value', header: { 'integer' => nil }, expected: { status: 200 } },
         
     | 
| 
       110 
138 
     | 
    
         
             
                  { check_header: false, description: 'invalid value', header: { 'integer' => 'x' }, expected: { status: 200 } },
         
     | 
| 
       111 
     | 
    
         
            -
                ].each do | 
     | 
| 
      
 139 
     | 
    
         
            +
                ].each do |h|
         
     | 
| 
      
 140 
     | 
    
         
            +
                  check_header = h[:check_header]
         
     | 
| 
      
 141 
     | 
    
         
            +
                  description = h[:description]
         
     | 
| 
      
 142 
     | 
    
         
            +
                  header = h[:header]
         
     | 
| 
      
 143 
     | 
    
         
            +
                  expected = h[:expected]
         
     | 
| 
       112 
144 
     | 
    
         
             
                  describe "when #{check_header}" do
         
     | 
| 
       113 
     | 
    
         
            -
                    %w(get post put patch delete).each do |method|
         
     | 
| 
      
 145 
     | 
    
         
            +
                    %w(get post put patch delete options).each do |method|
         
     | 
| 
       114 
146 
     | 
    
         
             
                      describe method do
         
     | 
| 
       115 
147 
     | 
    
         
             
                        describe description do
         
     | 
| 
       116 
148 
     | 
    
         
             
                          if expected[:error].nil?
         
     | 
| 
         @@ -151,7 +183,7 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       151 
183 
     | 
    
         
             
                    get "/characters"
         
     | 
| 
       152 
184 
     | 
    
         
             
                  end
         
     | 
| 
       153 
185 
     | 
    
         | 
| 
       154 
     | 
    
         
            -
                  assert_match(/but received String: 1/i, e.message)
         
     | 
| 
      
 186 
     | 
    
         
            +
                  assert_match(/but received String: \"1\"/i, e.message)
         
     | 
| 
       155 
187 
     | 
    
         
             
                end
         
     | 
| 
       156 
188 
     | 
    
         | 
| 
       157 
189 
     | 
    
         
             
                it "detects an invalid response status code with validate_success_only=true" do
         
     | 
| 
         @@ -174,7 +206,11 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       174 
206 
     | 
    
         
             
                  { description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 500 } },
         
     | 
| 
       175 
207 
     | 
    
         
             
                  { description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/c') }, expected: { status: 500 } },
         
     | 
| 
       176 
208 
     | 
    
         
             
                  { description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
         
     | 
| 
       177 
     | 
    
         
            -
                ].each do | 
     | 
| 
      
 209 
     | 
    
         
            +
                ].each do |h|
         
     | 
| 
      
 210 
     | 
    
         
            +
                  description = h[:description]
         
     | 
| 
      
 211 
     | 
    
         
            +
                  accept_request_filter = h[:accept_request_filter]
         
     | 
| 
      
 212 
     | 
    
         
            +
                  expected = h[:expected]
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
       178 
214 
     | 
    
         
             
                  it description do
         
     | 
| 
       179 
215 
     | 
    
         
             
                    @app = new_response_rack('not_json', {}, schema: open_api_3_schema, prefix: '/v1', accept_request_filter: accept_request_filter)
         
     | 
| 
       180 
216 
     | 
    
         | 
| 
         @@ -185,12 +221,65 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       185 
221 
     | 
    
         
             
                end
         
     | 
| 
       186 
222 
     | 
    
         
             
              end
         
     | 
| 
       187 
223 
     | 
    
         | 
| 
      
 224 
     | 
    
         
            +
              it 'does not suppress application error' do
         
     | 
| 
      
 225 
     | 
    
         
            +
                @app = Rack::Builder.new {
         
     | 
| 
      
 226 
     | 
    
         
            +
                  use Committee::Middleware::ResponseValidation, {schema: open_api_3_schema, raise: true}
         
     | 
| 
      
 227 
     | 
    
         
            +
                  run lambda { |_|
         
     | 
| 
      
 228 
     | 
    
         
            +
                    JSON.load('-') # invalid json  
         
     | 
| 
      
 229 
     | 
    
         
            +
                  }
         
     | 
| 
      
 230 
     | 
    
         
            +
                }
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
                assert_raises(JSON::ParserError) do
         
     | 
| 
      
 233 
     | 
    
         
            +
                  get "/error", nil
         
     | 
| 
      
 234 
     | 
    
         
            +
                end
         
     | 
| 
      
 235 
     | 
    
         
            +
              end
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
              it "strict and invalid status" do    
         
     | 
| 
      
 238 
     | 
    
         
            +
                @app = new_response_rack(JSON.generate(CHARACTERS_RESPONSE), {}, {schema: open_api_3_schema, strict: true}, {status: 201})
         
     | 
| 
      
 239 
     | 
    
         
            +
                get "/characters"
         
     | 
| 
      
 240 
     | 
    
         
            +
                assert_equal 500, last_response.status
         
     | 
| 
      
 241 
     | 
    
         
            +
              end
         
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
      
 243 
     | 
    
         
            +
              it "strict and invalid status with raise" do
         
     | 
| 
      
 244 
     | 
    
         
            +
                @app = new_response_rack(JSON.generate(CHARACTERS_RESPONSE), {}, {schema: open_api_3_schema, strict: true, raise: true}, {status: 201})
         
     | 
| 
      
 245 
     | 
    
         
            +
             
     | 
| 
      
 246 
     | 
    
         
            +
                assert_raises(Committee::InvalidResponse) do
         
     | 
| 
      
 247 
     | 
    
         
            +
                  get "/characters"
         
     | 
| 
      
 248 
     | 
    
         
            +
                end
         
     | 
| 
      
 249 
     | 
    
         
            +
              end
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
              it "strict and invalid content type" do
         
     | 
| 
      
 252 
     | 
    
         
            +
                @app = new_response_rack("abc", 
         
     | 
| 
      
 253 
     | 
    
         
            +
                  {}, 
         
     | 
| 
      
 254 
     | 
    
         
            +
                  {schema: open_api_3_schema, strict: true},
         
     | 
| 
      
 255 
     | 
    
         
            +
                  {content_type: 'application/text'}
         
     | 
| 
      
 256 
     | 
    
         
            +
                )
         
     | 
| 
      
 257 
     | 
    
         
            +
                get "/characters"
         
     | 
| 
      
 258 
     | 
    
         
            +
                assert_equal 500, last_response.status
         
     | 
| 
      
 259 
     | 
    
         
            +
              end
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
              it "strict and invalid content type with raise" do
         
     | 
| 
      
 262 
     | 
    
         
            +
                @app = new_response_rack("abc",
         
     | 
| 
      
 263 
     | 
    
         
            +
                  {},
         
     | 
| 
      
 264 
     | 
    
         
            +
                  {schema: open_api_3_schema, strict: true, raise: true},
         
     | 
| 
      
 265 
     | 
    
         
            +
                  {content_type: 'application/text'}
         
     | 
| 
      
 266 
     | 
    
         
            +
                )
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
                assert_raises(Committee::InvalidResponse) do
         
     | 
| 
      
 269 
     | 
    
         
            +
                  get "/characters"
         
     | 
| 
      
 270 
     | 
    
         
            +
                end
         
     | 
| 
      
 271 
     | 
    
         
            +
              end
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
       188 
273 
     | 
    
         
             
              private
         
     | 
| 
       189 
274 
     | 
    
         | 
| 
       190 
275 
     | 
    
         
             
              def new_response_rack(response, headers = {}, options = {}, rack_options = {})
         
     | 
| 
      
 276 
     | 
    
         
            +
                # TODO: delete when 5.0.0 released because default value changed
         
     | 
| 
      
 277 
     | 
    
         
            +
                options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
       191 
279 
     | 
    
         
             
                status = rack_options[:status] || 200
         
     | 
| 
      
 280 
     | 
    
         
            +
                content_type = rack_options[:content_type] || "application/json"
         
     | 
| 
       192 
281 
     | 
    
         
             
                headers = {
         
     | 
| 
       193 
     | 
    
         
            -
                  "Content-Type" =>  
     | 
| 
      
 282 
     | 
    
         
            +
                  "Content-Type" => content_type
         
     | 
| 
       194 
283 
     | 
    
         
             
                }.merge(headers)
         
     | 
| 
       195 
284 
     | 
    
         
             
                Rack::Builder.new {
         
     | 
| 
       196 
285 
     | 
    
         
             
                  use Committee::Middleware::ResponseValidation, options
         
     | 
| 
         @@ -15,6 +15,14 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       15 
15 
     | 
    
         
             
                assert_equal 200, last_response.status
         
     | 
| 
       16 
16 
     | 
    
         
             
              end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
              # TODO: remove 5.0.0
         
     | 
| 
      
 19 
     | 
    
         
            +
              it "passes through a valid response" do
         
     | 
| 
      
 20 
     | 
    
         
            +
                # will show deprecated message
         
     | 
| 
      
 21 
     | 
    
         
            +
                @app = new_rack_app(JSON.generate([ValidApp]), {}, schema: hyper_schema, strict: true)
         
     | 
| 
      
 22 
     | 
    
         
            +
                get "/apps"
         
     | 
| 
      
 23 
     | 
    
         
            +
                assert_equal 200, last_response.status
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       18 
26 
     | 
    
         
             
              it "doesn't call error_handler (has a arg) when response is valid" do
         
     | 
| 
       19 
27 
     | 
    
         
             
                called = false
         
     | 
| 
       20 
28 
     | 
    
         
             
                pr = ->(_e) { called = true }
         
     | 
| 
         @@ -77,6 +85,12 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       77 
85 
     | 
    
         
             
                assert_equal 204, last_response.status
         
     | 
| 
       78 
86 
     | 
    
         
             
              end
         
     | 
| 
       79 
87 
     | 
    
         | 
| 
      
 88 
     | 
    
         
            +
              it "passes through a 304 (not modified) response" do
         
     | 
| 
      
 89 
     | 
    
         
            +
                @app = new_rack_app("", {}, app_status: 304, schema: hyper_schema)
         
     | 
| 
      
 90 
     | 
    
         
            +
                get "/apps"
         
     | 
| 
      
 91 
     | 
    
         
            +
                assert_equal 304, last_response.status
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
       80 
94 
     | 
    
         
             
              it "skip validation when 4xx" do
         
     | 
| 
       81 
95 
     | 
    
         
             
                @app = new_rack_app("[{x:y}]", {}, schema: hyper_schema, validate_success_only: true, app_status: 400)
         
     | 
| 
       82 
96 
     | 
    
         
             
                get "/apps"
         
     | 
| 
         @@ -91,17 +105,6 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       91 
105 
     | 
    
         
             
                assert_match(/valid json/i, last_response.body)
         
     | 
| 
       92 
106 
     | 
    
         
             
              end
         
     | 
| 
       93 
107 
     | 
    
         | 
| 
       94 
     | 
    
         
            -
              it "calls error_handler (has a arg) when it rescues JSON errors" do
         
     | 
| 
       95 
     | 
    
         
            -
                called_err = nil
         
     | 
| 
       96 
     | 
    
         
            -
                pr = ->(e) { called_err = e }
         
     | 
| 
       97 
     | 
    
         
            -
                @app = new_rack_app("[{x:y}]", {}, schema: hyper_schema, error_handler: pr)
         
     | 
| 
       98 
     | 
    
         
            -
                _, err = capture_io do
         
     | 
| 
       99 
     | 
    
         
            -
                  get "/apps"
         
     | 
| 
       100 
     | 
    
         
            -
                end
         
     | 
| 
       101 
     | 
    
         
            -
                assert_kind_of JSON::ParserError, called_err
         
     | 
| 
       102 
     | 
    
         
            -
                assert_match(/\[DEPRECATION\]/i, err)
         
     | 
| 
       103 
     | 
    
         
            -
              end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
108 
     | 
    
         
             
              it "calls error_handler (has two args) when it rescues JSON errors" do
         
     | 
| 
       106 
109 
     | 
    
         
             
                called_err = nil
         
     | 
| 
       107 
110 
     | 
    
         
             
                pr = ->(e, _env) { called_err = e }
         
     | 
| 
         @@ -124,20 +127,6 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       124 
127 
     | 
    
         
             
                end
         
     | 
| 
       125 
128 
     | 
    
         
             
              end
         
     | 
| 
       126 
129 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
              it "calls error_handler (has a arg) when it rescues JSON errors" do
         
     | 
| 
       128 
     | 
    
         
            -
                called_err = nil
         
     | 
| 
       129 
     | 
    
         
            -
                pr = ->(e) { called_err = e }
         
     | 
| 
       130 
     | 
    
         
            -
                @app = new_rack_app("[{x:y}]", {}, raise: true, schema: hyper_schema, error_handler: pr)
         
     | 
| 
       131 
     | 
    
         
            -
                assert_raises(Committee::InvalidResponse) do
         
     | 
| 
       132 
     | 
    
         
            -
                  _, err = capture_io do
         
     | 
| 
       133 
     | 
    
         
            -
                    get "/apps"
         
     | 
| 
       134 
     | 
    
         
            -
                  end
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
                  assert_kind_of JSON::ParserError, called_err
         
     | 
| 
       137 
     | 
    
         
            -
                  assert_match(/\[DEPRECATION\]/i, err)
         
     | 
| 
       138 
     | 
    
         
            -
                end
         
     | 
| 
       139 
     | 
    
         
            -
              end
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
130 
     | 
    
         
             
              it "calls error_handler (has two args) when it rescues JSON errors" do
         
     | 
| 
       142 
131 
     | 
    
         
             
                called_err = nil
         
     | 
| 
       143 
132 
     | 
    
         
             
                pr = ->(e, _env) { called_err = e }
         
     | 
| 
         @@ -167,7 +156,10 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       167 
156 
     | 
    
         
             
                  { description: 'when not specified, includes everything', accept_request_filter: nil, expected: { status: 500 } },
         
     | 
| 
       168 
157 
     | 
    
         
             
                  { description: 'when predicate matches, performs validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/a') }, expected: { status: 500 } },
         
     | 
| 
       169 
158 
     | 
    
         
             
                  { description: 'when predicate does not match, skips validation', accept_request_filter: -> (request) { request.path.start_with?('/v1/x') }, expected: { status: 200 } },
         
     | 
| 
       170 
     | 
    
         
            -
                ].each do | 
     | 
| 
      
 159 
     | 
    
         
            +
                ].each do |h|
         
     | 
| 
      
 160 
     | 
    
         
            +
                  description = h[:description]
         
     | 
| 
      
 161 
     | 
    
         
            +
                  accept_request_filter = h[:accept_request_filter]
         
     | 
| 
      
 162 
     | 
    
         
            +
                  expected = h[:expected]
         
     | 
| 
       171 
163 
     | 
    
         
             
                  it description do
         
     | 
| 
       172 
164 
     | 
    
         
             
                    @app = new_rack_app('not_json', {}, schema: hyper_schema, prefix: '/v1', accept_request_filter: accept_request_filter)
         
     | 
| 
       173 
165 
     | 
    
         | 
| 
         @@ -181,6 +173,9 @@ describe Committee::Middleware::ResponseValidation do 
     | 
|
| 
       181 
173 
     | 
    
         
             
              private
         
     | 
| 
       182 
174 
     | 
    
         | 
| 
       183 
175 
     | 
    
         
             
              def new_rack_app(response, headers = {}, options = {})
         
     | 
| 
      
 176 
     | 
    
         
            +
                # TODO: delete when 5.0.0 released because default value changed
         
     | 
| 
      
 177 
     | 
    
         
            +
                options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
       184 
179 
     | 
    
         
             
                headers = {
         
     | 
| 
       185 
180 
     | 
    
         
             
                  "Content-Type" => "application/json"
         
     | 
| 
       186 
181 
     | 
    
         
             
                }.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|
         
     |