committee 2.0.0.pre → 2.0.0.pre2
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/bin/committee_stub.rb +3 -4
- data/lib/committee/drivers/open_api_2.rb +81 -33
- data/test/drivers/open_api_2_test.rb +44 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c27dbbfbcb3d316bd61c7056fe0a8f7fec175ab6
|
4
|
+
data.tar.gz: c3ad5a80a63987ae2f94988ed12b1285e71ee760
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86f1c3e718e6dee210e3c42ba2d1a5ba0b029137adc1be572d5dac9d6048dc7c84cf4274a652360473b9e263662912f5a7a94fc27b2666daf054530f0b44c40f
|
7
|
+
data.tar.gz: 6dd6d2dc9165ea38e3df05a0d35915809a82447a5708728c192d22ee632692448f6e4996733c165c8f0d6f4895dff7bfa18b952c070b2a8bb1e01d21073ad7c7
|
@@ -6,13 +6,15 @@ module Committee
|
|
6
6
|
class CommitteeStub
|
7
7
|
# Gets a Rack app suitable for use as a stub.
|
8
8
|
def get_app(schema, options)
|
9
|
+
cache = {}
|
10
|
+
|
9
11
|
Rack::Builder.new {
|
10
12
|
unless options[:tolerant]
|
11
13
|
use Committee::Middleware::RequestValidation, schema: schema
|
12
14
|
use Committee::Middleware::ResponseValidation, schema: schema
|
13
15
|
end
|
14
16
|
|
15
|
-
use Committee::Middleware::Stub, schema: schema
|
17
|
+
use Committee::Middleware::Stub, cache: cache, schema: schema
|
16
18
|
|
17
19
|
run lambda { |_|
|
18
20
|
[404, {}, ["Not found"]]
|
@@ -53,9 +55,6 @@ module Committee
|
|
53
55
|
end
|
54
56
|
[options, parser]
|
55
57
|
end
|
56
|
-
|
57
|
-
def get_schema(driver_name, data)
|
58
|
-
end
|
59
58
|
end
|
60
59
|
end
|
61
60
|
end
|
@@ -89,43 +89,54 @@ module Committee::Drivers
|
|
89
89
|
self.link_data = link_data
|
90
90
|
end
|
91
91
|
|
92
|
+
# Returns a tuple of (schema, schema_data) where only one of the two
|
93
|
+
# values is present. This is either a full schema that's ready to go _or_
|
94
|
+
# a hash of unparsed schema data.
|
92
95
|
def call
|
93
|
-
link_schema = JsonSchema::Schema.new
|
94
|
-
link_schema.properties = {}
|
95
|
-
link_schema.required = []
|
96
|
-
|
97
96
|
if link_data["parameters"]
|
98
|
-
link_data["parameters"].
|
99
|
-
|
100
|
-
|
101
|
-
raise ArgumentError,
|
102
|
-
"Committee: no #{field} section in link data."
|
103
|
-
end
|
104
|
-
end
|
97
|
+
body_param = link_data["parameters"].detect { |p| p["in"] == "body" }
|
98
|
+
if body_param
|
99
|
+
check_required_fields!(body_param)
|
105
100
|
|
106
|
-
|
101
|
+
if link_data["parameters"].detect { |p| p["in"] == "form" } != nil
|
102
|
+
raise ArgumentError, "Committee: can't mix body parameter " \
|
103
|
+
"with form parameters."
|
104
|
+
end
|
107
105
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
106
|
+
schema_data = body_param["schema"]
|
107
|
+
[nil, schema_data]
|
108
|
+
else
|
109
|
+
link_schema = JsonSchema::Schema.new
|
110
|
+
link_schema.properties = {}
|
111
|
+
link_schema.required = []
|
112
|
+
|
113
|
+
link_data["parameters"].each do |param_data|
|
114
|
+
check_required_fields!(param_data)
|
115
|
+
|
116
|
+
param_schema = JsonSchema::Schema.new
|
117
|
+
|
118
|
+
# We could probably use more validation here, but the formats of
|
119
|
+
# OpenAPI 2 are based off of what's available in JSON schema, and
|
120
|
+
# therefore this should map over quite well.
|
121
|
+
param_schema.type = [param_data["type"]]
|
122
|
+
|
123
|
+
# And same idea: despite parameters not being schemas, the items
|
124
|
+
# key (if preset) is actually a schema that defines each item of an
|
125
|
+
# array type, so we can just reflect that directly onto our
|
126
|
+
# artifical schema.
|
127
|
+
if param_data["type"] == "array" && param_data["items"]
|
128
|
+
param_schema.items = param_data["items"]
|
129
|
+
end
|
112
130
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
if param_data["type"] == "array" && param_data["items"]
|
118
|
-
param_schema.items = param_data["items"]
|
131
|
+
link_schema.properties[param_data["name"]] = param_schema
|
132
|
+
if param_data["required"] == true
|
133
|
+
link_schema.required << param_data["name"]
|
134
|
+
end
|
119
135
|
end
|
120
136
|
|
121
|
-
link_schema
|
122
|
-
if param_data["required"] == true
|
123
|
-
link_schema.required << param_data["name"]
|
124
|
-
end
|
137
|
+
[link_schema, nil]
|
125
138
|
end
|
126
139
|
end
|
127
|
-
|
128
|
-
link_schema
|
129
140
|
end
|
130
141
|
|
131
142
|
private
|
@@ -135,6 +146,15 @@ module Committee::Drivers
|
|
135
146
|
].map(&:to_s).freeze
|
136
147
|
|
137
148
|
attr_accessor :link_data
|
149
|
+
|
150
|
+
def check_required_fields!(param_data)
|
151
|
+
LINK_REQUIRED_FIELDS.each do |field|
|
152
|
+
if !param_data[field]
|
153
|
+
raise ArgumentError,
|
154
|
+
"Committee: no #{field} section in link data."
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
138
158
|
end
|
139
159
|
|
140
160
|
class Schema < Committee::Drivers::Schema
|
@@ -219,10 +239,14 @@ module Committee::Drivers
|
|
219
239
|
# all schemas into one big hash and then parse it all at the end. After
|
220
240
|
# we parse it, go through each link and assign a proper schema object. In
|
221
241
|
# practice this comes out to somewhere on the order of 50x faster.
|
242
|
+
schemas_data = { "properties" => {} }
|
243
|
+
|
244
|
+
# Exactly the same idea, but for response schemas.
|
222
245
|
target_schemas_data = { "properties" => {} }
|
223
246
|
|
224
247
|
data['paths'].each do |path, methods|
|
225
248
|
href = schema.base_path + path
|
249
|
+
schemas_data["properties"][href] = { "properties" => {} }
|
226
250
|
target_schemas_data["properties"][href] = { "properties" => {} }
|
227
251
|
|
228
252
|
methods.each do |method, link_data|
|
@@ -236,7 +260,14 @@ module Committee::Drivers
|
|
236
260
|
|
237
261
|
# Convert the spec's parameter pseudo-schemas into JSON schemas that
|
238
262
|
# we can use for some basic request validation.
|
239
|
-
link.schema = ParameterSchemaBuilder.new(link_data).call
|
263
|
+
link.schema, schema_data = ParameterSchemaBuilder.new(link_data).call
|
264
|
+
|
265
|
+
# If data came back instead of a schema (this occurs when a route has
|
266
|
+
# a single `body` parameter instead of a collection of URL/query/form
|
267
|
+
# parameters), store it for later parsing.
|
268
|
+
if schema_data
|
269
|
+
schemas_data["properties"][href]["properties"][method] = schema_data
|
270
|
+
end
|
240
271
|
|
241
272
|
# Arbitrarily pick one response for the time being. Prefers in order:
|
242
273
|
# a 200, 201, any 3-digit numerical response, then anything at all.
|
@@ -263,15 +294,25 @@ module Committee::Drivers
|
|
263
294
|
# #parse_definitions!, but what we're doing here is prefixing references
|
264
295
|
# with a specialized internal URI so that they can reference definitions
|
265
296
|
# from another document in the store.
|
266
|
-
|
267
|
-
|
268
|
-
target_schemas =
|
269
|
-
|
297
|
+
schemas =
|
298
|
+
rewrite_references_and_parse(schemas_data, store)
|
299
|
+
target_schemas =
|
300
|
+
rewrite_references_and_parse(target_schemas_data, store)
|
270
301
|
|
271
302
|
# As noted above, now that we've parsed our aggregate response schema, go
|
272
303
|
# back through each link and them their response schema.
|
273
304
|
routes.each do |method, method_routes|
|
274
305
|
method_routes.each do |(_, link)|
|
306
|
+
# request
|
307
|
+
#
|
308
|
+
# Differs slightly from responses in that the schema may already have
|
309
|
+
# been set for endpoints with non-body parameters, so check for nil
|
310
|
+
# before we set it.
|
311
|
+
if schema = schemas.properties[link.href].properties[method]
|
312
|
+
link.schema = schema
|
313
|
+
end
|
314
|
+
|
315
|
+
# response
|
275
316
|
link.target_schema =
|
276
317
|
target_schemas.properties[link.href].properties[method]
|
277
318
|
end
|
@@ -280,6 +321,13 @@ module Committee::Drivers
|
|
280
321
|
routes
|
281
322
|
end
|
282
323
|
|
324
|
+
def rewrite_references_and_parse(schemas_data, store)
|
325
|
+
schemas = rewrite_references(schemas_data)
|
326
|
+
schemas = JsonSchema.parse!(schemas_data)
|
327
|
+
schemas.expand_references!(:store => store)
|
328
|
+
schemas
|
329
|
+
end
|
330
|
+
|
283
331
|
def rewrite_references(schema)
|
284
332
|
if schema.is_a?(Hash)
|
285
333
|
ref = schema["$ref"]
|
@@ -197,8 +197,9 @@ describe Committee::Drivers::OpenAPI2::ParameterSchemaBuilder do
|
|
197
197
|
}
|
198
198
|
]
|
199
199
|
}
|
200
|
-
schema = call(data)
|
200
|
+
schema, schema_data = call(data)
|
201
201
|
|
202
|
+
assert_equal nil, schema_data
|
202
203
|
assert_equal ["limit"], schema.properties.keys
|
203
204
|
assert_equal [], schema.required
|
204
205
|
assert_equal ["integer"], schema.properties["limit"].type
|
@@ -213,8 +214,9 @@ describe Committee::Drivers::OpenAPI2::ParameterSchemaBuilder do
|
|
213
214
|
}
|
214
215
|
]
|
215
216
|
}
|
216
|
-
schema = call(data)
|
217
|
+
schema, schema_data = call(data)
|
217
218
|
|
219
|
+
assert_equal nil, schema_data
|
218
220
|
assert_equal ["limit"], schema.required
|
219
221
|
end
|
220
222
|
|
@@ -230,12 +232,31 @@ describe Committee::Drivers::OpenAPI2::ParameterSchemaBuilder do
|
|
230
232
|
}
|
231
233
|
]
|
232
234
|
}
|
233
|
-
schema = call(data)
|
235
|
+
schema, schema_data = call(data)
|
234
236
|
|
237
|
+
assert_equal nil, schema_data
|
235
238
|
assert_equal ["array"], schema.properties["tags"].type
|
236
239
|
assert_equal({ "type" => "string" }, schema.properties["tags"].items)
|
237
240
|
end
|
238
241
|
|
242
|
+
it "returns schema data for a body parameter" do
|
243
|
+
data = {
|
244
|
+
"parameters" => [
|
245
|
+
{
|
246
|
+
"name" => "payload",
|
247
|
+
"in" => "body",
|
248
|
+
"schema" => {
|
249
|
+
"$ref" => "#/definitions/foo",
|
250
|
+
}
|
251
|
+
}
|
252
|
+
]
|
253
|
+
}
|
254
|
+
schema, schema_data = call(data)
|
255
|
+
|
256
|
+
assert_equal nil, schema
|
257
|
+
assert_equal({ "$ref" => "#/definitions/foo" }, schema_data)
|
258
|
+
end
|
259
|
+
|
239
260
|
it "requires that certain fields are present" do
|
240
261
|
data = {
|
241
262
|
"parameters" => [
|
@@ -249,6 +270,26 @@ describe Committee::Drivers::OpenAPI2::ParameterSchemaBuilder do
|
|
249
270
|
assert_equal "Committee: no name section in link data.", e.message
|
250
271
|
end
|
251
272
|
|
273
|
+
it "requires that body parameters not be mixed with form parameters" do
|
274
|
+
data = {
|
275
|
+
"parameters" => [
|
276
|
+
{
|
277
|
+
"name" => "payload",
|
278
|
+
"in" => "body",
|
279
|
+
},
|
280
|
+
{
|
281
|
+
"name" => "limit",
|
282
|
+
"in" => "form",
|
283
|
+
},
|
284
|
+
]
|
285
|
+
}
|
286
|
+
e = assert_raises ArgumentError do
|
287
|
+
call(data)
|
288
|
+
end
|
289
|
+
assert_equal "Committee: can't mix body parameter with form parameters.",
|
290
|
+
e.message
|
291
|
+
end
|
292
|
+
|
252
293
|
def call(data)
|
253
294
|
Committee::Drivers::OpenAPI2::ParameterSchemaBuilder.new(data).call
|
254
295
|
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: 2.0.0.
|
4
|
+
version: 2.0.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandur
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-10-
|
12
|
+
date: 2016-10-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json_schema
|