committee 4.1.0 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,14 +46,14 @@ describe Committee::Test::Methods do
46
46
  it "passes through a valid response" do
47
47
  @app = new_rack_app(JSON.generate([ValidApp]))
48
48
  get "/apps"
49
- assert_schema_conform
49
+ assert_schema_conform(200)
50
50
  end
51
51
 
52
52
  it "detects an invalid response Content-Type" do
53
53
  @app = new_rack_app(JSON.generate([ValidApp]), {})
54
54
  get "/apps"
55
55
  e = assert_raises(Committee::InvalidResponse) do
56
- assert_schema_conform
56
+ assert_schema_conform(200)
57
57
  end
58
58
  assert_match(/response header must be set to/i, e.message)
59
59
  end
@@ -64,7 +64,8 @@ describe Committee::Test::Methods do
64
64
  _, err = capture_io do
65
65
  assert_schema_conform
66
66
  end
67
- assert_match(/\[DEPRECATION\]/i, err)
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)
68
69
  end
69
70
  end
70
71
 
@@ -161,7 +162,8 @@ describe Committee::Test::Methods do
161
162
  _, err = capture_io do
162
163
  assert_schema_conform
163
164
  end
164
- assert_match(/\[DEPRECATION\]/i, err)
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)
165
167
  end
166
168
  end
167
169
 
@@ -227,6 +229,145 @@ describe Committee::Test::Methods do
227
229
  end
228
230
  assert_match(/`GET \/undefined` undefined in schema/i, e.message)
229
231
  end
232
+
233
+ it "raises error when path does not match prefix" do
234
+ @committee_options.merge!({prefix: '/api'})
235
+ @app = new_rack_app(JSON.generate(@correct_response))
236
+ get "/characters"
237
+ e = assert_raises(Committee::InvalidResponse) do
238
+ assert_response_schema_confirm
239
+ end
240
+ assert_match(/`GET \/characters` undefined in schema \(prefix: "\/api"\)/i, e.message)
241
+ end
242
+
243
+ describe 'coverage' do
244
+ before do
245
+ @schema_coverage = Committee::Test::SchemaCoverage.new(open_api_3_coverage_schema)
246
+ @committee_options.merge!(schema: open_api_3_coverage_schema, schema_coverage: @schema_coverage)
247
+
248
+ @app = new_rack_app(JSON.generate({ success: true }))
249
+ end
250
+ it 'records openapi coverage' do
251
+ get "/posts"
252
+ assert_response_schema_confirm
253
+ assert_equal({
254
+ '/threads/{id}' => {
255
+ 'get' => {
256
+ 'responses' => {
257
+ '200' => false,
258
+ },
259
+ },
260
+ },
261
+ '/posts' => {
262
+ 'get' => {
263
+ 'responses' => {
264
+ '200' => true,
265
+ '404' => false,
266
+ 'default' => false,
267
+ },
268
+ },
269
+ 'post' => {
270
+ 'responses' => {
271
+ '200' => false,
272
+ },
273
+ },
274
+ },
275
+ '/likes' => {
276
+ 'post' => {
277
+ 'responses' => {
278
+ '200' => false,
279
+ },
280
+ },
281
+ 'delete' => {
282
+ 'responses' => {
283
+ '200' => false,
284
+ },
285
+ },
286
+ },
287
+ }, @schema_coverage.report)
288
+ end
289
+
290
+ it 'can record openapi coverage correctly when prefix is set' do
291
+ @committee_options.merge!(prefix: '/api')
292
+ post "/api/likes"
293
+ assert_response_schema_confirm
294
+ assert_equal({
295
+ '/threads/{id}' => {
296
+ 'get' => {
297
+ 'responses' => {
298
+ '200' => false,
299
+ },
300
+ },
301
+ },
302
+ '/posts' => {
303
+ 'get' => {
304
+ 'responses' => {
305
+ '200' => false,
306
+ '404' => false,
307
+ 'default' => false,
308
+ },
309
+ },
310
+ 'post' => {
311
+ 'responses' => {
312
+ '200' => false,
313
+ },
314
+ },
315
+ },
316
+ '/likes' => {
317
+ 'post' => {
318
+ 'responses' => {
319
+ '200' => true,
320
+ },
321
+ },
322
+ 'delete' => {
323
+ 'responses' => {
324
+ '200' => false,
325
+ },
326
+ },
327
+ },
328
+ }, @schema_coverage.report)
329
+ end
330
+
331
+ it 'records openapi coverage correctly with path param' do
332
+ get "/threads/asd"
333
+ assert_response_schema_confirm
334
+ assert_equal({
335
+ '/threads/{id}' => {
336
+ 'get' => {
337
+ 'responses' => {
338
+ '200' => true,
339
+ },
340
+ },
341
+ },
342
+ '/posts' => {
343
+ 'get' => {
344
+ 'responses' => {
345
+ '200' => false,
346
+ '404' => false,
347
+ 'default' => false,
348
+ },
349
+ },
350
+ 'post' => {
351
+ 'responses' => {
352
+ '200' => false,
353
+ },
354
+ },
355
+ },
356
+ '/likes' => {
357
+ 'post' => {
358
+ 'responses' => {
359
+ '200' => false,
360
+ },
361
+ },
362
+ 'delete' => {
363
+ 'responses' => {
364
+ '200' => false,
365
+ },
366
+ },
367
+ },
368
+ }, @schema_coverage.report)
369
+ end
370
+ end
230
371
  end
231
372
  end
232
373
 
@@ -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
@@ -55,10 +55,18 @@ def open_api_2_schema
55
55
  @open_api_2_schema ||= Committee::Drivers.load_from_file(open_api_2_schema_path)
56
56
  end
57
57
 
58
+ def open_api_2_form_schema
59
+ @open_api_2_form_schema ||= Committee::Drivers.load_from_file(open_api_2_form_schema_path)
60
+ end
61
+
58
62
  def open_api_3_schema
59
63
  @open_api_3_schema ||= Committee::Drivers.load_from_file(open_api_3_schema_path)
60
64
  end
61
65
 
66
+ def open_api_3_coverage_schema
67
+ @open_api_3_coverage_schema ||= Committee::Drivers.load_from_file(open_api_3_coverage_schema_path)
68
+ end
69
+
62
70
  # Don't cache this because we'll often manipulate the created hash in tests.
63
71
  def hyper_schema_data
64
72
  JSON.parse(File.read(hyper_schema_schema_path))
@@ -69,6 +77,10 @@ def open_api_2_data
69
77
  JSON.parse(File.read(open_api_2_schema_path))
70
78
  end
71
79
 
80
+ def open_api_2_form_data
81
+ JSON.parse(File.read(open_api_2_form_schema_path))
82
+ end
83
+
72
84
  def open_api_3_data
73
85
  YAML.load_file(open_api_3_schema_path)
74
86
  end
@@ -81,10 +93,18 @@ def open_api_2_schema_path
81
93
  "./test/data/openapi2/petstore-expanded.json"
82
94
  end
83
95
 
96
+ def open_api_2_form_schema_path
97
+ "./test/data/openapi2/petstore-expanded-form.json"
98
+ end
99
+
84
100
  def open_api_3_schema_path
85
101
  "./test/data/openapi3/normal.yaml"
86
102
  end
87
103
 
104
+ def open_api_3_coverage_schema_path
105
+ "./test/data/openapi3/coverage.yaml"
106
+ end
107
+
88
108
  def open_api_3_0_1_schema_path
89
109
  "./test/data/openapi3/3_0_1.yaml"
90
110
  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.1.0
4
+ version: 4.4.0
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: 2020-06-27 00:00:00.000000000 Z
13
+ date: 2021-06-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json_schema
@@ -53,6 +53,9 @@ dependencies:
53
53
  - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: 0.11.1
56
+ - - "<"
57
+ - !ruby/object:Gem::Version
58
+ version: '1.0'
56
59
  type: :runtime
57
60
  prerelease: false
58
61
  version_requirements: !ruby/object:Gem::Requirement
@@ -60,6 +63,9 @@ dependencies:
60
63
  - - ">="
61
64
  - !ruby/object:Gem::Version
62
65
  version: 0.11.1
66
+ - - "<"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
63
69
  - !ruby/object:Gem::Dependency
64
70
  name: minitest
65
71
  requirement: !ruby/object:Gem::Requirement
@@ -146,6 +152,20 @@ dependencies:
146
152
  version: '0'
147
153
  - !ruby/object:Gem::Dependency
148
154
  name: rubocop
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "<"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.13.0
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "<"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.13.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop-performance
149
169
  requirement: !ruby/object:Gem::Requirement
150
170
  requirements:
151
171
  - - ">="
@@ -159,7 +179,21 @@ dependencies:
159
179
  - !ruby/object:Gem::Version
160
180
  version: '0'
161
181
  - !ruby/object:Gem::Dependency
162
- name: rubocop-performance
182
+ name: rubocop-minitest
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: rubocop-rake
163
197
  requirement: !ruby/object:Gem::Requirement
164
198
  requirements:
165
199
  - - ">="
@@ -186,7 +220,7 @@ dependencies:
186
220
  - - ">="
187
221
  - !ruby/object:Gem::Version
188
222
  version: '0'
189
- description:
223
+ description:
190
224
  email:
191
225
  - brandur@mutelight.org
192
226
  - geemus+github@gmail.com
@@ -238,6 +272,8 @@ files:
238
272
  - lib/committee/schema_validator/open_api_3/router.rb
239
273
  - lib/committee/schema_validator/option.rb
240
274
  - lib/committee/test/methods.rb
275
+ - lib/committee/test/schema_coverage.rb
276
+ - lib/committee/utils.rb
241
277
  - lib/committee/validation_error.rb
242
278
  - test/bin/committee_stub_test.rb
243
279
  - test/bin_test.rb
@@ -268,13 +304,14 @@ files:
268
304
  - test/schema_validator/open_api_3/response_validator_test.rb
269
305
  - test/test/methods_new_version_test.rb
270
306
  - test/test/methods_test.rb
307
+ - test/test/schema_coverage_test.rb
271
308
  - test/test_helper.rb
272
309
  - test/validation_error_test.rb
273
310
  homepage: https://github.com/interagent/committee
274
311
  licenses:
275
312
  - MIT
276
313
  metadata: {}
277
- post_install_message:
314
+ post_install_message:
278
315
  rdoc_options: []
279
316
  require_paths:
280
317
  - lib
@@ -289,8 +326,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
289
326
  - !ruby/object:Gem::Version
290
327
  version: '0'
291
328
  requirements: []
292
- rubygems_version: 3.1.2
293
- signing_key:
329
+ rubygems_version: 3.2.3
330
+ signing_key:
294
331
  specification_version: 4
295
332
  summary: A collection of Rack middleware to support JSON Schema.
296
333
  test_files: []