committee 1.15.0 → 2.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/bin/committee-stub +10 -36
  3. data/lib/committee/bin/committee_stub.rb +61 -0
  4. data/lib/committee/drivers/hyper_schema.rb +151 -0
  5. data/lib/committee/drivers/open_api_2.rb +297 -0
  6. data/lib/committee/drivers.rb +57 -0
  7. data/lib/committee/middleware/base.rb +52 -13
  8. data/lib/committee/middleware/request_validation.rb +33 -10
  9. data/lib/committee/middleware/response_validation.rb +2 -1
  10. data/lib/committee/middleware/stub.rb +24 -8
  11. data/lib/committee/request_validator.rb +1 -1
  12. data/lib/committee/response_generator.rb +58 -13
  13. data/lib/committee/response_validator.rb +32 -8
  14. data/lib/committee/router.rb +5 -33
  15. data/lib/committee/{query_params_coercer.rb → string_params_coercer.rb} +11 -6
  16. data/lib/committee/test/methods.rb +49 -12
  17. data/lib/committee.rb +15 -1
  18. data/test/bin/committee_stub_test.rb +45 -0
  19. data/test/bin_test.rb +20 -0
  20. data/test/committee_test.rb +49 -0
  21. data/test/drivers/hyper_schema_test.rb +95 -0
  22. data/test/drivers/open_api_2_test.rb +255 -0
  23. data/test/drivers_test.rb +60 -0
  24. data/test/middleware/base_test.rb +49 -5
  25. data/test/middleware/request_validation_test.rb +39 -25
  26. data/test/middleware/response_validation_test.rb +32 -20
  27. data/test/middleware/stub_test.rb +50 -19
  28. data/test/request_unpacker_test.rb +10 -0
  29. data/test/request_validator_test.rb +4 -3
  30. data/test/response_generator_test.rb +50 -6
  31. data/test/response_validator_test.rb +29 -4
  32. data/test/router_test.rb +40 -13
  33. data/test/{query_params_coercer_test.rb → string_params_coercer_test.rb} +3 -4
  34. data/test/test/methods_test.rb +44 -5
  35. data/test/test_helper.rb +59 -1
  36. metadata +62 -10
@@ -0,0 +1,49 @@
1
+ require_relative "test_helper"
2
+
3
+ describe Committee do
4
+ it "debugs based off env" do
5
+ old = ENV["COMMITTEE_DEBUG"]
6
+ begin
7
+ ENV["COMMITTEE_DEBUG"] = nil
8
+ refute Committee.debug?
9
+ ENV["COMMITTEE_DEBUG"] = "true"
10
+ assert Committee.debug?
11
+ ensure
12
+ ENV["COMMITTEE_DEBUG"] = old
13
+ end
14
+ end
15
+
16
+ it "logs debug messages to stderr" do
17
+ old_stderr = $stderr
18
+ $stderr = StringIO.new
19
+ begin
20
+ stub(Committee).debug? { false }
21
+ Committee.log_debug "blah"
22
+ assert_equal "", $stderr.string
23
+
24
+ stub(Committee).debug? { true }
25
+ Committee.log_debug "blah"
26
+ assert_equal "blah\n", $stderr.string
27
+ ensure
28
+ $stderr = old_stderr
29
+ end
30
+ end
31
+
32
+ it "warns on deprecated unless $VERBOSE is nil" do
33
+ old_stderr = $stderr
34
+ old_verbose = $VERBOSE
35
+ $stderr = StringIO.new
36
+ begin
37
+ $VERBOSE = nil
38
+ Committee.warn_deprecated "blah"
39
+ assert_equal "", $stderr.string
40
+
41
+ $VERBOSE = true
42
+ Committee.warn_deprecated "blah"
43
+ assert_equal "blah\n", $stderr.string
44
+ ensure
45
+ $stderr = old_stderr
46
+ $VERBOSE = old_verbose
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,95 @@
1
+ require_relative "../test_helper"
2
+
3
+ describe Committee::Drivers::HyperSchema do
4
+ before do
5
+ @driver = Committee::Drivers::HyperSchema.new
6
+ end
7
+
8
+ it "has a name" do
9
+ assert_equal :hyper_schema, @driver.name
10
+ end
11
+
12
+ it "has a schema class" do
13
+ assert_equal Committee::Drivers::HyperSchema::Schema, @driver.schema_class
14
+ end
15
+
16
+ it "parses a hyper-schema and builds routes" do
17
+ schema = @driver.parse(hyper_schema_data)
18
+ assert_kind_of Committee::Drivers::HyperSchema::Schema, schema
19
+ assert_equal @driver, schema.driver
20
+
21
+ assert_kind_of Hash, schema.routes
22
+ refute schema.routes.empty?
23
+ assert(schema.routes.keys.all? { |m|
24
+ ["DELETE", "GET", "PATCH", "POST", "PUT"].include?(m)
25
+ })
26
+
27
+ schema.routes.each do |(_, method_routes)|
28
+ method_routes.each do |regex, link|
29
+ assert_kind_of Regexp, regex
30
+ assert_kind_of Committee::Drivers::HyperSchema::Link, link
31
+ end
32
+ end
33
+ end
34
+
35
+ it "defaults to no path parameters" do
36
+ assert_equal false, @driver.default_path_params
37
+ end
38
+
39
+ it "defaults to no query parameters" do
40
+ assert_equal false, @driver.default_query_params
41
+ end
42
+ end
43
+
44
+ describe Committee::Drivers::HyperSchema::Link do
45
+ before do
46
+ @hyper_schema_link = JsonSchema::Schema::Link.new
47
+ @hyper_schema_link.enc_type = "application/x-www-form-urlencoded"
48
+ @hyper_schema_link.href = "/apps"
49
+ @hyper_schema_link.media_type = "application/json"
50
+ @hyper_schema_link.method = "GET"
51
+ @hyper_schema_link.parent = { "title" => "parent" }
52
+ @hyper_schema_link.rel = "instances"
53
+ @hyper_schema_link.schema = { "title" => "input" }
54
+ @hyper_schema_link.target_schema = { "title" => "target" }
55
+
56
+ @link = Committee::Drivers::HyperSchema::Link.new(@hyper_schema_link)
57
+ end
58
+
59
+ it "proxies #enc_type" do
60
+ assert_equal "application/x-www-form-urlencoded", @link.enc_type
61
+ end
62
+
63
+ it "proxies #href" do
64
+ assert_equal "/apps", @link.href
65
+ end
66
+
67
+ it "proxies #media_type" do
68
+ assert_equal "application/json", @link.media_type
69
+ end
70
+
71
+ it "proxies #method" do
72
+ assert_equal "GET", @link.method
73
+ end
74
+
75
+ it "proxies #rel" do
76
+ assert_equal "instances", @link.rel
77
+ end
78
+
79
+ it "proxies #schema" do
80
+ assert_equal @hyper_schema_link.schema, @link.schema
81
+ end
82
+
83
+ it "generates 200 #status_success for non-create" do
84
+ assert_equal 200, @link.status_success
85
+ end
86
+
87
+ it "generates 201 #status_success for create" do
88
+ @hyper_schema_link.rel = "create"
89
+ assert_equal 201, @link.status_success
90
+ end
91
+
92
+ it "proxies #target_schema" do
93
+ assert_equal @hyper_schema_link.target_schema, @link.target_schema
94
+ end
95
+ end
@@ -0,0 +1,255 @@
1
+ require_relative "../test_helper"
2
+
3
+ describe Committee::Drivers::OpenAPI2 do
4
+ before do
5
+ @driver = Committee::Drivers::OpenAPI2.new
6
+ end
7
+
8
+ it "has a name" do
9
+ assert_equal :open_api_2, @driver.name
10
+ end
11
+
12
+ it "has a schema class" do
13
+ assert_equal Committee::Drivers::OpenAPI2::Schema, @driver.schema_class
14
+ end
15
+
16
+ it "parses an OpenAPI 2 spec" do
17
+ schema = @driver.parse(open_api_2_data)
18
+ assert_kind_of Committee::Drivers::OpenAPI2::Schema, schema
19
+ assert_kind_of JsonSchema::Schema, schema.definitions
20
+ assert_equal @driver, schema.driver
21
+
22
+ assert_kind_of Hash, schema.routes
23
+ refute schema.routes.empty?
24
+ assert(schema.routes.keys.all? { |m|
25
+ ["DELETE", "GET", "PATCH", "POST", "PUT"].include?(m)
26
+ })
27
+
28
+ schema.routes.each do |(_, method_routes)|
29
+ method_routes.each do |regex, link|
30
+ assert_kind_of Regexp, regex
31
+ assert_kind_of Committee::Drivers::OpenAPI2::Link, link
32
+
33
+ # verify that we've correct generated a parameters schema for each link
34
+ if link.target_schema
35
+ assert_kind_of JsonSchema::Schema, link.schema if link.schema
36
+ end
37
+
38
+ if link.target_schema
39
+ assert_kind_of JsonSchema::Schema, link.target_schema
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ it "names capture groups into href regexes" do
46
+ schema = @driver.parse(open_api_2_data)
47
+ assert_equal %r{^\/api\/pets\/(?<id>[^\/]+)$}.inspect,
48
+ schema.routes["DELETE"][0][0].inspect
49
+ end
50
+
51
+ it "prefers a 200 response first" do
52
+ schema_data = schema_data_with_responses({
53
+ '201' => { 'schema' => { 'description' => '201 response' } },
54
+ '200' => { 'schema' => { 'description' => '200 response' } },
55
+ })
56
+
57
+ schema = @driver.parse(schema_data)
58
+ link = schema.routes['GET'][0][1]
59
+ assert_equal 200, link.status_success
60
+ assert_equal({ 'description' => '200 response' }, link.target_schema.data)
61
+ end
62
+
63
+ it "prefers a 201 response next" do
64
+ schema_data = schema_data_with_responses({
65
+ '302' => { 'schema' => { 'description' => '302 response' } },
66
+ '201' => { 'schema' => { 'description' => '201 response' } },
67
+ })
68
+
69
+ schema = @driver.parse(schema_data)
70
+ link = schema.routes['GET'][0][1]
71
+ assert_equal 201, link.status_success
72
+ assert_equal({ 'description' => '201 response' }, link.target_schema.data)
73
+ end
74
+
75
+ it "prefers any three-digit response next" do
76
+ schema_data = schema_data_with_responses({
77
+ 'default' => { 'schema' => { 'description' => 'default response' } },
78
+ '302' => { 'schema' => { 'description' => '302 response' } },
79
+ })
80
+
81
+ schema = @driver.parse(schema_data)
82
+ link = schema.routes['GET'][0][1]
83
+ assert_equal 302, link.status_success
84
+ assert_equal({ 'description' => '302 response' }, link.target_schema.data)
85
+ end
86
+
87
+ it "falls back to no response" do
88
+ schema_data = schema_data_with_responses({})
89
+
90
+ schema = @driver.parse(schema_data)
91
+ link = schema.routes['GET'][0][1]
92
+ assert_equal nil, link.status_success
93
+ assert_equal nil, link.target_schema
94
+ end
95
+
96
+ it "refuses to parse other version of OpenAPI" do
97
+ data = open_api_2_data
98
+ data['swagger'] = '3.0'
99
+ e = assert_raises(ArgumentError) do
100
+ @driver.parse(data)
101
+ end
102
+ assert_equal "Committee: driver requires OpenAPI 2.0.", e.message
103
+ end
104
+
105
+ it "refuses to parse a spec without mandatory fields" do
106
+ data = open_api_2_data
107
+ data['definitions'] = nil
108
+ e = assert_raises(ArgumentError) do
109
+ @driver.parse(data)
110
+ end
111
+ assert_equal "Committee: no definitions section in spec data.", e.message
112
+ end
113
+
114
+ it "defaults to path parameters" do
115
+ assert_equal true, @driver.default_path_params
116
+ end
117
+
118
+ it "defaults to query parameters" do
119
+ assert_equal true, @driver.default_query_params
120
+ end
121
+
122
+ def schema_data_with_responses(response_data)
123
+ {
124
+ 'swagger' => '2.0',
125
+ 'consumes' => ['application/json'],
126
+ 'produces' => ['application/json'],
127
+ 'paths' => {
128
+ '/foos' => {
129
+ 'get' => {
130
+ 'responses' => response_data,
131
+ },
132
+ },
133
+ },
134
+ 'definitions' => {},
135
+ }
136
+ end
137
+ end
138
+
139
+ describe Committee::Drivers::OpenAPI2::Link do
140
+ before do
141
+ @link = Committee::Drivers::OpenAPI2::Link.new
142
+ @link.enc_type = "application/x-www-form-urlencoded"
143
+ @link.href = "/apps"
144
+ @link.media_type = "application/json"
145
+ @link.method = "GET"
146
+ @link.status_success = 200
147
+ @link.schema = { "title" => "input" }
148
+ @link.target_schema = { "title" => "target" }
149
+ end
150
+
151
+ it "uses set #enc_type" do
152
+ assert_equal "application/x-www-form-urlencoded", @link.enc_type
153
+ end
154
+
155
+ it "uses set #href" do
156
+ assert_equal "/apps", @link.href
157
+ end
158
+
159
+ it "uses set #media_type" do
160
+ assert_equal "application/json", @link.media_type
161
+ end
162
+
163
+ it "uses set #method" do
164
+ assert_equal "GET", @link.method
165
+ end
166
+
167
+ it "proxies #rel" do
168
+ e = assert_raises do
169
+ @link.rel
170
+ end
171
+ assert_equal "Committee: rel not implemented for OpenAPI", e.message
172
+ end
173
+
174
+ it "uses set #schema" do
175
+ assert_equal({ "title" => "input" }, @link.schema)
176
+ end
177
+
178
+ it "uses set #status_success" do
179
+ assert_equal 200, @link.status_success
180
+ end
181
+
182
+ it "uses set #target_schema" do
183
+ assert_equal({ "title" => "target" }, @link.target_schema)
184
+ end
185
+ end
186
+
187
+ describe Committee::Drivers::OpenAPI2::ParameterSchemaBuilder do
188
+ before do
189
+ end
190
+
191
+ it "reflects a basic type into a schema" do
192
+ data = {
193
+ "parameters" => [
194
+ {
195
+ "name" => "limit",
196
+ "type" => "integer",
197
+ }
198
+ ]
199
+ }
200
+ schema = call(data)
201
+
202
+ assert_equal ["limit"], schema.properties.keys
203
+ assert_equal [], schema.required
204
+ assert_equal ["integer"], schema.properties["limit"].type
205
+ end
206
+
207
+ it "reflects a required property into a schema" do
208
+ data = {
209
+ "parameters" => [
210
+ {
211
+ "name" => "limit",
212
+ "required" => true,
213
+ }
214
+ ]
215
+ }
216
+ schema = call(data)
217
+
218
+ assert_equal ["limit"], schema.required
219
+ end
220
+
221
+ it "reflects an array with an items schema into a schema" do
222
+ data = {
223
+ "parameters" => [
224
+ {
225
+ "name" => "tags",
226
+ "type" => "array",
227
+ "items" => {
228
+ "type" => "string"
229
+ }
230
+ }
231
+ ]
232
+ }
233
+ schema = call(data)
234
+
235
+ assert_equal ["array"], schema.properties["tags"].type
236
+ assert_equal({ "type" => "string" }, schema.properties["tags"].items)
237
+ end
238
+
239
+ it "requires that certain fields are present" do
240
+ data = {
241
+ "parameters" => [
242
+ {
243
+ }
244
+ ]
245
+ }
246
+ e = assert_raises ArgumentError do
247
+ call(data)
248
+ end
249
+ assert_equal "Committee: no name section in link data.", e.message
250
+ end
251
+
252
+ def call(data)
253
+ Committee::Drivers::OpenAPI2::ParameterSchemaBuilder.new(data).call
254
+ end
255
+ end
@@ -0,0 +1,60 @@
1
+ require_relative "test_helper"
2
+
3
+ describe Committee::Drivers do
4
+ DRIVERS = [
5
+ :hyper_schema,
6
+ :open_api_2,
7
+ ].freeze
8
+
9
+ it "gets driver with .driver_from_name" do
10
+ DRIVERS.each do |name|
11
+ driver = Committee::Drivers.driver_from_name(name)
12
+ assert_kind_of Committee::Drivers::Driver, driver
13
+ end
14
+ end
15
+
16
+ it "raises an ArgumentError for an unknown driver with .driver_from_name" do
17
+ e = assert_raises(ArgumentError) do
18
+ Committee::Drivers.driver_from_name(:blueprint)
19
+ end
20
+ assert_equal %{Committee: unknown driver "blueprint".}, e.message
21
+ end
22
+ end
23
+
24
+ describe Committee::Drivers::Driver do
25
+ DRIVER_METHODS = {
26
+ :default_path_params => [],
27
+ :default_query_params => [],
28
+ :name => [],
29
+ :parse => [nil],
30
+ :schema_class => [],
31
+ }
32
+
33
+ it "has a set of abstract methods" do
34
+ driver = Committee::Drivers::Driver.new
35
+ DRIVER_METHODS.each do |name, args|
36
+ e = assert_raises do
37
+ driver.send(name, *args)
38
+ end
39
+ assert_equal "needs implementation", e.message,
40
+ "Incorrect error message while sending #{name}: #{e.message}"
41
+ end
42
+ end
43
+ end
44
+
45
+ describe Committee::Drivers::Schema do
46
+ SCHEMA_METHODS = {
47
+ :driver => [],
48
+ }
49
+
50
+ it "has a set of abstract methods" do
51
+ schema = Committee::Drivers::Schema.new
52
+ SCHEMA_METHODS.each do |name, args|
53
+ e = assert_raises do
54
+ schema.send(name, *args)
55
+ end
56
+ assert_equal "needs implementation", e.message,
57
+ "Incorrect error message while sending #{name}: #{e.message}"
58
+ end
59
+ end
60
+ end
@@ -7,8 +7,10 @@ describe Committee::Middleware::Base do
7
7
  @app
8
8
  end
9
9
 
10
- it "accepts schema hash" do
11
- @app = new_rack_app(schema: JSON.parse(File.read("./test/data/schema.json")))
10
+ it "accepts just a schema object" do
11
+ @app = new_rack_app(
12
+ schema: hyper_schema
13
+ )
12
14
  params = {
13
15
  "name" => "cloudnasium"
14
16
  }
@@ -17,9 +19,11 @@ describe Committee::Middleware::Base do
17
19
  assert_equal 200, last_response.status
18
20
  end
19
21
 
20
- it "accepts schema object" do
21
- schema = JsonSchema.parse!(JSON.parse(File.read("./test/data/schema.json")))
22
- @app = new_rack_app(schema: schema)
22
+ it "accepts schema string (legacy behavior)" do
23
+ mock(Committee).warn_deprecated.with_any_args
24
+ @app = new_rack_app(
25
+ schema: JSON.dump(hyper_schema_data)
26
+ )
23
27
  params = {
24
28
  "name" => "cloudnasium"
25
29
  }
@@ -28,6 +32,46 @@ describe Committee::Middleware::Base do
28
32
  assert_equal 200, last_response.status
29
33
  end
30
34
 
35
+ it "accepts schema hash (legacy behavior)" do
36
+ mock(Committee).warn_deprecated.with_any_args
37
+ @app = new_rack_app(
38
+ schema: hyper_schema_data
39
+ )
40
+ params = {
41
+ "name" => "cloudnasium"
42
+ }
43
+ header "Content-Type", "application/json"
44
+ post "/apps", JSON.generate(params)
45
+ assert_equal 200, last_response.status
46
+ end
47
+
48
+ it "accepts schema JsonSchema::Schema object (legacy behavior)" do
49
+ # Note we don't warn here because this is a recent deprecation and passing
50
+ # a schema object will not be a huge performance hit. We should probably
51
+ # start warning on the next version.
52
+
53
+ @app = new_rack_app(
54
+ schema: JsonSchema.parse!(hyper_schema_data)
55
+ )
56
+ params = {
57
+ "name" => "cloudnasium"
58
+ }
59
+ header "Content-Type", "application/json"
60
+ post "/apps", JSON.generate(params)
61
+ assert_equal 200, last_response.status
62
+ end
63
+
64
+ it "doesn't accept other schema types" do
65
+ @app = new_rack_app(
66
+ schema: 7,
67
+ )
68
+ e = assert_raises(ArgumentError) do
69
+ post "/apps"
70
+ end
71
+ assert_equal "Committee: schema expected to be a hash or an instance " +
72
+ "of Committee::Drivers::Schema.", e.message
73
+ end
74
+
31
75
  private
32
76
 
33
77
  def new_rack_app(options = {})
@@ -8,7 +8,7 @@ describe Committee::Middleware::RequestValidation do
8
8
  end
9
9
 
10
10
  it "passes through a valid request" do
11
- @app = new_rack_app
11
+ @app = new_rack_app(schema: hyper_schema)
12
12
  params = {
13
13
  "name" => "cloudnasium"
14
14
  }
@@ -18,7 +18,7 @@ describe Committee::Middleware::RequestValidation do
18
18
  end
19
19
 
20
20
  it "detects an invalid request" do
21
- @app = new_rack_app
21
+ @app = new_rack_app(schema: hyper_schema)
22
22
  header "Content-Type", "application/json"
23
23
  params = {
24
24
  "name" => 1
@@ -29,7 +29,7 @@ describe Committee::Middleware::RequestValidation do
29
29
  end
30
30
 
31
31
  it "rescues JSON errors" do
32
- @app = new_rack_app
32
+ @app = new_rack_app(schema: hyper_schema)
33
33
  header "Content-Type", "application/json"
34
34
  post "/apps", "{x:y}"
35
35
  assert_equal 400, last_response.status
@@ -37,7 +37,7 @@ describe Committee::Middleware::RequestValidation do
37
37
  end
38
38
 
39
39
  it "takes a prefix" do
40
- @app = new_rack_app(prefix: "/v1")
40
+ @app = new_rack_app(prefix: "/v1", schema: hyper_schema)
41
41
  params = {
42
42
  "name" => "cloudnasium"
43
43
  }
@@ -47,37 +47,26 @@ describe Committee::Middleware::RequestValidation do
47
47
  end
48
48
 
49
49
  it "ignores paths outside the prefix" do
50
- @app = new_rack_app(prefix: "/v1")
50
+ @app = new_rack_app(prefix: "/v1", schema: hyper_schema)
51
51
  header "Content-Type", "text/html"
52
52
  get "/hello"
53
53
  assert_equal 200, last_response.status
54
54
  end
55
55
 
56
- it "warns when sending a deprecated string" do
57
- mock(Committee).warn_deprecated.with_any_args
58
- @app = new_rack_app(schema: File.read("./test/data/schema.json"))
59
- params = {
60
- "name" => "cloudnasium"
61
- }
62
- header "Content-Type", "application/json"
63
- post "/apps", JSON.generate(params)
64
- assert_equal 200, last_response.status
65
- end
66
-
67
56
  it "routes to paths not in schema" do
68
- @app = new_rack_app
57
+ @app = new_rack_app(schema: hyper_schema)
69
58
  get "/not-a-resource"
70
59
  assert_equal 200, last_response.status
71
60
  end
72
61
 
73
62
  it "doesn't route to paths not in schema when in strict mode" do
74
- @app = new_rack_app(strict: true)
63
+ @app = new_rack_app(schema: hyper_schema, strict: true)
75
64
  get "/not-a-resource"
76
65
  assert_equal 404, last_response.status
77
66
  end
78
67
 
79
68
  it "optionally raises an error" do
80
- @app = new_rack_app(raise: true)
69
+ @app = new_rack_app(raise: true, schema: hyper_schema)
81
70
  header "Content-Type", "application/json"
82
71
  assert_raises(Committee::InvalidRequest) do
83
72
  post "/apps", "{x:y}"
@@ -85,7 +74,7 @@ describe Committee::Middleware::RequestValidation do
85
74
  end
86
75
 
87
76
  it "optionally skip content_type check" do
88
- @app = new_rack_app(check_content_type: false)
77
+ @app = new_rack_app(check_content_type: false, schema: hyper_schema)
89
78
  params = {
90
79
  "name" => "cloudnasium"
91
80
  }
@@ -95,26 +84,51 @@ describe Committee::Middleware::RequestValidation do
95
84
  end
96
85
 
97
86
  it "optionally coerces query params" do
98
- @app = new_rack_app(coerce_query_params: true)
87
+ @app = new_rack_app(coerce_query_params: true, schema: hyper_schema)
99
88
  header "Content-Type", "application/json"
100
89
  get "/search/apps", {"per_page" => "10", "query" => "cloudnasium"}
101
90
  assert_equal 200, last_response.status
102
91
  end
103
92
 
104
93
  it "still raises an error if query param coercion is not possible" do
105
- @app = new_rack_app(coerce_query_params: true)
94
+ @app = new_rack_app(coerce_query_params: true, schema: hyper_schema)
106
95
  header "Content-Type", "application/json"
107
96
  get "/search/apps", {"per_page" => "foo", "query" => "cloudnasium"}
108
97
  assert_equal 400, last_response.status
109
98
  assert_match /invalid request/i, last_response.body
110
99
  end
111
100
 
101
+ it "passes through a valid request for OpenAPI" do
102
+ @app = new_rack_app(schema: open_api_2_schema)
103
+ get "/api/pets?limit=3"
104
+ assert_equal 200, last_response.status
105
+ end
106
+
107
+ it "detects an invalid request for OpenAPI" do
108
+ @app = new_rack_app(schema: open_api_2_schema)
109
+ get "/api/pets?limit=foo"
110
+ assert_equal 400, last_response.status
111
+ assert_match /invalid request/i, last_response.body
112
+ end
113
+
114
+ it "passes through a valid request for OpenAPI including path parameters" do
115
+ @app = new_rack_app(schema: open_api_2_schema)
116
+ # not that ID is expect to be an integer
117
+ get "/api/pets/123"
118
+ assert_equal 200, last_response.status
119
+ end
120
+
121
+ it "detects an invalid request for OpenAPI including path parameters" do
122
+ @app = new_rack_app(schema: open_api_2_schema)
123
+ # not that ID is expect to be an integer
124
+ get "/api/pets/not-integer"
125
+ assert_equal 400, last_response.status
126
+ assert_match /invalid request/i, last_response.body
127
+ end
128
+
112
129
  private
113
130
 
114
131
  def new_rack_app(options = {})
115
- options = {
116
- schema: JSON.parse(File.read("./test/data/schema.json"))
117
- }.merge(options)
118
132
  Rack::Builder.new {
119
133
  use Committee::Middleware::RequestValidation, options
120
134
  run lambda { |_|