committee 1.15.0 → 2.0.0.pre

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.
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 { |_|