committee 3.0.3 → 3.1.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/middleware/base.rb +1 -0
- data/lib/committee/middleware/request_validation.rb +2 -0
- data/lib/committee/middleware/response_validation.rb +0 -2
- data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +1 -1
- data/lib/committee/test/methods.rb +40 -5
- data/test/middleware/request_validation_open_api_3_test.rb +11 -0
- data/test/middleware/request_validation_test.rb +33 -0
- data/test/schema_validator/hyper_schema/response_generator_test.rb +1 -1
- data/test/schema_validator/hyper_schema/response_validator_test.rb +2 -2
- data/test/test/methods_test.rb +133 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0261ef5b9991afdc79316a4aa67e05293b5cc0dc83a8b7dc80a330fcc2d633b9
|
4
|
+
data.tar.gz: a67badbaa49fa492e9bd562293666734a9c733a9d5fa8c54b6a7cf6b3a414305
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8de3637d5059cb2dee41b9d78aa6b448d3c60fc246485bca06cbceb1e2f993c8b86f9d76a9388359c1f05b05e429eaf5949d6e6dfd587246ac4ab8c59f0f37bd
|
7
|
+
data.tar.gz: 510f84e62e9f52239845130b14a6f9432bc2c391c92ab5334b74b301c9119378a491add7f7cfb33fd711a522b727da325a045be31e04ac94fd8c0ead858042a6
|
@@ -17,6 +17,7 @@ module Committee::Middleware
|
|
17
17
|
|
18
18
|
@app.call(request.env)
|
19
19
|
rescue Committee::BadRequest, Committee::InvalidRequest
|
20
|
+
@error_handler.call($!) if @error_handler
|
20
21
|
raise if @raise
|
21
22
|
@error_class.new(400, :bad_request, $!.message).render
|
22
23
|
rescue Committee::NotFound => e
|
@@ -27,6 +28,7 @@ module Committee::Middleware
|
|
27
28
|
e.message
|
28
29
|
).render
|
29
30
|
rescue JSON::ParserError
|
31
|
+
@error_handler.call($!) if @error_handler
|
30
32
|
raise Committee::InvalidRequest if @raise
|
31
33
|
@error_class.new(400, :bad_request, "Request body wasn't valid JSON.").render
|
32
34
|
end
|
@@ -18,7 +18,7 @@ module Committee
|
|
18
18
|
return {} unless options.coerce_value
|
19
19
|
|
20
20
|
request_operation.validate_path_params(options)
|
21
|
-
rescue OpenAPIParser::
|
21
|
+
rescue OpenAPIParser::OpenAPIError => e
|
22
22
|
raise Committee::InvalidRequest.new(e.message)
|
23
23
|
end
|
24
24
|
|
@@ -1,18 +1,27 @@
|
|
1
1
|
module Committee::Test
|
2
2
|
module Methods
|
3
3
|
def assert_schema_conform
|
4
|
-
|
5
|
-
|
4
|
+
assert_request_schema_confirm unless old_behavior
|
5
|
+
assert_response_schema_confirm
|
6
|
+
end
|
7
|
+
|
8
|
+
def assert_request_schema_confirm
|
9
|
+
unless schema_validator.link_exist?
|
10
|
+
request = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
|
11
|
+
raise Committee::InvalidRequest.new(request)
|
12
|
+
end
|
6
13
|
|
7
|
-
|
14
|
+
schema_validator.request_validate(request_object)
|
15
|
+
end
|
8
16
|
|
9
|
-
|
17
|
+
def assert_response_schema_confirm
|
18
|
+
unless schema_validator.link_exist?
|
10
19
|
response = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
|
11
20
|
raise Committee::InvalidResponse.new(response)
|
12
21
|
end
|
13
22
|
|
14
23
|
status, headers, body = response_data
|
15
|
-
|
24
|
+
schema_validator.response_validate(status, headers, [body], true) if validate_response?(status)
|
16
25
|
end
|
17
26
|
|
18
27
|
def committee_options
|
@@ -30,5 +39,31 @@ module Committee::Test
|
|
30
39
|
def validate_response?(status)
|
31
40
|
Committee::Middleware::ResponseValidation.validate?(status, committee_options.fetch(:validate_success_only, false))
|
32
41
|
end
|
42
|
+
|
43
|
+
def schema
|
44
|
+
@schema ||= Committee::Middleware::Base.get_schema(committee_options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def router
|
48
|
+
@router ||= schema.build_router(committee_options)
|
49
|
+
end
|
50
|
+
|
51
|
+
def schema_validator
|
52
|
+
@schema_validator ||= router.build_schema_validator(request_object)
|
53
|
+
end
|
54
|
+
|
55
|
+
def old_behavior
|
56
|
+
old_assert_behavior = committee_options.fetch(:old_assert_behavior, nil)
|
57
|
+
if old_assert_behavior.nil?
|
58
|
+
warn <<-MSG
|
59
|
+
[DEPRECATION] now assert_schema_confirm check response schema only.
|
60
|
+
but we will change check request and response in future major version.
|
61
|
+
so if you want to conform response only, please use assert_response_schema_confirm,
|
62
|
+
or you can suppress this message and keep old behavior by setting old_assert_behavior=true.
|
63
|
+
MSG
|
64
|
+
old_assert_behavior = true
|
65
|
+
end
|
66
|
+
old_assert_behavior
|
67
|
+
end
|
33
68
|
end
|
34
69
|
end
|
@@ -322,6 +322,17 @@ describe Committee::Middleware::RequestValidation do
|
|
322
322
|
assert_match(/required parameters query_string not exist in/i, e.message)
|
323
323
|
end
|
324
324
|
|
325
|
+
it "raises error when required path parameter is invalid" do
|
326
|
+
@app = new_rack_app(raise: true, schema: open_api_3_schema)
|
327
|
+
|
328
|
+
e = assert_raises(Committee::InvalidRequest) do
|
329
|
+
not_an_integer = 'abc'
|
330
|
+
get "/coerce_path_params/#{not_an_integer}", nil
|
331
|
+
end
|
332
|
+
|
333
|
+
assert_match(/is String but it's not valid integer in/i, e.message)
|
334
|
+
end
|
335
|
+
|
325
336
|
it "optionally raises an error" do
|
326
337
|
@app = new_rack_app(raise: true, schema: open_api_3_schema)
|
327
338
|
header "Content-Type", "application/json"
|
@@ -61,6 +61,18 @@ describe Committee::Middleware::RequestValidation do
|
|
61
61
|
assert_equal 200, last_response.status
|
62
62
|
end
|
63
63
|
|
64
|
+
it "doesn't call error_handler when request is valid" do
|
65
|
+
called_error = false
|
66
|
+
pr = ->(_) { called_error = true }
|
67
|
+
@app = new_rack_app(schema: hyper_schema, error_handler: pr)
|
68
|
+
params = {
|
69
|
+
"name" => "cloudnasium"
|
70
|
+
}
|
71
|
+
header "Content-Type", "application/json"
|
72
|
+
post "/apps", JSON.generate(params)
|
73
|
+
assert !called_error
|
74
|
+
end
|
75
|
+
|
64
76
|
it "passes given a datetime and with coerce_date_times enabled on GET endpoint" do
|
65
77
|
key_name = "update_time"
|
66
78
|
params = {
|
@@ -270,6 +282,18 @@ describe Committee::Middleware::RequestValidation do
|
|
270
282
|
assert_match(/invalid request/i, last_response.body)
|
271
283
|
end
|
272
284
|
|
285
|
+
it "calls error_handler when request is invalid" do
|
286
|
+
called_err = nil
|
287
|
+
pr = ->(e) { called_err = e }
|
288
|
+
@app = new_rack_app(schema: hyper_schema, error_handler: pr)
|
289
|
+
header "Content-Type", "application/json"
|
290
|
+
params = {
|
291
|
+
"name" => 1
|
292
|
+
}
|
293
|
+
post "/apps", JSON.generate(params)
|
294
|
+
assert_kind_of Committee::InvalidRequest, called_err
|
295
|
+
end
|
296
|
+
|
273
297
|
it "rescues JSON errors" do
|
274
298
|
@app = new_rack_app(schema: hyper_schema)
|
275
299
|
header "Content-Type", "application/json"
|
@@ -278,6 +302,15 @@ describe Committee::Middleware::RequestValidation do
|
|
278
302
|
assert_match(/valid json/i, last_response.body)
|
279
303
|
end
|
280
304
|
|
305
|
+
it "calls error_handler when it rescues JSON errors" do
|
306
|
+
called_err = nil
|
307
|
+
pr = ->(e) { called_err = e }
|
308
|
+
@app = new_rack_app(schema: hyper_schema, error_handler: pr)
|
309
|
+
header "Content-Type", "application/json"
|
310
|
+
post "/apps", "{x:y}"
|
311
|
+
assert_kind_of JSON::ParserError, called_err
|
312
|
+
end
|
313
|
+
|
281
314
|
it "takes a prefix" do
|
282
315
|
@app = new_rack_app(prefix: "/v1", schema: hyper_schema)
|
283
316
|
params = {
|
@@ -43,7 +43,7 @@ describe Committee::SchemaValidator::HyperSchema::ResponseGenerator do
|
|
43
43
|
data, _schema = call
|
44
44
|
|
45
45
|
# We're testing for legacy behavior here: even without a `targetSchema` as
|
46
|
-
# long as `rel` is set to `instances` we still wrap the
|
46
|
+
# long as `rel` is set to `instances` we still wrap the result in an
|
47
47
|
# array.
|
48
48
|
assert_equal "instances", @list_link.rel
|
49
49
|
|
@@ -43,7 +43,7 @@ describe Committee::SchemaValidator::HyperSchema::ResponseValidator do
|
|
43
43
|
@link.target_schema = nil
|
44
44
|
|
45
45
|
# We're testing for legacy behavior here: even without a `targetSchema` as
|
46
|
-
# long as `rel` is set to `instances` we still wrap the
|
46
|
+
# long as `rel` is set to `instances` we still wrap the result in an
|
47
47
|
# array.
|
48
48
|
assert_equal "instances", @link.rel
|
49
49
|
|
@@ -59,7 +59,7 @@ describe Committee::SchemaValidator::HyperSchema::ResponseValidator do
|
|
59
59
|
@link.target_schema = nil
|
60
60
|
|
61
61
|
# We're testing for legacy behavior here: even without a `targetSchema` as
|
62
|
-
# long as `rel` is set to `instances` we still wrap the
|
62
|
+
# long as `rel` is set to `instances` we still wrap the result in an
|
63
63
|
# array.
|
64
64
|
assert_equal "instances", @link.rel
|
65
65
|
|
data/test/test/methods_test.rb
CHANGED
@@ -52,6 +52,67 @@ describe Committee::Test::Methods do
|
|
52
52
|
end
|
53
53
|
assert_match(/response header must be set to/i, e.message)
|
54
54
|
end
|
55
|
+
|
56
|
+
it "outputs deprecation warning" do
|
57
|
+
@app = new_rack_app(JSON.generate([ValidApp]))
|
58
|
+
get "/apps"
|
59
|
+
_, err = capture_io do
|
60
|
+
assert_schema_conform
|
61
|
+
end
|
62
|
+
assert_match(/\[DEPRECATION\]/i, err)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "assert_request_schema_confirm" do
|
67
|
+
it "passes through a valid request" do
|
68
|
+
@app = new_rack_app([])
|
69
|
+
get "/apps"
|
70
|
+
assert_request_schema_confirm
|
71
|
+
end
|
72
|
+
|
73
|
+
it "not exist required" do
|
74
|
+
@app = new_rack_app([])
|
75
|
+
get "/search/apps", {}
|
76
|
+
e = assert_raises(Committee::InvalidRequest) do
|
77
|
+
assert_request_schema_confirm
|
78
|
+
end
|
79
|
+
assert_match(/"query" wasn't supplied\./i, e.message)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "path undefined in schema" do
|
83
|
+
@app = new_rack_app([])
|
84
|
+
get "/undefined"
|
85
|
+
e = assert_raises(Committee::InvalidRequest) do
|
86
|
+
assert_request_schema_confirm
|
87
|
+
end
|
88
|
+
assert_match(/`GET \/undefined` undefined in schema/i, e.message)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#assert_response_schema_confirm" do
|
93
|
+
it "passes through a valid response" do
|
94
|
+
@app = new_rack_app(JSON.generate([ValidApp]))
|
95
|
+
get "/apps"
|
96
|
+
assert_response_schema_confirm
|
97
|
+
end
|
98
|
+
|
99
|
+
it "detects an invalid response Content-Type" do
|
100
|
+
@app = new_rack_app(JSON.generate([ValidApp]), {})
|
101
|
+
get "/apps"
|
102
|
+
e = assert_raises(Committee::InvalidResponse) do
|
103
|
+
assert_response_schema_confirm
|
104
|
+
end
|
105
|
+
assert_match(/response header must be set to/i, e.message)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "path undefined in schema" do
|
109
|
+
@app = new_rack_app(JSON.generate([ValidApp]))
|
110
|
+
get "/undefined"
|
111
|
+
e = assert_raises(Committee::InvalidResponse) do
|
112
|
+
assert_response_schema_confirm
|
113
|
+
end
|
114
|
+
assert_match(/`GET \/undefined` undefined in schema/i, e.message)
|
115
|
+
end
|
55
116
|
end
|
56
117
|
end
|
57
118
|
|
@@ -88,6 +149,78 @@ describe Committee::Test::Methods do
|
|
88
149
|
end
|
89
150
|
assert_match(/don't exist status code definition/i, e.message)
|
90
151
|
end
|
152
|
+
|
153
|
+
it "outputs deprecation warning" do
|
154
|
+
@app = new_rack_app(JSON.generate(@correct_response))
|
155
|
+
get "/characters"
|
156
|
+
_, err = capture_io do
|
157
|
+
assert_schema_conform
|
158
|
+
end
|
159
|
+
assert_match(/\[DEPRECATION\]/i, err)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "assert_request_schema_confirm" do
|
164
|
+
it "passes through a valid request" do
|
165
|
+
@app = new_rack_app([])
|
166
|
+
get "/characters"
|
167
|
+
assert_request_schema_confirm
|
168
|
+
end
|
169
|
+
|
170
|
+
it "not exist required" do
|
171
|
+
@app = new_rack_app([])
|
172
|
+
get "/validate", {"query_string" => "query", "query_integer_list" => [1, 2]}
|
173
|
+
e = assert_raises(Committee::InvalidRequest) do
|
174
|
+
assert_request_schema_confirm
|
175
|
+
end
|
176
|
+
assert_match(/required parameters query_string not exist in #\/paths/i, e.message)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "path undefined in schema" do
|
180
|
+
@app = new_rack_app([])
|
181
|
+
get "/undefined"
|
182
|
+
e = assert_raises(Committee::InvalidRequest) do
|
183
|
+
assert_request_schema_confirm
|
184
|
+
end
|
185
|
+
assert_match(/`GET \/undefined` undefined in schema/i, e.message)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "#assert_response_schema_confirm" do
|
190
|
+
it "passes through a valid response" do
|
191
|
+
@app = new_rack_app(JSON.generate(@correct_response))
|
192
|
+
get "/characters"
|
193
|
+
assert_response_schema_confirm
|
194
|
+
end
|
195
|
+
|
196
|
+
it "detects an invalid response Content-Type" do
|
197
|
+
@app = new_rack_app(JSON.generate([@correct_response]), {})
|
198
|
+
get "/characters"
|
199
|
+
e = assert_raises(Committee::InvalidResponse) do
|
200
|
+
assert_response_schema_confirm
|
201
|
+
end
|
202
|
+
assert_match(/don't exist response definition/i, e.message)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "detects an invalid response status code" do
|
206
|
+
@app = new_rack_app(JSON.generate([@correct_response]), {}, 419)
|
207
|
+
|
208
|
+
get "/characters"
|
209
|
+
|
210
|
+
e = assert_raises(Committee::InvalidResponse) do
|
211
|
+
assert_response_schema_confirm
|
212
|
+
end
|
213
|
+
assert_match(/don't exist status code definition/i, e.message)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "path undefined in schema" do
|
217
|
+
@app = new_rack_app(JSON.generate(@correct_response))
|
218
|
+
get "/undefined"
|
219
|
+
e = assert_raises(Committee::InvalidResponse) do
|
220
|
+
assert_response_schema_confirm
|
221
|
+
end
|
222
|
+
assert_match(/`GET \/undefined` undefined in schema/i, e.message)
|
223
|
+
end
|
91
224
|
end
|
92
225
|
end
|
93
226
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: committee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandur
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-08-07 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json_schema
|