committee 4.99.1 → 5.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/lib/committee/drivers/hyper_schema/schema.rb +2 -2
  3. data/lib/committee/drivers/open_api_2/driver.rb +1 -1
  4. data/lib/committee/drivers/open_api_2/parameter_schema_builder.rb +1 -1
  5. data/lib/committee/drivers/open_api_2/schema.rb +2 -2
  6. data/lib/committee/drivers/open_api_3/schema.rb +2 -2
  7. data/lib/committee/drivers/schema.rb +1 -1
  8. data/lib/committee/drivers.rb +21 -9
  9. data/lib/committee/middleware/base.rb +6 -5
  10. data/lib/committee/middleware/request_validation.rb +1 -8
  11. data/lib/committee/middleware/response_validation.rb +13 -14
  12. data/lib/committee/request_unpacker.rb +1 -1
  13. data/lib/committee/schema_validator/hyper_schema/response_validator.rb +1 -1
  14. data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +32 -33
  15. data/lib/committee/schema_validator/open_api_3/request_validator.rb +2 -2
  16. data/lib/committee/schema_validator/open_api_3.rb +23 -18
  17. data/lib/committee/schema_validator/option.rb +4 -21
  18. data/lib/committee/test/methods.rb +3 -8
  19. data/lib/committee/version.rb +5 -0
  20. data/lib/committee.rb +9 -2
  21. data/test/committee_test.rb +28 -2
  22. data/test/drivers/open_api_3/driver_test.rb +1 -1
  23. data/test/drivers_test.rb +21 -8
  24. data/test/middleware/base_test.rb +6 -13
  25. data/test/middleware/request_validation_open_api_3_test.rb +38 -42
  26. data/test/middleware/request_validation_test.rb +1 -28
  27. data/test/middleware/response_validation_open_api_3_test.rb +46 -3
  28. data/test/middleware/response_validation_test.rb +6 -25
  29. data/test/schema_validator/hyper_schema/response_validator_test.rb +10 -0
  30. data/test/schema_validator/hyper_schema/router_test.rb +2 -2
  31. data/test/schema_validator/hyper_schema/string_params_coercer_test.rb +1 -1
  32. data/test/schema_validator/open_api_3/operation_wrapper_test.rb +56 -12
  33. data/test/schema_validator/open_api_3/request_validator_test.rb +13 -0
  34. data/test/schema_validator/open_api_3/response_validator_test.rb +15 -1
  35. data/test/test/methods_new_version_test.rb +1 -1
  36. data/test/test/methods_test.rb +11 -31
  37. data/test/test_helper.rb +12 -4
  38. metadata +13 -18
@@ -14,7 +14,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
14
14
  options = {}
15
15
  options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
16
16
 
17
- @validator_option = Committee::SchemaValidator::Option.new(options, open_api_3_schema, :open_api_3, true)
17
+ @validator_option = Committee::SchemaValidator::Option.new(options, open_api_3_schema, :open_api_3)
18
18
  end
19
19
 
20
20
  def operation_object
@@ -32,12 +32,15 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
32
32
  ]
33
33
 
34
34
  it 'correct data' do
35
- operation_object.validate_request_params(SCHEMA_PROPERTIES_PAIR.to_h, HEADER, @validator_option)
35
+ operation_object.validate_request_params({}, {}, SCHEMA_PROPERTIES_PAIR.to_h, HEADER, @validator_option)
36
36
  assert true
37
37
  end
38
38
 
39
39
  it 'correct object data' do
40
- operation_object.validate_request_params({
40
+ operation_object.validate_request_params(
41
+ {},
42
+ {},
43
+ {
41
44
  "object_1" =>
42
45
  {
43
46
  "string_1" => nil,
@@ -54,7 +57,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
54
57
 
55
58
  it 'invalid params' do
56
59
  e = assert_raises(Committee::InvalidRequest) {
57
- operation_object.validate_request_params({"string" => 1}, HEADER, @validator_option)
60
+ operation_object.validate_request_params({}, {}, {"string" => 1}, HEADER, @validator_option)
58
61
  }
59
62
 
60
63
  assert_match(/expected string, but received Integer: 1/i, e.message)
@@ -63,10 +66,10 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
63
66
 
64
67
  it 'support put method' do
65
68
  @method = "put"
66
- operation_object.validate_request_params({"string" => "str"}, HEADER, @validator_option)
69
+ operation_object.validate_request_params({}, {}, {"string" => "str"}, HEADER, @validator_option)
67
70
 
68
71
  e = assert_raises(Committee::InvalidRequest) {
69
- operation_object.validate_request_params({"string" => 1}, HEADER, @validator_option)
72
+ operation_object.validate_request_params({}, {}, {"string" => 1}, HEADER, @validator_option)
70
73
  }
71
74
 
72
75
  assert_match(/expected string, but received Integer: 1/i, e.message)
@@ -75,10 +78,10 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
75
78
 
76
79
  it 'support patch method' do
77
80
  @method = "patch"
78
- operation_object.validate_request_params({"integer" => 1}, HEADER, @validator_option)
81
+ operation_object.validate_request_params({}, {}, {"integer" => 1}, HEADER, @validator_option)
79
82
 
80
83
  e = assert_raises(Committee::InvalidRequest) {
81
- operation_object.validate_request_params({"integer" => "str"}, HEADER, @validator_option)
84
+ operation_object.validate_request_params({}, {}, {"integer" => "str"}, HEADER, @validator_option)
82
85
  }
83
86
 
84
87
  assert_match(/expected integer, but received String: "str"/i, e.message)
@@ -86,7 +89,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
86
89
  end
87
90
 
88
91
  it 'unknown param' do
89
- operation_object.validate_request_params({"unknown" => 1}, HEADER, @validator_option)
92
+ operation_object.validate_request_params({}, {}, {"unknown" => 1}, HEADER, @validator_option)
90
93
  end
91
94
 
92
95
  describe 'support get method' do
@@ -96,13 +99,17 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
96
99
 
97
100
  it 'correct' do
98
101
  operation_object.validate_request_params(
102
+ {},
99
103
  {"query_string" => "query", "query_integer_list" => [1, 2]},
104
+ {},
100
105
  HEADER,
101
106
  @validator_option
102
107
  )
103
108
 
104
109
  operation_object.validate_request_params(
110
+ {},
105
111
  {"query_string" => "query", "query_integer_list" => [1, 2], "optional_integer" => 1},
112
+ {},
106
113
  HEADER,
107
114
  @validator_option
108
115
  )
@@ -112,7 +119,7 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
112
119
 
113
120
  it 'not exist required' do
114
121
  e = assert_raises(Committee::InvalidRequest) {
115
- operation_object.validate_request_params({"query_integer_list" => [1, 2]}, HEADER, @validator_option)
122
+ operation_object.validate_request_params({}, {"query_integer_list" => [1, 2]}, {}, HEADER, @validator_option)
116
123
  }
117
124
 
118
125
  assert_match(/missing required parameters: query_string/i, e.message)
@@ -122,7 +129,9 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
122
129
  it 'invalid type' do
123
130
  e = assert_raises(Committee::InvalidRequest) {
124
131
  operation_object.validate_request_params(
132
+ {},
125
133
  {"query_string" => 1, "query_integer_list" => [1, 2], "optional_integer" => 1},
134
+ {},
126
135
  HEADER,
127
136
  @validator_option
128
137
  )
@@ -140,14 +149,14 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
140
149
  end
141
150
 
142
151
  it 'correct' do
143
- operation_object.validate_request_params({"limit" => "1"}, HEADER, @validator_option)
152
+ operation_object.validate_request_params({}, {"limit" => "1"}, {}, HEADER, @validator_option)
144
153
 
145
154
  assert true
146
155
  end
147
156
 
148
157
  it 'invalid type' do
149
158
  e = assert_raises(Committee::InvalidRequest) {
150
- operation_object.validate_request_params({"limit" => "a"}, HEADER, @validator_option)
159
+ operation_object.validate_request_params({}, {"limit" => "a"}, {}, HEADER, @validator_option)
151
160
  }
152
161
 
153
162
  assert_match(/expected integer, but received String: "a"/i, e.message)
@@ -155,6 +164,41 @@ describe Committee::SchemaValidator::OpenAPI3::OperationWrapper do
155
164
  end
156
165
  end
157
166
 
167
+ describe 'support head method' do
168
+ before do
169
+ @path = '/characters'
170
+ @method = 'head'
171
+ end
172
+
173
+ it 'correct' do
174
+ operation_object.validate_request_params({}, {"limit" => "1"}, {}, HEADER, @validator_option)
175
+
176
+ assert true
177
+ end
178
+
179
+ it 'invalid type' do
180
+ e = assert_raises(Committee::InvalidRequest) {
181
+ operation_object.validate_request_params({}, {"limit" => "a"}, {}, HEADER, @validator_option)
182
+ }
183
+
184
+ assert_match(/expected integer, but received String: "a"/i, e.message)
185
+ assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
186
+ end
187
+ end
188
+
189
+ it 'support options method' do
190
+ @method = "options"
191
+ operation_object.validate_request_params({}, {}, {"integer" => 1}, HEADER, @validator_option)
192
+
193
+ e = assert_raises(Committee::InvalidRequest) {
194
+ operation_object.validate_request_params({}, {}, {"integer" => "str"}, HEADER, @validator_option)
195
+ }
196
+
197
+ assert_match(/expected integer, but received String: "str"/i, e.message)
198
+ assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
199
+ end
200
+
201
+
158
202
  describe '#content_types' do
159
203
  it 'returns supported content types' do
160
204
  @path = '/validate_content_types'
@@ -71,7 +71,20 @@ describe Committee::SchemaValidator::OpenAPI3::RequestValidator do
71
71
  assert_equal 200, last_response.status
72
72
  end
73
73
 
74
+ it "does not mix up parameters and requestBody" do
75
+ @app = new_rack_app(check_content_type: true, schema: open_api_3_schema)
76
+ params = {
77
+ "last_name" => "Skywalker"
78
+ }
79
+ header "Content-Type", "application/json"
80
+ post "/additional_properties?first_name=Luke", JSON.generate(params)
81
+ assert_equal 200, last_response.status
82
+ end
83
+
74
84
  def new_rack_app(options = {})
85
+ # TODO: delete when 5.0.0 released because default value changed
86
+ options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
87
+
75
88
  Rack::Builder.new {
76
89
  use Committee::Middleware::RequestValidation, options
77
90
  run lambda { |_|
@@ -17,7 +17,7 @@ describe Committee::SchemaValidator::OpenAPI3::ResponseValidator do
17
17
  options = {}
18
18
  options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
19
19
 
20
- @validator_option = Committee::SchemaValidator::Option.new(options, open_api_3_schema, :open_api_3, false)
20
+ @validator_option = Committee::SchemaValidator::Option.new(options, open_api_3_schema, :open_api_3)
21
21
  end
22
22
 
23
23
  it "passes through a valid response" do
@@ -42,6 +42,15 @@ describe Committee::SchemaValidator::OpenAPI3::ResponseValidator do
42
42
  assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
43
43
  end
44
44
 
45
+ it "raises InvalidResponse when a invalid status code with strict option" do
46
+ @status = 201
47
+ e = assert_raises(Committee::InvalidResponse) {
48
+ call_response_validator(true)
49
+ }
50
+
51
+ assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
52
+ end
53
+
45
54
  it "passes through a valid response with no Content-Type" do
46
55
  @headers = {}
47
56
  call_response_validator
@@ -67,6 +76,11 @@ describe Committee::SchemaValidator::OpenAPI3::ResponseValidator do
67
76
  call_response_validator
68
77
  end
69
78
 
79
+ it "passes through a 304 Not Modified response" do
80
+ @status, @headers, @data = 304, {}, nil
81
+ call_response_validator
82
+ end
83
+
70
84
  private
71
85
 
72
86
  def call_response_validator(strict = false)
@@ -72,7 +72,7 @@ describe Committee::Test::Methods do
72
72
  @committee_options.merge!(validate_success_only: true)
73
73
  @app = new_rack_app(JSON.generate([ValidApp]), 400, {})
74
74
  get "/apps"
75
- assert_schema_conform
75
+ assert_schema_conform(400)
76
76
  end
77
77
 
78
78
  it "detects an invalid response Content-Type and check all status code" do
@@ -57,16 +57,6 @@ describe Committee::Test::Methods do
57
57
  end
58
58
  assert_match(/response header must be set to/i, e.message)
59
59
  end
60
-
61
- it "outputs deprecation warning" do
62
- @app = new_rack_app(JSON.generate([ValidApp]))
63
- get "/apps"
64
- _, err = capture_io do
65
- assert_schema_conform
66
- end
67
- assert_match(/\[DEPRECATION\] Now assert_schema_conform check response schema only/i, err)
68
- assert_match(/\[DEPRECATION\] Pass expected response status code/i, err)
69
- end
70
60
  end
71
61
 
72
62
  describe "assert_request_schema_confirm" do
@@ -99,14 +89,14 @@ describe Committee::Test::Methods do
99
89
  it "passes through a valid response" do
100
90
  @app = new_rack_app(JSON.generate([ValidApp]))
101
91
  get "/apps"
102
- assert_response_schema_confirm
92
+ assert_response_schema_confirm(200)
103
93
  end
104
94
 
105
95
  it "detects an invalid response Content-Type" do
106
96
  @app = new_rack_app(JSON.generate([ValidApp]), {})
107
97
  get "/apps"
108
98
  e = assert_raises(Committee::InvalidResponse) do
109
- assert_response_schema_confirm
99
+ assert_response_schema_confirm(200)
110
100
  end
111
101
  assert_match(/response header must be set to/i, e.message)
112
102
  end
@@ -133,14 +123,14 @@ describe Committee::Test::Methods do
133
123
  it "passes through a valid response" do
134
124
  @app = new_rack_app(JSON.generate(@correct_response))
135
125
  get "/characters"
136
- assert_schema_conform
126
+ assert_schema_conform(200)
137
127
  end
138
128
 
139
129
  it "detects an invalid response Content-Type" do
140
130
  @app = new_rack_app(JSON.generate([@correct_response]), {})
141
131
  get "/characters"
142
132
  e = assert_raises(Committee::InvalidResponse) do
143
- assert_schema_conform
133
+ assert_schema_conform(200)
144
134
  end
145
135
  assert_match(/response definition does not exist/i, e.message)
146
136
  end
@@ -151,20 +141,10 @@ describe Committee::Test::Methods do
151
141
  get "/characters"
152
142
 
153
143
  e = assert_raises(Committee::InvalidResponse) do
154
- assert_schema_conform
144
+ assert_schema_conform(419)
155
145
  end
156
146
  assert_match(/status code definition does not exist/i, e.message)
157
147
  end
158
-
159
- it "outputs deprecation warning" do
160
- @app = new_rack_app(JSON.generate(@correct_response))
161
- get "/characters"
162
- _, err = capture_io do
163
- assert_schema_conform
164
- end
165
- assert_match(/\[DEPRECATION\] Now assert_schema_conform check response schema only/i, err)
166
- assert_match(/\[DEPRECATION\] Pass expected response status code/i, err)
167
- end
168
148
  end
169
149
 
170
150
  describe "assert_request_schema_confirm" do
@@ -198,14 +178,14 @@ describe Committee::Test::Methods do
198
178
  it "passes through a valid response" do
199
179
  @app = new_rack_app(JSON.generate(@correct_response))
200
180
  get "/characters"
201
- assert_response_schema_confirm
181
+ assert_response_schema_confirm(200)
202
182
  end
203
183
 
204
184
  it "detects an invalid response Content-Type" do
205
185
  @app = new_rack_app(JSON.generate([@correct_response]), {})
206
186
  get "/characters"
207
187
  e = assert_raises(Committee::InvalidResponse) do
208
- assert_response_schema_confirm
188
+ assert_response_schema_confirm(200)
209
189
  end
210
190
  assert_match(/response definition does not exist/i, e.message)
211
191
  end
@@ -216,7 +196,7 @@ describe Committee::Test::Methods do
216
196
  get "/characters"
217
197
 
218
198
  e = assert_raises(Committee::InvalidResponse) do
219
- assert_response_schema_confirm
199
+ assert_response_schema_confirm(419)
220
200
  end
221
201
  assert_match(/status code definition does not exist/i, e.message)
222
202
  end
@@ -249,7 +229,7 @@ describe Committee::Test::Methods do
249
229
  end
250
230
  it 'records openapi coverage' do
251
231
  get "/posts"
252
- assert_response_schema_confirm
232
+ assert_response_schema_confirm(200)
253
233
  assert_equal({
254
234
  '/threads/{id}' => {
255
235
  'get' => {
@@ -290,7 +270,7 @@ describe Committee::Test::Methods do
290
270
  it 'can record openapi coverage correctly when prefix is set' do
291
271
  @committee_options.merge!(prefix: '/api')
292
272
  post "/api/likes"
293
- assert_response_schema_confirm
273
+ assert_response_schema_confirm(200)
294
274
  assert_equal({
295
275
  '/threads/{id}' => {
296
276
  'get' => {
@@ -330,7 +310,7 @@ describe Committee::Test::Methods do
330
310
 
331
311
  it 'records openapi coverage correctly with path param' do
332
312
  get "/threads/asd"
333
- assert_response_schema_confirm
313
+ assert_response_schema_confirm(200)
334
314
  assert_equal({
335
315
  '/threads/{id}' => {
336
316
  'get' => {
data/test/test_helper.rb CHANGED
@@ -12,7 +12,7 @@ SimpleCov.start do
12
12
 
13
13
  # This library has a pretty modest number of lines, so let's try to stick
14
14
  # to a 100% coverage target for a while and see what happens.
15
- minimum_coverage 99
15
+ minimum_coverage 100
16
16
  end
17
17
 
18
18
  require "minitest"
@@ -60,11 +60,11 @@ def open_api_2_form_schema
60
60
  end
61
61
 
62
62
  def open_api_3_schema
63
- @open_api_3_schema ||= Committee::Drivers.load_from_file(open_api_3_schema_path)
63
+ @open_api_3_schema ||= Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true})
64
64
  end
65
65
 
66
66
  def open_api_3_coverage_schema
67
- @open_api_3_coverage_schema ||= Committee::Drivers.load_from_file(open_api_3_coverage_schema_path)
67
+ @open_api_3_coverage_schema ||= Committee::Drivers.load_from_file(open_api_3_coverage_schema_path, parser_options:{strict_reference_validation: true})
68
68
  end
69
69
 
70
70
  # Don't cache this because we'll often manipulate the created hash in tests.
@@ -82,7 +82,11 @@ def open_api_2_form_data
82
82
  end
83
83
 
84
84
  def open_api_3_data
85
- YAML.load_file(open_api_3_schema_path)
85
+ if YAML.respond_to?(:unsafe_load_file)
86
+ YAML.unsafe_load_file(open_api_3_schema_path)
87
+ else
88
+ YAML.load_file(open_api_3_schema_path)
89
+ end
86
90
  end
87
91
 
88
92
  def hyper_schema_schema_path
@@ -108,3 +112,7 @@ end
108
112
  def open_api_3_0_1_schema_path
109
113
  "./test/data/openapi3/3_0_1.yaml"
110
114
  end
115
+
116
+ def open_api_3_invalid_reference_path
117
+ "./test/data/openapi3/invalid_reference.yaml"
118
+ end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: committee
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.99.1
4
+ version: 5.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandur
8
8
  - geemus (Wesley Beary)
9
9
  - ota42y
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-01-28 00:00:00.000000000 Z
13
+ date: 2023-01-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json_schema
@@ -50,20 +50,14 @@ dependencies:
50
50
  name: openapi_parser
51
51
  requirement: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: 0.11.1
56
- - - "<"
53
+ - - "~>"
57
54
  - !ruby/object:Gem::Version
58
55
  version: '1.0'
59
56
  type: :runtime
60
57
  prerelease: false
61
58
  version_requirements: !ruby/object:Gem::Requirement
62
59
  requirements:
63
- - - ">="
64
- - !ruby/object:Gem::Version
65
- version: 0.11.1
66
- - - "<"
60
+ - - "~>"
67
61
  - !ruby/object:Gem::Version
68
62
  version: '1.0'
69
63
  - !ruby/object:Gem::Dependency
@@ -220,7 +214,7 @@ dependencies:
220
214
  - - ">="
221
215
  - !ruby/object:Gem::Version
222
216
  version: '0'
223
- description:
217
+ description:
224
218
  email:
225
219
  - brandur@mutelight.org
226
220
  - geemus+github@gmail.com
@@ -275,6 +269,7 @@ files:
275
269
  - lib/committee/test/schema_coverage.rb
276
270
  - lib/committee/utils.rb
277
271
  - lib/committee/validation_error.rb
272
+ - lib/committee/version.rb
278
273
  - test/bin/committee_stub_test.rb
279
274
  - test/bin_test.rb
280
275
  - test/committee_test.rb
@@ -311,7 +306,7 @@ homepage: https://github.com/interagent/committee
311
306
  licenses:
312
307
  - MIT
313
308
  metadata: {}
314
- post_install_message:
309
+ post_install_message:
315
310
  rdoc_options: []
316
311
  require_paths:
317
312
  - lib
@@ -319,15 +314,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
319
314
  requirements:
320
315
  - - ">="
321
316
  - !ruby/object:Gem::Version
322
- version: 2.4.0
317
+ version: 2.6.0
323
318
  required_rubygems_version: !ruby/object:Gem::Requirement
324
319
  requirements:
325
- - - ">="
320
+ - - ">"
326
321
  - !ruby/object:Gem::Version
327
- version: '0'
322
+ version: 1.3.1
328
323
  requirements: []
329
- rubygems_version: 3.3.3
330
- signing_key:
324
+ rubygems_version: 3.2.3
325
+ signing_key:
331
326
  specification_version: 4
332
327
  summary: A collection of Rack middleware to support JSON Schema.
333
328
  test_files: []