committee 4.2.1 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/committee.rb +2 -3
- data/lib/committee/middleware/request_validation.rb +4 -4
- data/lib/committee/middleware/response_validation.rb +1 -1
- data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +4 -0
- data/lib/committee/schema_validator/open_api_3/router.rb +3 -1
- data/lib/committee/test/methods.rb +17 -3
- data/lib/committee/test/schema_coverage.rb +101 -0
- data/lib/committee/validation_error.rb +3 -2
- data/test/committee_test.rb +1 -1
- data/test/test/methods_test.rb +139 -0
- data/test/test/schema_coverage_test.rb +216 -0
- data/test/test_helper.rb +8 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19c70ee2e436755ddf7b0b59b213ab7c00b60e67ce52520b956b889121b24e4c
|
|
4
|
+
data.tar.gz: 06066adc6056231938d36d93a98c5d7318d9c1ff367784265d66c0eb271fb7b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bfbcc7aa85c676291125ed16b20badadda3eb8d895b6834cdc884602345c6ed3a052ecbdd381615b8bbca49815d884407cf8cc2f8cbbe05702593b5cc171f568
|
|
7
|
+
data.tar.gz: cc454350c3d04969ad3f24c1922b887a6e319cea4f0a869b647ef439dbc9f5f83f3922bde82abdeb0994a540e53d5e68345e76d7291b408e42cd2f5a4df9eec1
|
data/lib/committee.rb
CHANGED
|
@@ -16,9 +16,7 @@ module Committee
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def self.warn_deprecated(message)
|
|
19
|
-
|
|
20
|
-
$stderr.puts(message)
|
|
21
|
-
end
|
|
19
|
+
warn("[DEPRECATION] #{message}")
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
22
|
|
|
@@ -31,3 +29,4 @@ require_relative "committee/validation_error"
|
|
|
31
29
|
|
|
32
30
|
require_relative "committee/bin/committee_stub"
|
|
33
31
|
require_relative "committee/test/methods"
|
|
32
|
+
require_relative "committee/test/schema_coverage"
|
|
@@ -21,14 +21,14 @@ module Committee
|
|
|
21
21
|
rescue Committee::BadRequest, Committee::InvalidRequest
|
|
22
22
|
handle_exception($!, request.env)
|
|
23
23
|
raise if @raise
|
|
24
|
-
return @error_class.new(400, :bad_request, $!.message).render unless @ignore_error
|
|
24
|
+
return @error_class.new(400, :bad_request, $!.message, request).render unless @ignore_error
|
|
25
25
|
rescue Committee::NotFound => e
|
|
26
26
|
raise if @raise
|
|
27
|
-
return @error_class.new(404, :not_found, e.message).render unless @ignore_error
|
|
27
|
+
return @error_class.new(404, :not_found, e.message, request).render unless @ignore_error
|
|
28
28
|
rescue JSON::ParserError
|
|
29
29
|
handle_exception($!, request.env)
|
|
30
30
|
raise Committee::InvalidRequest if @raise
|
|
31
|
-
return @error_class.new(400, :bad_request, "Request body wasn't valid JSON.").render unless @ignore_error
|
|
31
|
+
return @error_class.new(400, :bad_request, "Request body wasn't valid JSON.", request).render unless @ignore_error
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
@app.call(request.env)
|
|
@@ -42,7 +42,7 @@ module Committee
|
|
|
42
42
|
if @error_handler.arity > 1
|
|
43
43
|
@error_handler.call(e, env)
|
|
44
44
|
else
|
|
45
|
-
|
|
45
|
+
Committee.warn_deprecated('Using `error_handler.call(exception)` is deprecated and will be change to `error_handler.call(exception, request.env)` in next major version.')
|
|
46
46
|
@error_handler.call(e)
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -46,7 +46,7 @@ module Committee
|
|
|
46
46
|
if @error_handler.arity > 1
|
|
47
47
|
@error_handler.call(e, env)
|
|
48
48
|
else
|
|
49
|
-
|
|
49
|
+
Committee.warn_deprecated('Using `error_handler.call(exception)` is deprecated and will be change to `error_handler.call(exception, request.env)` in next major version.')
|
|
50
50
|
@error_handler.call(e)
|
|
51
51
|
end
|
|
52
52
|
end
|
|
@@ -17,6 +17,10 @@ module Committee
|
|
|
17
17
|
request_operation.original_path
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
def http_method
|
|
21
|
+
request_operation.http_method
|
|
22
|
+
end
|
|
23
|
+
|
|
20
24
|
def coerce_path_parameter(validator_option)
|
|
21
25
|
options = build_openapi_parser_path_option(validator_option)
|
|
22
26
|
return {} unless options.coerce_value
|
|
@@ -22,8 +22,10 @@ module Committee
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def operation_object(request)
|
|
25
|
+
return nil unless includes_request?(request)
|
|
26
|
+
|
|
25
27
|
path = request.path
|
|
26
|
-
path = path.gsub(@prefix_regexp, '') if
|
|
28
|
+
path = path.gsub(@prefix_regexp, '') if @prefix_regexp
|
|
27
29
|
|
|
28
30
|
request_method = request.request_method.downcase
|
|
29
31
|
|
|
@@ -10,7 +10,7 @@ module Committee
|
|
|
10
10
|
|
|
11
11
|
def assert_request_schema_confirm
|
|
12
12
|
unless schema_validator.link_exist?
|
|
13
|
-
request = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
|
|
13
|
+
request = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema (prefix: #{committee_options[:prefix].inspect})."
|
|
14
14
|
raise Committee::InvalidRequest.new(request)
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -19,11 +19,17 @@ module Committee
|
|
|
19
19
|
|
|
20
20
|
def assert_response_schema_confirm
|
|
21
21
|
unless schema_validator.link_exist?
|
|
22
|
-
response = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema."
|
|
22
|
+
response = "`#{request_object.request_method} #{request_object.path_info}` undefined in schema (prefix: #{committee_options[:prefix].inspect})."
|
|
23
23
|
raise Committee::InvalidResponse.new(response)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
status, headers, body = response_data
|
|
27
|
+
|
|
28
|
+
if schema_coverage
|
|
29
|
+
operation_object = router.operation_object(request_object)
|
|
30
|
+
schema_coverage&.update_response_coverage!(operation_object.original_path, operation_object.http_method, status)
|
|
31
|
+
end
|
|
32
|
+
|
|
27
33
|
schema_validator.response_validate(status, headers, [body], true) if validate_response?(status)
|
|
28
34
|
end
|
|
29
35
|
|
|
@@ -55,10 +61,18 @@ module Committee
|
|
|
55
61
|
@schema_validator ||= router.build_schema_validator(request_object)
|
|
56
62
|
end
|
|
57
63
|
|
|
64
|
+
def schema_coverage
|
|
65
|
+
return nil unless schema.is_a?(Committee::Drivers::OpenAPI3::Schema)
|
|
66
|
+
|
|
67
|
+
coverage = committee_options.fetch(:schema_coverage, nil)
|
|
68
|
+
|
|
69
|
+
coverage.is_a?(SchemaCoverage) ? coverage : nil
|
|
70
|
+
end
|
|
71
|
+
|
|
58
72
|
def old_behavior
|
|
59
73
|
old_assert_behavior = committee_options.fetch(:old_assert_behavior, nil)
|
|
60
74
|
if old_assert_behavior.nil?
|
|
61
|
-
|
|
75
|
+
Committee.warn_deprecated('Now assert_schema_conform check response schema only. but we will change check request and response in future major version. so if you want to conform response only, please use assert_response_schema_confirm, or you can suppress this message and keep old behavior by setting old_assert_behavior=true.')
|
|
62
76
|
old_assert_behavior = true
|
|
63
77
|
end
|
|
64
78
|
old_assert_behavior
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Committee
|
|
4
|
+
module Test
|
|
5
|
+
class SchemaCoverage
|
|
6
|
+
attr_reader :schema
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def merge_report(first, second)
|
|
10
|
+
report = first.dup
|
|
11
|
+
second.each do |k, v|
|
|
12
|
+
if v.is_a?(Hash)
|
|
13
|
+
if report[k].nil?
|
|
14
|
+
report[k] = v
|
|
15
|
+
else
|
|
16
|
+
report[k] = merge_report(report[k], v)
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
report[k] ||= v
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
report
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def flatten_report(report)
|
|
26
|
+
responses = []
|
|
27
|
+
report.each do |path_name, path_coverage|
|
|
28
|
+
path_coverage.each do |method, method_coverage|
|
|
29
|
+
responses_coverage = method_coverage['responses']
|
|
30
|
+
responses_coverage.each do |response_status, is_covered|
|
|
31
|
+
responses << {
|
|
32
|
+
path: path_name,
|
|
33
|
+
method: method,
|
|
34
|
+
status: response_status,
|
|
35
|
+
is_covered: is_covered,
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
{
|
|
41
|
+
responses: responses,
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def initialize(schema)
|
|
47
|
+
raise 'Unsupported schema' unless schema.is_a?(Committee::Drivers::OpenAPI3::Schema)
|
|
48
|
+
|
|
49
|
+
@schema = schema
|
|
50
|
+
@covered = {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def update_response_coverage!(path, method, response_status)
|
|
54
|
+
method = method.to_s.downcase
|
|
55
|
+
response_status = response_status.to_s
|
|
56
|
+
|
|
57
|
+
@covered[path] ||= {}
|
|
58
|
+
@covered[path][method] ||= {}
|
|
59
|
+
@covered[path][method]['responses'] ||= {}
|
|
60
|
+
@covered[path][method]['responses'][response_status] = true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def report
|
|
64
|
+
report = {}
|
|
65
|
+
|
|
66
|
+
schema.open_api.paths.path.each do |path_name, path_item|
|
|
67
|
+
report[path_name] = {}
|
|
68
|
+
path_item._openapi_all_child_objects.each do |object_name, object|
|
|
69
|
+
next unless object.is_a?(OpenAPIParser::Schemas::Operation)
|
|
70
|
+
|
|
71
|
+
method = object_name.split('/').last&.downcase
|
|
72
|
+
next unless method
|
|
73
|
+
|
|
74
|
+
report[path_name][method] ||= {}
|
|
75
|
+
|
|
76
|
+
# TODO: check coverage on request params/body as well?
|
|
77
|
+
|
|
78
|
+
report[path_name][method]['responses'] ||= {}
|
|
79
|
+
object.responses.response.each do |response_status, _|
|
|
80
|
+
is_covered = @covered.dig(path_name, method, 'responses', response_status) || false
|
|
81
|
+
report[path_name][method]['responses'][response_status] = is_covered
|
|
82
|
+
end
|
|
83
|
+
if object.responses.default
|
|
84
|
+
is_default_covered = (@covered.dig(path_name, method, 'responses') || {}).any? do |status, is_covered|
|
|
85
|
+
is_covered && !object.responses.response.key?(status)
|
|
86
|
+
end
|
|
87
|
+
report[path_name][method]['responses']['default'] = is_default_covered
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
report
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def report_flatten
|
|
96
|
+
self.class.flatten_report(report)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module Committee
|
|
4
4
|
class ValidationError
|
|
5
|
-
attr_reader :id, :message, :status
|
|
5
|
+
attr_reader :id, :message, :status, :request
|
|
6
6
|
|
|
7
|
-
def initialize(status, id, message)
|
|
7
|
+
def initialize(status, id, message, request = nil)
|
|
8
8
|
@status = status
|
|
9
9
|
@id = id
|
|
10
10
|
@message = message
|
|
11
|
+
@request = request
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def error_body
|
data/test/committee_test.rb
CHANGED
data/test/test/methods_test.rb
CHANGED
|
@@ -227,6 +227,145 @@ describe Committee::Test::Methods do
|
|
|
227
227
|
end
|
|
228
228
|
assert_match(/`GET \/undefined` undefined in schema/i, e.message)
|
|
229
229
|
end
|
|
230
|
+
|
|
231
|
+
it "raises error when path does not match prefix" do
|
|
232
|
+
@committee_options.merge!({prefix: '/api'})
|
|
233
|
+
@app = new_rack_app(JSON.generate(@correct_response))
|
|
234
|
+
get "/characters"
|
|
235
|
+
e = assert_raises(Committee::InvalidResponse) do
|
|
236
|
+
assert_response_schema_confirm
|
|
237
|
+
end
|
|
238
|
+
assert_match(/`GET \/characters` undefined in schema \(prefix: "\/api"\)/i, e.message)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
describe 'coverage' do
|
|
242
|
+
before do
|
|
243
|
+
@schema_coverage = Committee::Test::SchemaCoverage.new(open_api_3_coverage_schema)
|
|
244
|
+
@committee_options.merge!(schema: open_api_3_coverage_schema, schema_coverage: @schema_coverage)
|
|
245
|
+
|
|
246
|
+
@app = new_rack_app(JSON.generate({ success: true }))
|
|
247
|
+
end
|
|
248
|
+
it 'records openapi coverage' do
|
|
249
|
+
get "/posts"
|
|
250
|
+
assert_response_schema_confirm
|
|
251
|
+
assert_equal({
|
|
252
|
+
'/threads/{id}' => {
|
|
253
|
+
'get' => {
|
|
254
|
+
'responses' => {
|
|
255
|
+
'200' => false,
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
'/posts' => {
|
|
260
|
+
'get' => {
|
|
261
|
+
'responses' => {
|
|
262
|
+
'200' => true,
|
|
263
|
+
'404' => false,
|
|
264
|
+
'default' => false,
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
'post' => {
|
|
268
|
+
'responses' => {
|
|
269
|
+
'200' => false,
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
'/likes' => {
|
|
274
|
+
'post' => {
|
|
275
|
+
'responses' => {
|
|
276
|
+
'200' => false,
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
'delete' => {
|
|
280
|
+
'responses' => {
|
|
281
|
+
'200' => false,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
}, @schema_coverage.report)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it 'can record openapi coverage correctly when prefix is set' do
|
|
289
|
+
@committee_options.merge!(prefix: '/api')
|
|
290
|
+
post "/api/likes"
|
|
291
|
+
assert_response_schema_confirm
|
|
292
|
+
assert_equal({
|
|
293
|
+
'/threads/{id}' => {
|
|
294
|
+
'get' => {
|
|
295
|
+
'responses' => {
|
|
296
|
+
'200' => false,
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
'/posts' => {
|
|
301
|
+
'get' => {
|
|
302
|
+
'responses' => {
|
|
303
|
+
'200' => false,
|
|
304
|
+
'404' => false,
|
|
305
|
+
'default' => false,
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
'post' => {
|
|
309
|
+
'responses' => {
|
|
310
|
+
'200' => false,
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
'/likes' => {
|
|
315
|
+
'post' => {
|
|
316
|
+
'responses' => {
|
|
317
|
+
'200' => true,
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
'delete' => {
|
|
321
|
+
'responses' => {
|
|
322
|
+
'200' => false,
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
}, @schema_coverage.report)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it 'records openapi coverage correctly with path param' do
|
|
330
|
+
get "/threads/asd"
|
|
331
|
+
assert_response_schema_confirm
|
|
332
|
+
assert_equal({
|
|
333
|
+
'/threads/{id}' => {
|
|
334
|
+
'get' => {
|
|
335
|
+
'responses' => {
|
|
336
|
+
'200' => true,
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
'/posts' => {
|
|
341
|
+
'get' => {
|
|
342
|
+
'responses' => {
|
|
343
|
+
'200' => false,
|
|
344
|
+
'404' => false,
|
|
345
|
+
'default' => false,
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
'post' => {
|
|
349
|
+
'responses' => {
|
|
350
|
+
'200' => false,
|
|
351
|
+
},
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
'/likes' => {
|
|
355
|
+
'post' => {
|
|
356
|
+
'responses' => {
|
|
357
|
+
'200' => false,
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
'delete' => {
|
|
361
|
+
'responses' => {
|
|
362
|
+
'200' => false,
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
}, @schema_coverage.report)
|
|
367
|
+
end
|
|
368
|
+
end
|
|
230
369
|
end
|
|
231
370
|
end
|
|
232
371
|
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
describe Committee::Test::SchemaCoverage do
|
|
6
|
+
before do
|
|
7
|
+
@schema_coverage = Committee::Test::SchemaCoverage.new(open_api_3_coverage_schema)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe 'recording coverage' do
|
|
11
|
+
def response_as_str(response)
|
|
12
|
+
[:path, :method, :status].map { |key| response[key] }.join(' ')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def uncovered_responses
|
|
16
|
+
@schema_coverage.report_flatten[:responses].select { |r| !r[:is_covered] }.map { |r| response_as_str(r) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def covered_responses
|
|
20
|
+
@schema_coverage.report_flatten[:responses].select { |r| r[:is_covered] }.map { |r| response_as_str(r) }
|
|
21
|
+
end
|
|
22
|
+
it 'can record and report coverage properly' do
|
|
23
|
+
@schema_coverage.update_response_coverage!('/posts', 'get', '200')
|
|
24
|
+
assert_equal([
|
|
25
|
+
'/posts get 200',
|
|
26
|
+
], covered_responses)
|
|
27
|
+
assert_equal([
|
|
28
|
+
'/threads/{id} get 200',
|
|
29
|
+
'/posts get 404',
|
|
30
|
+
'/posts get default',
|
|
31
|
+
'/posts post 200',
|
|
32
|
+
'/likes post 200',
|
|
33
|
+
'/likes delete 200',
|
|
34
|
+
], uncovered_responses)
|
|
35
|
+
|
|
36
|
+
@schema_coverage.update_response_coverage!('/likes', 'post', '200')
|
|
37
|
+
assert_equal([
|
|
38
|
+
'/posts get 200',
|
|
39
|
+
'/likes post 200',
|
|
40
|
+
], covered_responses)
|
|
41
|
+
assert_equal([
|
|
42
|
+
'/threads/{id} get 200',
|
|
43
|
+
'/posts get 404',
|
|
44
|
+
'/posts get default',
|
|
45
|
+
'/posts post 200',
|
|
46
|
+
'/likes delete 200',
|
|
47
|
+
], uncovered_responses)
|
|
48
|
+
|
|
49
|
+
@schema_coverage.update_response_coverage!('/likes', 'delete', '200')
|
|
50
|
+
assert_equal([
|
|
51
|
+
'/posts get 200',
|
|
52
|
+
'/likes post 200',
|
|
53
|
+
'/likes delete 200',
|
|
54
|
+
], covered_responses)
|
|
55
|
+
assert_equal([
|
|
56
|
+
'/threads/{id} get 200',
|
|
57
|
+
'/posts get 404',
|
|
58
|
+
'/posts get default',
|
|
59
|
+
'/posts post 200',
|
|
60
|
+
], uncovered_responses)
|
|
61
|
+
|
|
62
|
+
@schema_coverage.update_response_coverage!('/posts', 'get', '422')
|
|
63
|
+
assert_equal([
|
|
64
|
+
'/posts get 200',
|
|
65
|
+
'/posts get default',
|
|
66
|
+
'/likes post 200',
|
|
67
|
+
'/likes delete 200',
|
|
68
|
+
], covered_responses)
|
|
69
|
+
assert_equal([
|
|
70
|
+
'/threads/{id} get 200',
|
|
71
|
+
'/posts get 404',
|
|
72
|
+
'/posts post 200',
|
|
73
|
+
], uncovered_responses)
|
|
74
|
+
|
|
75
|
+
assert_equal({
|
|
76
|
+
'/threads/{id}' => {
|
|
77
|
+
'get' => {
|
|
78
|
+
'responses' => {
|
|
79
|
+
'200' => false,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
'/posts' => {
|
|
84
|
+
'get' => {
|
|
85
|
+
'responses' => {
|
|
86
|
+
'200' => true,
|
|
87
|
+
'404' => false,
|
|
88
|
+
'default' => true,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
'post' => {
|
|
92
|
+
'responses' => {
|
|
93
|
+
'200' => false,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
'/likes' => {
|
|
98
|
+
'post' => {
|
|
99
|
+
'responses' => {
|
|
100
|
+
'200' => true,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
'delete' => {
|
|
104
|
+
'responses' => {
|
|
105
|
+
'200' => true,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
}, @schema_coverage.report)
|
|
110
|
+
|
|
111
|
+
@schema_coverage.update_response_coverage!('/posts', 'post', '200')
|
|
112
|
+
@schema_coverage.update_response_coverage!('/posts', 'get', '404')
|
|
113
|
+
@schema_coverage.update_response_coverage!('/threads/{id}', 'get', '200')
|
|
114
|
+
assert_equal([
|
|
115
|
+
'/threads/{id} get 200',
|
|
116
|
+
'/posts get 200',
|
|
117
|
+
'/posts get 404',
|
|
118
|
+
'/posts get default',
|
|
119
|
+
'/posts post 200',
|
|
120
|
+
'/likes post 200',
|
|
121
|
+
'/likes delete 200',
|
|
122
|
+
], covered_responses)
|
|
123
|
+
assert_equal([], uncovered_responses)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe '.merge_report' do
|
|
128
|
+
it 'can merge 2 coverage reports together' do
|
|
129
|
+
report = Committee::Test::SchemaCoverage.merge_report(
|
|
130
|
+
{
|
|
131
|
+
'/posts' => {
|
|
132
|
+
'get' => {
|
|
133
|
+
'responses' => {
|
|
134
|
+
'200' => true,
|
|
135
|
+
'404' => false,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
'post' => {
|
|
139
|
+
'responses' => {
|
|
140
|
+
'200' => false,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
'/likes' => {
|
|
145
|
+
'post' => {
|
|
146
|
+
'responses' => {
|
|
147
|
+
'200' => true,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
'/posts' => {
|
|
154
|
+
'get' => {
|
|
155
|
+
'responses' => {
|
|
156
|
+
'200' => true,
|
|
157
|
+
'404' => true,
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
'post' => {
|
|
161
|
+
'responses' => {
|
|
162
|
+
'200' => false,
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
'/likes' => {
|
|
167
|
+
'post' => {
|
|
168
|
+
'responses' => {
|
|
169
|
+
'200' => false,
|
|
170
|
+
'400' => false,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
'/users' => {
|
|
175
|
+
'get' => {
|
|
176
|
+
'responses' => {
|
|
177
|
+
'200' => true,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
assert_equal({
|
|
185
|
+
'/posts' => {
|
|
186
|
+
'get' => {
|
|
187
|
+
'responses' => {
|
|
188
|
+
'200' => true,
|
|
189
|
+
'404' => true,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
'post' => {
|
|
193
|
+
'responses' => {
|
|
194
|
+
'200' => false,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
'/likes' => {
|
|
199
|
+
'post' => {
|
|
200
|
+
'responses' => {
|
|
201
|
+
'200' => true,
|
|
202
|
+
'400' => false,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
'/users' => {
|
|
207
|
+
'get' => {
|
|
208
|
+
'responses' => {
|
|
209
|
+
'200' => true,
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
}, report)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
data/test/test_helper.rb
CHANGED
|
@@ -59,6 +59,10 @@ def open_api_3_schema
|
|
|
59
59
|
@open_api_3_schema ||= Committee::Drivers.load_from_file(open_api_3_schema_path)
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
+
def open_api_3_coverage_schema
|
|
63
|
+
@open_api_3_coverage_schema ||= Committee::Drivers.load_from_file(open_api_3_coverage_schema_path)
|
|
64
|
+
end
|
|
65
|
+
|
|
62
66
|
# Don't cache this because we'll often manipulate the created hash in tests.
|
|
63
67
|
def hyper_schema_data
|
|
64
68
|
JSON.parse(File.read(hyper_schema_schema_path))
|
|
@@ -85,6 +89,10 @@ def open_api_3_schema_path
|
|
|
85
89
|
"./test/data/openapi3/normal.yaml"
|
|
86
90
|
end
|
|
87
91
|
|
|
92
|
+
def open_api_3_coverage_schema_path
|
|
93
|
+
"./test/data/openapi3/coverage.yaml"
|
|
94
|
+
end
|
|
95
|
+
|
|
88
96
|
def open_api_3_0_1_schema_path
|
|
89
97
|
"./test/data/openapi3/3_0_1.yaml"
|
|
90
98
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: committee
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brandur
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2020-
|
|
13
|
+
date: 2020-12-23 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: json_schema
|
|
@@ -238,6 +238,7 @@ files:
|
|
|
238
238
|
- lib/committee/schema_validator/open_api_3/router.rb
|
|
239
239
|
- lib/committee/schema_validator/option.rb
|
|
240
240
|
- lib/committee/test/methods.rb
|
|
241
|
+
- lib/committee/test/schema_coverage.rb
|
|
241
242
|
- lib/committee/validation_error.rb
|
|
242
243
|
- test/bin/committee_stub_test.rb
|
|
243
244
|
- test/bin_test.rb
|
|
@@ -268,6 +269,7 @@ files:
|
|
|
268
269
|
- test/schema_validator/open_api_3/response_validator_test.rb
|
|
269
270
|
- test/test/methods_new_version_test.rb
|
|
270
271
|
- test/test/methods_test.rb
|
|
272
|
+
- test/test/schema_coverage_test.rb
|
|
271
273
|
- test/test_helper.rb
|
|
272
274
|
- test/validation_error_test.rb
|
|
273
275
|
homepage: https://github.com/interagent/committee
|