committee 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d8e95c038f0a60b8733804e45d07d86d06fe443b
4
- data.tar.gz: 50bd54f25decd41bbd3f0408a27d96945cdcbf4c
3
+ metadata.gz: 6b64e50881610fea8f1bb4ee2f0c5ec42f196d15
4
+ data.tar.gz: b1a449811bf1750b00f3dde8acd48520a42af196
5
5
  SHA512:
6
- metadata.gz: 1882ae94a7ebc433f0c477fb8af1e39c9e54315387d276ecf1d2fa9c00aea9181ea343e1ce26628d06a01d062c82fdf9ca62728ee16afab2555594d0d1d14a39
7
- data.tar.gz: 31e11c118cac2fddee6723cd56434b49e91dedd5d32203446db4de8e8843403a943ce1ff9851a918df1ca844da39ce37d94b8930e3a52f245b2d7c87844fd4cf
6
+ metadata.gz: 577dcd6f0ff08f595af7c031d3f37cd96b9186858066716b27a9d6d150141309da0ccfab324b6c03fc38784a8456b0ddb523b1c37493b29d9d6baa343ee2ef53
7
+ data.tar.gz: 4193d95a73e0af8d5e66d51a05e2cd5e500874712c1bb498b7a9f89f829c9d4fac2ec69c9c27ed79e87d6ed3977e7966d3bcd924700559aec743c6c882a8ff28
@@ -81,19 +81,66 @@ module Committee::Drivers
81
81
  # data.
82
82
  attr_accessor :target_schema
83
83
 
84
+ attr_accessor :header_schema
85
+
84
86
  def rel
85
87
  raise "Committee: rel not implemented for OpenAPI"
86
88
  end
87
89
  end
88
90
 
89
- # ParameterSchemaBuilder converts OpenAPI 2 link parameters, which are not
90
- # quite JSON schemas (but will be in OpenAPI 3) into synthetic schemas that
91
- # we can use to do some basic request validation.
92
- class ParameterSchemaBuilder
91
+ class SchemaBuilder
93
92
  def initialize(link_data)
94
93
  self.link_data = link_data
95
94
  end
96
95
 
96
+ private
97
+
98
+ LINK_REQUIRED_FIELDS = [
99
+ :name
100
+ ].map(&:to_s).freeze
101
+
102
+ attr_accessor :link_data
103
+
104
+ def check_required_fields!(param_data)
105
+ LINK_REQUIRED_FIELDS.each do |field|
106
+ if !param_data[field]
107
+ raise ArgumentError,
108
+ "Committee: no #{field} section in link data."
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ class HeaderSchemaBuilder < SchemaBuilder
115
+ def call
116
+ if link_data["parameters"]
117
+ link_schema = JsonSchema::Schema.new
118
+ link_schema.properties = {}
119
+ link_schema.required = []
120
+
121
+ header_parameters = link_data["parameters"].select { |param_data| param_data["in"] == "header" }
122
+ header_parameters.each do |param_data|
123
+ check_required_fields!(param_data)
124
+
125
+ param_schema = JsonSchema::Schema.new
126
+
127
+ param_schema.type = [param_data["type"]]
128
+
129
+ link_schema.properties[param_data["name"]] = param_schema
130
+ if param_data["required"] == true
131
+ link_schema.required << param_data["name"]
132
+ end
133
+ end
134
+
135
+ link_schema
136
+ end
137
+ end
138
+ end
139
+
140
+ # ParameterSchemaBuilder converts OpenAPI 2 link parameters, which are not
141
+ # quite JSON schemas (but will be in OpenAPI 3) into synthetic schemas that
142
+ # we can use to do some basic request validation.
143
+ class ParameterSchemaBuilder < SchemaBuilder
97
144
  # Returns a tuple of (schema, schema_data) where only one of the two
98
145
  # values is present. This is either a full schema that's ready to go _or_
99
146
  # a hash of unparsed schema data.
@@ -115,7 +162,8 @@ module Committee::Drivers
115
162
  link_schema.properties = {}
116
163
  link_schema.required = []
117
164
 
118
- link_data["parameters"].each do |param_data|
165
+ parameters = link_data["parameters"].reject { |param_data| param_data["in"] == "header" }
166
+ parameters.each do |param_data|
119
167
  check_required_fields!(param_data)
120
168
 
121
169
  param_schema = JsonSchema::Schema.new
@@ -143,23 +191,6 @@ module Committee::Drivers
143
191
  end
144
192
  end
145
193
  end
146
-
147
- private
148
-
149
- LINK_REQUIRED_FIELDS = [
150
- :name
151
- ].map(&:to_s).freeze
152
-
153
- attr_accessor :link_data
154
-
155
- def check_required_fields!(param_data)
156
- LINK_REQUIRED_FIELDS.each do |field|
157
- if !param_data[field]
158
- raise ArgumentError,
159
- "Committee: no #{field} section in link data."
160
- end
161
- end
162
- end
163
194
  end
164
195
 
165
196
  class Schema < Committee::Drivers::Schema
@@ -266,6 +297,7 @@ module Committee::Drivers
266
297
  # Convert the spec's parameter pseudo-schemas into JSON schemas that
267
298
  # we can use for some basic request validation.
268
299
  link.schema, schema_data = ParameterSchemaBuilder.new(link_data).call
300
+ link.header_schema = HeaderSchemaBuilder.new(link_data).call
269
301
 
270
302
  # If data came back instead of a schema (this occurs when a route has
271
303
  # a single `body` parameter instead of a collection of URL/query/form
@@ -5,6 +5,7 @@ module Committee::Middleware
5
5
 
6
6
  @error_class = options.fetch(:error_class, Committee::ValidationError)
7
7
  @params_key = options[:params_key] || "committee.params"
8
+ @headers_key = options[:headers_key] || "committee.headers"
8
9
  @raise = options[:raise]
9
10
  @schema = get_schema(options[:schema] ||
10
11
  raise(ArgumentError, "Committee: need option `schema`"))
@@ -6,6 +6,7 @@ module Committee::Middleware
6
6
  @allow_form_params = options.fetch(:allow_form_params, true)
7
7
  @allow_query_params = options.fetch(:allow_query_params, true)
8
8
  @check_content_type = options.fetch(:check_content_type, true)
9
+ @check_header = options.fetch(:check_header, true)
9
10
  @optimistic_json = options.fetch(:optimistic_json, false)
10
11
  @strict = options[:strict]
11
12
  @coerce_date_times = options.fetch(:coerce_date_times, false)
@@ -39,7 +40,7 @@ module Committee::Middleware
39
40
  end
40
41
  end
41
42
 
42
- request.env[@params_key] = Committee::RequestUnpacker.new(
43
+ request.env[@params_key], request.env[@headers_key] = Committee::RequestUnpacker.new(
43
44
  request,
44
45
  allow_form_params: @allow_form_params,
45
46
  allow_query_params: @allow_query_params,
@@ -51,8 +52,8 @@ module Committee::Middleware
51
52
  request.env[@params_key].merge!(param_matches) if param_matches
52
53
 
53
54
  if link
54
- validator = Committee::RequestValidator.new(link, check_content_type: @check_content_type)
55
- validator.call(request, request.env[@params_key])
55
+ validator = Committee::RequestValidator.new(link, check_content_type: @check_content_type, check_header: @check_header)
56
+ validator.call(request, request.env[@params_key], request.env[@headers_key])
56
57
 
57
58
  parameter_coerce!(request, link, @params_key)
58
59
  parameter_coerce!(request, link, "rack.request.query_hash") if !request.GET.nil? && !link.schema.nil?
@@ -40,9 +40,9 @@ module Committee
40
40
  end
41
41
 
42
42
  if @allow_query_params
43
- indifferent_params(@request.GET).merge(params)
43
+ [indifferent_params(@request.GET).merge(params), headers]
44
44
  else
45
- params
45
+ [params, headers]
46
46
  end
47
47
  end
48
48
 
@@ -87,5 +87,14 @@ module Committee
87
87
  nil
88
88
  end
89
89
  end
90
+
91
+ def headers
92
+ env = @request.env
93
+ env.keys.grep(/HTTP_/).inject({}) do |headers, key|
94
+ headerized_key = key.gsub(/^HTTP_/, '').gsub(/_/, '-')
95
+ headers[headerized_key] = env[key]
96
+ headers
97
+ end
98
+ end
90
99
  end
91
100
  end
@@ -3,12 +3,21 @@ module Committee
3
3
  def initialize(link, options = {})
4
4
  @link = link
5
5
  @check_content_type = options.fetch(:check_content_type, true)
6
+ @check_header = options.fetch(:check_header, true)
6
7
  end
7
8
 
8
- def call(request, data)
9
- check_content_type!(request, data) if @check_content_type
9
+ def call(request, params, headers)
10
+ check_content_type!(request, params) if @check_content_type
10
11
  if @link.schema
11
- valid, errors = @link.schema.validate(data)
12
+ valid, errors = @link.schema.validate(params)
13
+ if !valid
14
+ errors = JsonSchema::SchemaError.aggregate(errors).join("\n")
15
+ raise InvalidRequest, "Invalid request.\n\n#{errors}"
16
+ end
17
+ end
18
+
19
+ if @check_header && @link.respond_to?(:header_schema) && @link.header_schema
20
+ valid, errors = @link.header_schema.validate(headers)
12
21
  if !valid
13
22
  errors = JsonSchema::SchemaError.aggregate(errors).join("\n")
14
23
  raise InvalidRequest, "Invalid request.\n\n#{errors}"
@@ -298,3 +298,26 @@ describe Committee::Drivers::OpenAPI2::ParameterSchemaBuilder do
298
298
  Committee::Drivers::OpenAPI2::ParameterSchemaBuilder.new(data).call
299
299
  end
300
300
  end
301
+
302
+ describe Committee::Drivers::OpenAPI2::HeaderSchemaBuilder do
303
+ it "returns schema data for header" do
304
+ data = {
305
+ "parameters" => [
306
+ {
307
+ "name" => "AUTH_TOKEN",
308
+ "type" => "string",
309
+ "in" => "header",
310
+ }
311
+ ]
312
+ }
313
+ schema = call(data)
314
+
315
+ assert_equal ["string"], schema.properties["AUTH_TOKEN"].type
316
+ end
317
+
318
+ private
319
+
320
+ def call(data)
321
+ Committee::Drivers::OpenAPI2::HeaderSchemaBuilder.new(data).call
322
+ end
323
+ end
@@ -347,13 +347,13 @@ describe Committee::Middleware::RequestValidation do
347
347
  }
348
348
 
349
349
  @app = new_rack_app_with_lambda(check_parameter, schema: open_api_2_schema)
350
- get "/api/pets?limit=3"
350
+ get "/api/pets?limit=3", nil, { "HTTP_AUTH_TOKEN" => "xxx" }
351
351
  assert_equal 200, last_response.status
352
352
  end
353
353
 
354
354
  it "detects an invalid request for OpenAPI" do
355
355
  @app = new_rack_app(schema: open_api_2_schema)
356
- get "/api/pets?limit=foo"
356
+ get "/api/pets?limit=foo", nil, { "HTTP_AUTH_TOKEN" => "xxx" }
357
357
  assert_equal 400, last_response.status
358
358
  assert_match /invalid request/i, last_response.body
359
359
  end
@@ -7,7 +7,7 @@ describe Committee::ParameterCoercer do
7
7
  @schema = JsonSchema.parse!(hyper_schema_data)
8
8
  @schema.expand_references!
9
9
  # POST /apps/:id
10
- @link = @link = @schema.properties["app"].links[0]
10
+ @link = @schema.properties["app"].links[0]
11
11
  end
12
12
 
13
13
  it "pass datetime string" do
@@ -9,7 +9,7 @@ describe Committee::RequestUnpacker do
9
9
  "rack.input" => StringIO.new('{"x":"y"}'),
10
10
  }
11
11
  request = Rack::Request.new(env)
12
- params = Committee::RequestUnpacker.new(request).call
12
+ params, _ = Committee::RequestUnpacker.new(request).call
13
13
  assert_equal({ "x" => "y" }, params)
14
14
  end
15
15
 
@@ -18,7 +18,7 @@ describe Committee::RequestUnpacker do
18
18
  "rack.input" => StringIO.new('{"x":"y"}'),
19
19
  }
20
20
  request = Rack::Request.new(env)
21
- params = Committee::RequestUnpacker.new(request).call
21
+ params, _ = Committee::RequestUnpacker.new(request).call
22
22
  assert_equal({ "x" => "y" }, params)
23
23
  end
24
24
 
@@ -28,7 +28,7 @@ describe Committee::RequestUnpacker do
28
28
  "rack.input" => StringIO.new('{"x":"y"}'),
29
29
  }
30
30
  request = Rack::Request.new(env)
31
- params = Committee::RequestUnpacker.new(request).call
31
+ params, _ = Committee::RequestUnpacker.new(request).call
32
32
  assert_equal({}, params)
33
33
  end
34
34
 
@@ -38,7 +38,7 @@ describe Committee::RequestUnpacker do
38
38
  "rack.input" => StringIO.new('{"x":"y"}'),
39
39
  }
40
40
  request = Rack::Request.new(env)
41
- params = Committee::RequestUnpacker.new(request, optimistic_json: true).call
41
+ params, _ = Committee::RequestUnpacker.new(request, optimistic_json: true).call
42
42
  assert_equal({ "x" => "y" }, params)
43
43
  end
44
44
 
@@ -48,7 +48,7 @@ describe Committee::RequestUnpacker do
48
48
  "rack.input" => StringIO.new('x=y&foo=42'),
49
49
  }
50
50
  request = Rack::Request.new(env)
51
- params = Committee::RequestUnpacker.new(request, optimistic_json: true).call
51
+ params, _ = Committee::RequestUnpacker.new(request, optimistic_json: true).call
52
52
  assert_equal({}, params)
53
53
  end
54
54
 
@@ -58,7 +58,7 @@ describe Committee::RequestUnpacker do
58
58
  "rack.input" => StringIO.new(""),
59
59
  }
60
60
  request = Rack::Request.new(env)
61
- params = Committee::RequestUnpacker.new(request).call
61
+ params, _ = Committee::RequestUnpacker.new(request).call
62
62
  assert_equal({}, params)
63
63
  end
64
64
 
@@ -68,7 +68,7 @@ describe Committee::RequestUnpacker do
68
68
  "rack.input" => StringIO.new("x=y"),
69
69
  }
70
70
  request = Rack::Request.new(env)
71
- params = Committee::RequestUnpacker.new(request).call
71
+ params, _ = Committee::RequestUnpacker.new(request).call
72
72
  assert_equal({}, params)
73
73
  end
74
74
 
@@ -78,7 +78,7 @@ describe Committee::RequestUnpacker do
78
78
  "rack.input" => StringIO.new("x=y"),
79
79
  }
80
80
  request = Rack::Request.new(env)
81
- params = Committee::RequestUnpacker.new(request, allow_form_params: true).call
81
+ params, _ = Committee::RequestUnpacker.new(request, allow_form_params: true).call
82
82
  assert_equal({ "x" => "y" }, params)
83
83
  end
84
84
 
@@ -92,7 +92,7 @@ describe Committee::RequestUnpacker do
92
92
  "rack.input" => StringIO.new("x=1"),
93
93
  }
94
94
  request = Rack::Request.new(env)
95
- params = Committee::RequestUnpacker.new(
95
+ params, _ = Committee::RequestUnpacker.new(
96
96
  request,
97
97
  allow_form_params: true,
98
98
  coerce_form_params: true,
@@ -108,7 +108,7 @@ describe Committee::RequestUnpacker do
108
108
  "QUERY_STRING" => "a=b"
109
109
  }
110
110
  request = Rack::Request.new(env)
111
- params = Committee::RequestUnpacker.new(request, allow_form_params: true, allow_query_params: true).call
111
+ params, _ = Committee::RequestUnpacker.new(request, allow_form_params: true, allow_query_params: true).call
112
112
  assert_equal({ "x" => "y", "a" => "b" }, params)
113
113
  end
114
114
 
@@ -118,7 +118,7 @@ describe Committee::RequestUnpacker do
118
118
  "QUERY_STRING" => "a=b"
119
119
  }
120
120
  request = Rack::Request.new(env)
121
- params = Committee::RequestUnpacker.new(request, allow_query_params: true).call
121
+ params, _ = Committee::RequestUnpacker.new(request, allow_query_params: true).call
122
122
  assert_equal({ "a" => "b" }, params)
123
123
  end
124
124
 
@@ -139,7 +139,7 @@ describe Committee::RequestUnpacker do
139
139
  "rack.input" => StringIO.new('{"x":"y"}'),
140
140
  }
141
141
  request = Rack::Request.new(env)
142
- params = Committee::RequestUnpacker.new(request).call
142
+ params, _ = Committee::RequestUnpacker.new(request).call
143
143
  assert_equal({}, params)
144
144
  end
145
145
 
@@ -149,7 +149,17 @@ describe Committee::RequestUnpacker do
149
149
  "rack.input" => StringIO.new('{"x":[]}'),
150
150
  }
151
151
  request = Rack::Request.new(env)
152
- params = Committee::RequestUnpacker.new(request).call
152
+ params, _ = Committee::RequestUnpacker.new(request).call
153
153
  assert_equal({ "x" => [] }, params)
154
154
  end
155
+
156
+ it "unpacks http header" do
157
+ env = {
158
+ "HTTP_FOO_BAR" => "some header value",
159
+ "rack.input" => StringIO.new(""),
160
+ }
161
+ request = Rack::Request.new(env)
162
+ _, headers = Committee::RequestUnpacker.new(request, { allow_header_params: true }).call
163
+ assert_equal({ "FOO-BAR" => "some header value" }, headers)
164
+ end
155
165
  end
@@ -3,102 +3,147 @@ require_relative "test_helper"
3
3
  require "stringio"
4
4
 
5
5
  describe Committee::RequestValidator do
6
- before do
7
- @schema = JsonSchema.parse!(hyper_schema_data)
8
- @schema.expand_references!
9
- # POST /apps/:id
10
- @link = @link = @schema.properties["app"].links[0]
11
- @request = Rack::Request.new({
12
- "CONTENT_TYPE" => "application/json",
13
- "rack.input" => StringIO.new("{}"),
14
- "REQUEST_METHOD" => "POST"
15
- })
16
- end
6
+ describe 'HyperSchema' do
7
+ before do
8
+ @schema = JsonSchema.parse!(hyper_schema_data)
9
+ @schema.expand_references!
10
+ # POST /apps/:id
11
+ @link = @schema.properties["app"].links[0]
12
+ @request = Rack::Request.new({
13
+ "CONTENT_TYPE" => "application/json",
14
+ "rack.input" => StringIO.new("{}"),
15
+ "REQUEST_METHOD" => "POST"
16
+ })
17
+ end
17
18
 
18
- it "passes through a valid request with Content-Type options" do
19
- @headers = { "Content-Type" => "application/json; charset=utf-8" }
20
- call({})
21
- end
19
+ it "passes through a valid request with Content-Type options" do
20
+ @headers = { "Content-Type" => "application/json; charset=utf-8" }
21
+ call({})
22
+ end
22
23
 
23
- it "passes through a valid request" do
24
- data = {
25
- "name" => "heroku-api",
26
- }
27
- call(data)
28
- end
24
+ it "passes through a valid request" do
25
+ data = {
26
+ "name" => "heroku-api",
27
+ }
28
+ call(data)
29
+ end
29
30
 
30
- it "passes through a valid request with Content-Type options" do
31
- @request =
32
- Rack::Request.new({
33
- "CONTENT_TYPE" => "application/json; charset=utf-8",
34
- "rack.input" => StringIO.new("{}"),
35
- })
36
- data = {
37
- "name" => "heroku-api",
38
- }
39
- call(data)
40
- end
31
+ it "passes through a valid request with Content-Type options" do
32
+ @request =
33
+ Rack::Request.new({
34
+ "CONTENT_TYPE" => "application/json; charset=utf-8",
35
+ "rack.input" => StringIO.new("{}"),
36
+ })
37
+ data = {
38
+ "name" => "heroku-api",
39
+ }
40
+ call(data)
41
+ end
42
+
43
+ it "detects an invalid request Content-Type" do
44
+ e = assert_raises(Committee::InvalidRequest) {
45
+ @request =
46
+ Rack::Request.new({
47
+ "CONTENT_TYPE" => "application/x-www-form-urlencoded",
48
+ "rack.input" => StringIO.new("{}"),
49
+ })
50
+ call({})
51
+ }
52
+ message =
53
+ %{"Content-Type" request header must be set to "application/json".}
54
+ assert_equal message, e.message
55
+ end
41
56
 
42
- it "detects an invalid request Content-Type" do
43
- e = assert_raises(Committee::InvalidRequest) {
57
+ it "allows skipping content_type check" do
44
58
  @request =
45
59
  Rack::Request.new({
46
- "CONTENT_TYPE" => "application/x-www-form-urlencoded",
47
- "rack.input" => StringIO.new("{}"),
48
- })
49
- call({})
50
- }
51
- message =
52
- %{"Content-Type" request header must be set to "application/json".}
53
- assert_equal message, e.message
54
- end
60
+ "CONTENT_TYPE" => "application/x-www-form-urlencoded",
61
+ "rack.input" => StringIO.new("{}"),
62
+ })
63
+ call({}, {}, check_content_type: false)
64
+ end
55
65
 
56
- it "allows skipping content_type check" do
57
- @request =
58
- Rack::Request.new({
59
- "CONTENT_TYPE" => "application/x-www-form-urlencoded",
60
- "rack.input" => StringIO.new("{}"),
61
- })
62
- call({}, check_content_type: false)
63
- end
66
+ it "detects an missing parameter in GET requests" do
67
+ # GET /apps/search?query=...
68
+ @link = @schema.properties["app"].links[5]
69
+ @request = Rack::Request.new({})
70
+ e = assert_raises(Committee::InvalidRequest) do
71
+ call({})
72
+ end
73
+ message =
74
+ %{Invalid request.\n\n#: failed schema #/definitions/app/links/5/schema: "query" wasn't supplied.}
75
+ assert_equal message, e.message
76
+ end
64
77
 
65
- it "detects an missing parameter in GET requests" do
66
- # GET /apps/search?query=...
67
- @link = @link = @schema.properties["app"].links[5]
68
- @request = Rack::Request.new({})
69
- e = assert_raises(Committee::InvalidRequest) do
78
+ it "allows an invalid Content-Type with an empty body" do
79
+ @request =
80
+ Rack::Request.new({
81
+ "CONTENT_TYPE" => "application/x-www-form-urlencoded",
82
+ "rack.input" => StringIO.new(""),
83
+ })
70
84
  call({})
71
85
  end
72
- message =
73
- %{Invalid request.\n\n#: failed schema #/definitions/app/links/5/schema: "query" wasn't supplied.}
74
- assert_equal message, e.message
75
- end
76
86
 
77
- it "allows an invalid Content-Type with an empty body" do
78
- @request =
79
- Rack::Request.new({
80
- "CONTENT_TYPE" => "application/x-www-form-urlencoded",
81
- "rack.input" => StringIO.new(""),
82
- })
83
- call({})
84
- end
87
+ it "detects a parameter of the wrong pattern" do
88
+ data = {
89
+ "name" => "%@!"
90
+ }
91
+ e = assert_raises(Committee::InvalidRequest) do
92
+ call(data)
93
+ end
94
+ message = %{Invalid request.\n\n#/name: failed schema #/definitions/app/links/0/schema/properties/name: %@! does not match /^[a-z][a-z0-9-]{3,30}$/.}
95
+ assert_equal message, e.message
96
+ end
85
97
 
86
- it "detects a parameter of the wrong pattern" do
87
- data = {
88
- "name" => "%@!"
89
- }
90
- e = assert_raises(Committee::InvalidRequest) do
91
- call(data)
98
+ private
99
+
100
+ def call(data, headers={}, options={})
101
+ # hyper-schema link should be dropped into driver wrapper before it's used
102
+ link = Committee::Drivers::HyperSchema::Link.new(@link)
103
+ Committee::RequestValidator.new(link, options).call(@request, data, headers)
92
104
  end
93
- message = %{Invalid request.\n\n#/name: failed schema #/definitions/app/links/0/schema/properties/name: %@! does not match /^[a-z][a-z0-9-]{3,30}$/.}
94
- assert_equal message, e.message
95
105
  end
96
106
 
97
- private
107
+ describe 'OpenAPI 2' do
108
+ before do
109
+ @schema = open_api_2_schema
110
+ @link = @schema.routes['GET'][0][1]
111
+ @request = Rack::Request.new({
112
+ "CONTENT_TYPE" => "application/json",
113
+ "rack.input" => StringIO.new("{}"),
114
+ "REQUEST_METHOD" => "POST"
115
+ })
116
+ end
117
+
118
+
119
+ it "passes through a valid request" do
120
+ headers = {
121
+ "AUTH-TOKEN" => "xxx"
122
+ }
123
+ call({}, headers)
124
+ end
125
+
126
+ it "detects an missing header parameter in GET requests" do
127
+ @link = @schema.routes['GET'][0][1]
128
+ @request = Rack::Request.new({})
129
+ e = assert_raises(Committee::InvalidRequest) do
130
+ call({}, {})
131
+ end
132
+ message = %{Invalid request.\n\n#: failed schema : "AUTH-TOKEN" wasn't supplied.}
133
+ assert_equal message, e.message
134
+ end
98
135
 
99
- def call(data, options={})
100
- # hyper-schema link should be dropped into driver wrapper before it's used
101
- link = Committee::Drivers::HyperSchema::Link.new(@link)
102
- Committee::RequestValidator.new(link, options).call(@request, data)
136
+ it "allows skipping header schema check" do
137
+ @link = @schema.routes['GET'][0][1]
138
+ @request = Rack::Request.new({})
139
+ call({}, {}, { check_header: false })
140
+ end
141
+
142
+ private
143
+
144
+ def call(data, headers={}, options={})
145
+ # hyper-schema link should be dropped into driver wrapper before it's used
146
+ Committee::RequestValidator.new(@link, options).call(@request, data, headers)
147
+ end
103
148
  end
104
149
  end
@@ -5,7 +5,7 @@ describe Committee::StringParamsCoercer do
5
5
  @schema = JsonSchema.parse!(hyper_schema_data)
6
6
  @schema.expand_references!
7
7
  # GET /search/apps
8
- @link = @link = @schema.properties["app"].links[5]
8
+ @link = @schema.properties["app"].links[5]
9
9
  end
10
10
 
11
11
  it "doesn't coerce params not in the schema" do
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.1
4
+ version: 2.1.0
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: 2018-02-27 00:00:00.000000000 Z
12
+ date: 2018-03-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json_schema
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
212
  version: '0'
213
213
  requirements: []
214
214
  rubyforge_project:
215
- rubygems_version: 2.4.5.1
215
+ rubygems_version: 2.6.14
216
216
  signing_key:
217
217
  specification_version: 4
218
218
  summary: A collection of Rack middleware to support JSON Schema.