committee 3.3.0 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/committee.rb +2 -3
  3. data/lib/committee/drivers.rb +5 -5
  4. data/lib/committee/errors.rb +12 -0
  5. data/lib/committee/middleware/request_validation.rb +4 -8
  6. data/lib/committee/middleware/response_validation.rb +3 -7
  7. data/lib/committee/request_unpacker.rb +1 -1
  8. data/lib/committee/schema_validator/hyper_schema.rb +8 -1
  9. data/lib/committee/schema_validator/open_api_3.rb +8 -1
  10. data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +8 -4
  11. data/lib/committee/schema_validator/open_api_3/router.rb +3 -1
  12. data/lib/committee/schema_validator/option.rb +8 -1
  13. data/lib/committee/test/methods.rb +17 -8
  14. data/lib/committee/test/schema_coverage.rb +101 -0
  15. data/lib/committee/validation_error.rb +3 -2
  16. data/test/bin/committee_stub_test.rb +5 -1
  17. data/test/committee_test.rb +1 -1
  18. data/test/middleware/base_test.rb +9 -3
  19. data/test/middleware/request_validation_open_api_3_test.rb +24 -6
  20. data/test/middleware/request_validation_test.rb +7 -1
  21. data/test/middleware/response_validation_open_api_3_test.rb +48 -2
  22. data/test/middleware/response_validation_test.rb +7 -1
  23. data/test/middleware/stub_test.rb +4 -0
  24. data/test/request_unpacker_test.rb +32 -3
  25. data/test/schema_validator/hyper_schema/router_test.rb +4 -0
  26. data/test/schema_validator/open_api_3/operation_wrapper_test.rb +15 -7
  27. data/test/schema_validator/open_api_3/request_validator_test.rb +3 -0
  28. data/test/schema_validator/open_api_3/response_validator_test.rb +12 -5
  29. data/test/test/methods_new_version_test.rb +3 -0
  30. data/test/test/methods_test.rb +145 -3
  31. data/test/test/schema_coverage_test.rb +216 -0
  32. data/test/test_helper.rb +9 -1
  33. metadata +8 -6
@@ -30,6 +30,9 @@ describe Committee::Test::Methods do
30
30
  @committee_schema = nil
31
31
 
32
32
  @committee_options = {schema: hyper_schema}
33
+
34
+ # TODO: delete when 5.0.0 released because default value changed
35
+ @committee_options[:parse_response_by_content_type] = false
33
36
  end
34
37
 
35
38
  describe "#assert_schema_conform" do
@@ -28,7 +28,10 @@ describe Committee::Test::Methods do
28
28
  # our purposes here in testing the module.
29
29
  @committee_router = nil
30
30
  @committee_schema = nil
31
- @committee_options = nil
31
+ @committee_options = {}
32
+
33
+ # TODO: delete when 5.0.0 released because default value changed
34
+ @committee_options[:parse_response_by_content_type] = true
32
35
  end
33
36
 
34
37
  describe "Hyper-Schema" do
@@ -36,7 +39,7 @@ describe Committee::Test::Methods do
36
39
  sc = JsonSchema.parse!(hyper_schema_data)
37
40
  sc.expand_references!
38
41
  s = Committee::Drivers::HyperSchema::Driver.new.parse(sc)
39
- @committee_options = {schema: s}
42
+ @committee_options.merge!({schema: s})
40
43
  end
41
44
 
42
45
  describe "#assert_schema_conform" do
@@ -120,7 +123,7 @@ describe Committee::Test::Methods do
120
123
 
121
124
  describe "OpenAPI3" do
122
125
  before do
123
- @committee_options = {schema: open_api_3_schema}
126
+ @committee_options.merge!({schema: open_api_3_schema})
124
127
 
125
128
  @correct_response = { string_1: :honoka }
126
129
  end
@@ -224,6 +227,145 @@ describe Committee::Test::Methods do
224
227
  end
225
228
  assert_match(/`GET \/undefined` undefined in schema/i, e.message)
226
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
227
369
  end
228
370
  end
229
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
@@ -56,7 +56,11 @@ def open_api_2_schema
56
56
  end
57
57
 
58
58
  def open_api_3_schema
59
- @open_api_3_schema ||= Committee::Drivers.load_from_data(open_api_3_data)
59
+ @open_api_3_schema ||= Committee::Drivers.load_from_file(open_api_3_schema_path)
60
+ end
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)
60
64
  end
61
65
 
62
66
  # Don't cache this because we'll often manipulate the created hash in tests.
@@ -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: 3.3.0
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: 2019-11-15 00:00:00.000000000 Z
13
+ date: 2020-12-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json_schema
@@ -52,14 +52,14 @@ dependencies:
52
52
  requirements:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
- version: 0.6.1
55
+ version: 0.11.1
56
56
  type: :runtime
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: 0.6.1
62
+ version: 0.11.1
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: minitest
65
65
  requirement: !ruby/object:Gem::Requirement
@@ -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
@@ -282,14 +284,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
282
284
  requirements:
283
285
  - - ">="
284
286
  - !ruby/object:Gem::Version
285
- version: 2.3.0
287
+ version: 2.4.0
286
288
  required_rubygems_version: !ruby/object:Gem::Requirement
287
289
  requirements:
288
290
  - - ">="
289
291
  - !ruby/object:Gem::Version
290
292
  version: '0'
291
293
  requirements: []
292
- rubygems_version: 3.0.3
294
+ rubygems_version: 3.1.2
293
295
  signing_key:
294
296
  specification_version: 4
295
297
  summary: A collection of Rack middleware to support JSON Schema.