grape 0.7.0 → 0.8.0
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.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +5 -13
- data/.rubocop.yml +6 -6
- data/.travis.yml +11 -2
- data/CHANGELOG.md +23 -1
- data/Gemfile +11 -10
- data/Guardfile +5 -6
- data/README.md +194 -13
- data/UPGRADING.md +3 -3
- data/grape.gemspec +1 -1
- data/grape.png +0 -0
- data/lib/grape/api.rb +21 -13
- data/lib/grape/endpoint.rb +31 -13
- data/lib/grape/exceptions/validation.rb +2 -2
- data/lib/grape/locale/en.yml +2 -0
- data/lib/grape/middleware/auth/oauth2.rb +69 -65
- data/lib/grape/middleware/error.rb +4 -2
- data/lib/grape/middleware/formatter.rb +2 -2
- data/lib/grape/middleware/versioner/accept_version_header.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +3 -3
- data/lib/grape/util/hash_stack.rb +1 -1
- data/lib/grape/validations.rb +22 -8
- data/lib/grape/validations/default.rb +1 -1
- data/lib/grape/validations/exactly_one_of.rb +26 -0
- data/lib/grape/validations/mutual_exclusion.rb +25 -0
- data/lib/grape/validations/presence.rb +1 -1
- data/lib/grape/validations/regexp.rb +2 -1
- data/lib/grape/validations/values.rb +7 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +390 -333
- data/spec/grape/endpoint_spec.rb +129 -99
- data/spec/grape/entity_spec.rb +47 -27
- data/spec/grape/exceptions/invalid_formatter_spec.rb +1 -1
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -1
- data/spec/grape/exceptions/missing_mime_type_spec.rb +2 -2
- data/spec/grape/exceptions/missing_option_spec.rb +1 -1
- data/spec/grape/exceptions/unknown_options_spec.rb +1 -1
- data/spec/grape/exceptions/unknown_validator_spec.rb +1 -1
- data/spec/grape/middleware/auth/basic_spec.rb +3 -3
- data/spec/grape/middleware/auth/digest_spec.rb +4 -4
- data/spec/grape/middleware/auth/oauth2_spec.rb +11 -11
- data/spec/grape/middleware/base_spec.rb +9 -9
- data/spec/grape/middleware/error_spec.rb +4 -4
- data/spec/grape/middleware/exception_spec.rb +17 -17
- data/spec/grape/middleware/formatter_spec.rb +38 -38
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +11 -11
- data/spec/grape/middleware/versioner/header_spec.rb +39 -39
- data/spec/grape/middleware/versioner/param_spec.rb +10 -10
- data/spec/grape/middleware/versioner/path_spec.rb +7 -7
- data/spec/grape/middleware/versioner_spec.rb +4 -4
- data/spec/grape/path_spec.rb +6 -6
- data/spec/grape/util/hash_stack_spec.rb +22 -22
- data/spec/grape/validations/coerce_spec.rb +34 -34
- data/spec/grape/validations/default_spec.rb +16 -16
- data/spec/grape/validations/exactly_one_of_spec.rb +71 -0
- data/spec/grape/validations/mutual_exclusion_spec.rb +61 -0
- data/spec/grape/validations/presence_spec.rb +34 -34
- data/spec/grape/validations/regexp_spec.rb +11 -4
- data/spec/grape/validations/values_spec.rb +34 -20
- data/spec/grape/validations_spec.rb +300 -147
- data/spec/shared/versioning_examples.rb +18 -18
- data/spec/spec_helper.rb +2 -1
- metadata +81 -38
@@ -57,7 +57,7 @@ describe Grape::Middleware::Error do
|
|
57
57
|
use Grape::Middleware::Error
|
58
58
|
run ExceptionApp
|
59
59
|
end
|
60
|
-
|
60
|
+
expect { get '/' }.to raise_error
|
61
61
|
end
|
62
62
|
|
63
63
|
context 'with rescue_all set to true' do
|
@@ -67,7 +67,7 @@ describe Grape::Middleware::Error do
|
|
67
67
|
run ExceptionApp
|
68
68
|
end
|
69
69
|
get '/'
|
70
|
-
last_response.body.
|
70
|
+
expect(last_response.body).to eq("rain!")
|
71
71
|
end
|
72
72
|
|
73
73
|
it 'defaults to a 500 status' do
|
@@ -76,7 +76,7 @@ describe Grape::Middleware::Error do
|
|
76
76
|
run ExceptionApp
|
77
77
|
end
|
78
78
|
get '/'
|
79
|
-
last_response.status.
|
79
|
+
expect(last_response.status).to eq(500)
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'is possible to specify a different default status code' do
|
@@ -85,7 +85,7 @@ describe Grape::Middleware::Error do
|
|
85
85
|
run ExceptionApp
|
86
86
|
end
|
87
87
|
get '/'
|
88
|
-
last_response.status.
|
88
|
+
expect(last_response.status).to eq(500)
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'is possible to return errors in json format' do
|
@@ -94,7 +94,7 @@ describe Grape::Middleware::Error do
|
|
94
94
|
run ExceptionApp
|
95
95
|
end
|
96
96
|
get '/'
|
97
|
-
last_response.body.
|
97
|
+
expect(last_response.body).to eq('{"error":"rain!"}')
|
98
98
|
end
|
99
99
|
|
100
100
|
it 'is possible to return hash errors in json format' do
|
@@ -103,8 +103,8 @@ describe Grape::Middleware::Error do
|
|
103
103
|
run ErrorHashApp
|
104
104
|
end
|
105
105
|
get '/'
|
106
|
-
['{"error":"rain!","detail":"missing widget"}',
|
107
|
-
|
106
|
+
expect(['{"error":"rain!","detail":"missing widget"}',
|
107
|
+
'{"detail":"missing widget","error":"rain!"}']).to include(last_response.body)
|
108
108
|
end
|
109
109
|
|
110
110
|
it 'is possible to return errors in jsonapi format' do
|
@@ -113,7 +113,7 @@ describe Grape::Middleware::Error do
|
|
113
113
|
run ExceptionApp
|
114
114
|
end
|
115
115
|
get '/'
|
116
|
-
last_response.body.
|
116
|
+
expect(last_response.body).to eq('{"error":"rain!"}')
|
117
117
|
end
|
118
118
|
|
119
119
|
it 'is possible to return hash errors in jsonapi format' do
|
@@ -122,8 +122,8 @@ describe Grape::Middleware::Error do
|
|
122
122
|
run ErrorHashApp
|
123
123
|
end
|
124
124
|
get '/'
|
125
|
-
['{"error":"rain!","detail":"missing widget"}',
|
126
|
-
|
125
|
+
expect(['{"error":"rain!","detail":"missing widget"}',
|
126
|
+
'{"detail":"missing widget","error":"rain!"}']).to include(last_response.body)
|
127
127
|
end
|
128
128
|
|
129
129
|
it 'is possible to return errors in xml format' do
|
@@ -132,7 +132,7 @@ describe Grape::Middleware::Error do
|
|
132
132
|
run ExceptionApp
|
133
133
|
end
|
134
134
|
get '/'
|
135
|
-
last_response.body.
|
135
|
+
expect(last_response.body).to eq("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<error>\n <message>rain!</message>\n</error>\n")
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'is possible to return hash errors in xml format' do
|
@@ -141,8 +141,8 @@ describe Grape::Middleware::Error do
|
|
141
141
|
run ErrorHashApp
|
142
142
|
end
|
143
143
|
get '/'
|
144
|
-
["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<error>\n <detail>missing widget</detail>\n <error>rain!</error>\n</error>\n",
|
145
|
-
|
144
|
+
expect(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<error>\n <detail>missing widget</detail>\n <error>rain!</error>\n</error>\n",
|
145
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<error>\n <error>rain!</error>\n <detail>missing widget</detail>\n</error>\n"]).to include(last_response.body)
|
146
146
|
end
|
147
147
|
|
148
148
|
it 'is possible to specify a custom formatter' do
|
@@ -157,7 +157,7 @@ describe Grape::Middleware::Error do
|
|
157
157
|
run ExceptionApp
|
158
158
|
end
|
159
159
|
get '/'
|
160
|
-
last_response.body.
|
160
|
+
expect(last_response.body).to eq('{:custom_formatter=>"rain!"}')
|
161
161
|
end
|
162
162
|
|
163
163
|
it 'does not trap regular error! codes' do
|
@@ -166,7 +166,7 @@ describe Grape::Middleware::Error do
|
|
166
166
|
run AccessDeniedApp
|
167
167
|
end
|
168
168
|
get '/'
|
169
|
-
last_response.status.
|
169
|
+
expect(last_response.status).to eq(401)
|
170
170
|
end
|
171
171
|
|
172
172
|
it 'responds to custom Grape exceptions appropriately' do
|
@@ -176,8 +176,8 @@ describe Grape::Middleware::Error do
|
|
176
176
|
end
|
177
177
|
|
178
178
|
get '/'
|
179
|
-
last_response.status.
|
180
|
-
last_response.body.
|
179
|
+
expect(last_response.status).to eq(400)
|
180
|
+
expect(last_response.body).to eq('failed validation')
|
181
181
|
end
|
182
182
|
|
183
183
|
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Grape::Middleware::Formatter do
|
4
4
|
subject { Grape::Middleware::Formatter.new(app) }
|
5
|
-
before { subject.
|
5
|
+
before { allow(subject).to receive(:dup).and_return(subject) }
|
6
6
|
|
7
7
|
let(:app) { lambda { |env| [200, {}, [@body || { "foo" => "bar" }]] } }
|
8
8
|
|
@@ -10,7 +10,7 @@ describe Grape::Middleware::Formatter do
|
|
10
10
|
it 'looks at the bodies for possibly serializable data' do
|
11
11
|
@body = { "abc" => "def" }
|
12
12
|
_, _, bodies = *subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json')
|
13
|
-
bodies.each { |b| b.
|
13
|
+
bodies.each { |b| expect(b).to eq(MultiJson.dump(@body)) }
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'calls #to_json since default format is json' do
|
@@ -21,7 +21,7 @@ describe Grape::Middleware::Formatter do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').last.each { |b| b.
|
24
|
+
subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').last.each { |b| expect(b).to eq('"bar"') }
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'calls #to_json if the content type is jsonapi' do
|
@@ -32,7 +32,7 @@ describe Grape::Middleware::Formatter do
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').last.each { |b| b.
|
35
|
+
subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') }
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'calls #to_xml if the content type is xml' do
|
@@ -43,18 +43,18 @@ describe Grape::Middleware::Formatter do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').last.each { |b| b.
|
46
|
+
subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').last.each { |b| expect(b).to eq('<bar/>') }
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
context 'error handling' do
|
51
51
|
let(:formatter) { double(:formatter) }
|
52
52
|
before do
|
53
|
-
Grape::Formatter::Base.
|
53
|
+
allow(Grape::Formatter::Base).to receive(:formatter_for) { formatter }
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'rescues formatter-specific exceptions' do
|
57
|
-
formatter.
|
57
|
+
allow(formatter).to receive(:call) { raise Grape::Exceptions::InvalidFormatter.new(String, 'xml') }
|
58
58
|
|
59
59
|
expect {
|
60
60
|
catch(:error) { subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json') }
|
@@ -62,7 +62,7 @@ describe Grape::Middleware::Formatter do
|
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'does not rescue other exceptions' do
|
65
|
-
formatter.
|
65
|
+
allow(formatter).to receive(:call) { raise StandardError }
|
66
66
|
|
67
67
|
expect {
|
68
68
|
catch(:error) { subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json') }
|
@@ -74,94 +74,94 @@ describe Grape::Middleware::Formatter do
|
|
74
74
|
|
75
75
|
it 'uses the xml extension if one is provided' do
|
76
76
|
subject.call('PATH_INFO' => '/info.xml')
|
77
|
-
subject.env['api.format'].
|
77
|
+
expect(subject.env['api.format']).to eq(:xml)
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'uses the json extension if one is provided' do
|
81
81
|
subject.call('PATH_INFO' => '/info.json')
|
82
|
-
subject.env['api.format'].
|
82
|
+
expect(subject.env['api.format']).to eq(:json)
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'uses the format parameter if one is provided' do
|
86
86
|
subject.call('PATH_INFO' => '/info', 'QUERY_STRING' => 'format=json')
|
87
|
-
subject.env['api.format'].
|
87
|
+
expect(subject.env['api.format']).to eq(:json)
|
88
88
|
subject.call('PATH_INFO' => '/info', 'QUERY_STRING' => 'format=xml')
|
89
|
-
subject.env['api.format'].
|
89
|
+
expect(subject.env['api.format']).to eq(:xml)
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'uses the default format if none is provided' do
|
93
93
|
subject.call('PATH_INFO' => '/info')
|
94
|
-
subject.env['api.format'].
|
94
|
+
expect(subject.env['api.format']).to eq(:txt)
|
95
95
|
end
|
96
96
|
|
97
97
|
it 'uses the requested format if provided in headers' do
|
98
98
|
subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json')
|
99
|
-
subject.env['api.format'].
|
99
|
+
expect(subject.env['api.format']).to eq(:json)
|
100
100
|
end
|
101
101
|
|
102
102
|
it 'uses the file extension format if provided before headers' do
|
103
103
|
subject.call('PATH_INFO' => '/info.txt', 'HTTP_ACCEPT' => 'application/json')
|
104
|
-
subject.env['api.format'].
|
104
|
+
expect(subject.env['api.format']).to eq(:txt)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
108
|
context 'accept header detection' do
|
109
109
|
it 'detects from the Accept header' do
|
110
110
|
subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/xml')
|
111
|
-
subject.env['api.format'].
|
111
|
+
expect(subject.env['api.format']).to eq(:xml)
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'looks for case-indifferent headers' do
|
115
115
|
subject.call('PATH_INFO' => '/info', 'http_accept' => 'application/xml')
|
116
|
-
subject.env['api.format'].
|
116
|
+
expect(subject.env['api.format']).to eq(:xml)
|
117
117
|
end
|
118
118
|
|
119
119
|
it 'uses quality rankings to determine formats' do
|
120
120
|
subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; q=0.3,application/xml; q=1.0')
|
121
|
-
subject.env['api.format'].
|
121
|
+
expect(subject.env['api.format']).to eq(:xml)
|
122
122
|
subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; q=1.0,application/xml; q=0.3')
|
123
|
-
subject.env['api.format'].
|
123
|
+
expect(subject.env['api.format']).to eq(:json)
|
124
124
|
end
|
125
125
|
|
126
126
|
it 'handles quality rankings mixed with nothing' do
|
127
127
|
subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json,application/xml; q=1.0')
|
128
|
-
subject.env['api.format'].
|
128
|
+
expect(subject.env['api.format']).to eq(:xml)
|
129
129
|
end
|
130
130
|
|
131
131
|
it 'parses headers with other attributes' do
|
132
132
|
subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/json; abc=2.3; q=1.0,application/xml; q=0.7')
|
133
|
-
subject.env['api.format'].
|
133
|
+
expect(subject.env['api.format']).to eq(:json)
|
134
134
|
end
|
135
135
|
|
136
136
|
it 'parses headers with vendor and api version' do
|
137
137
|
subject.call('PATH_INFO' => '/info', 'HTTP_ACCEPT' => 'application/vnd.test-v1+xml')
|
138
|
-
subject.env['api.format'].
|
138
|
+
expect(subject.env['api.format']).to eq(:xml)
|
139
139
|
end
|
140
140
|
|
141
141
|
it 'parses headers with symbols as hash keys' do
|
142
142
|
subject.call('PATH_INFO' => '/info', 'http_accept' => 'application/xml', system_time: '091293')
|
143
|
-
subject.env[:system_time].
|
143
|
+
expect(subject.env[:system_time]).to eq('091293')
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
147
|
context 'content-type' do
|
148
148
|
it 'is set for json' do
|
149
149
|
_, headers, _ = subject.call('PATH_INFO' => '/info.json')
|
150
|
-
headers['Content-type'].
|
150
|
+
expect(headers['Content-type']).to eq('application/json')
|
151
151
|
end
|
152
152
|
it 'is set for xml' do
|
153
153
|
_, headers, _ = subject.call('PATH_INFO' => '/info.xml')
|
154
|
-
headers['Content-type'].
|
154
|
+
expect(headers['Content-type']).to eq('application/xml')
|
155
155
|
end
|
156
156
|
it 'is set for txt' do
|
157
157
|
_, headers, _ = subject.call('PATH_INFO' => '/info.txt')
|
158
|
-
headers['Content-type'].
|
158
|
+
expect(headers['Content-type']).to eq('text/plain')
|
159
159
|
end
|
160
160
|
it 'is set for custom' do
|
161
161
|
subject.options[:content_types] = {}
|
162
162
|
subject.options[:content_types][:custom] = 'application/x-custom'
|
163
163
|
_, headers, _ = subject.call('PATH_INFO' => '/info.custom')
|
164
|
-
headers['Content-type'].
|
164
|
+
expect(headers['Content-type']).to eq('application/x-custom')
|
165
165
|
end
|
166
166
|
end
|
167
167
|
|
@@ -171,17 +171,17 @@ describe Grape::Middleware::Formatter do
|
|
171
171
|
subject.options[:content_types][:custom] = "don't care"
|
172
172
|
subject.options[:formatters][:custom] = lambda { |obj, env| 'CUSTOM FORMAT' }
|
173
173
|
_, _, body = subject.call('PATH_INFO' => '/info.custom')
|
174
|
-
body.body.
|
174
|
+
expect(body.body).to eq(['CUSTOM FORMAT'])
|
175
175
|
end
|
176
176
|
it 'uses default json formatter' do
|
177
177
|
@body = ['blah']
|
178
178
|
_, _, body = subject.call('PATH_INFO' => '/info.json')
|
179
|
-
body.body.
|
179
|
+
expect(body.body).to eq(['["blah"]'])
|
180
180
|
end
|
181
181
|
it 'uses custom json formatter' do
|
182
182
|
subject.options[:formatters][:json] = lambda { |obj, env| 'CUSTOM JSON FORMAT' }
|
183
183
|
_, _, body = subject.call('PATH_INFO' => '/info.json')
|
184
|
-
body.body.
|
184
|
+
expect(body.body).to eq(['CUSTOM JSON FORMAT'])
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
@@ -198,8 +198,8 @@ describe Grape::Middleware::Formatter do
|
|
198
198
|
'rack.input' => io,
|
199
199
|
'CONTENT_LENGTH' => io.length
|
200
200
|
)
|
201
|
-
subject.env['rack.request.form_hash']['is_boolean'].
|
202
|
-
subject.env['rack.request.form_hash']['string'].
|
201
|
+
expect(subject.env['rack.request.form_hash']['is_boolean']).to be true
|
202
|
+
expect(subject.env['rack.request.form_hash']['string']).to eq('thing')
|
203
203
|
end
|
204
204
|
end
|
205
205
|
end
|
@@ -212,8 +212,8 @@ describe Grape::Middleware::Formatter do
|
|
212
212
|
'rack.input' => io,
|
213
213
|
'HTTP_TRANSFER_ENCODING' => 'chunked'
|
214
214
|
)
|
215
|
-
subject.env['rack.request.form_hash']['is_boolean'].
|
216
|
-
subject.env['rack.request.form_hash']['string'].
|
215
|
+
expect(subject.env['rack.request.form_hash']['is_boolean']).to be true
|
216
|
+
expect(subject.env['rack.request.form_hash']['string']).to eq('thing')
|
217
217
|
end
|
218
218
|
it "rewinds IO" do
|
219
219
|
io = StringIO.new('{"is_boolean":true,"string":"thing"}')
|
@@ -225,8 +225,8 @@ describe Grape::Middleware::Formatter do
|
|
225
225
|
'rack.input' => io,
|
226
226
|
'HTTP_TRANSFER_ENCODING' => 'chunked'
|
227
227
|
)
|
228
|
-
subject.env['rack.request.form_hash']['is_boolean'].
|
229
|
-
subject.env['rack.request.form_hash']['string'].
|
228
|
+
expect(subject.env['rack.request.form_hash']['is_boolean']).to be true
|
229
|
+
expect(subject.env['rack.request.form_hash']['string']).to eq('thing')
|
230
230
|
end
|
231
231
|
it 'parses the body from an xml #{method} and copies values into rack.request.from_hash' do
|
232
232
|
io = StringIO.new('<thing><name>Test</name></thing>')
|
@@ -237,7 +237,7 @@ describe Grape::Middleware::Formatter do
|
|
237
237
|
'rack.input' => io,
|
238
238
|
'CONTENT_LENGTH' => io.length
|
239
239
|
)
|
240
|
-
subject.env['rack.request.form_hash']['thing']['name'].
|
240
|
+
expect(subject.env['rack.request.form_hash']['thing']['name']).to eq('Test')
|
241
241
|
end
|
242
242
|
[Rack::Request::FORM_DATA_MEDIA_TYPES, Rack::Request::PARSEABLE_DATA_MEDIA_TYPES].flatten.each do |content_type|
|
243
243
|
it "ignores #{content_type}" do
|
@@ -249,7 +249,7 @@ describe Grape::Middleware::Formatter do
|
|
249
249
|
'rack.input' => io,
|
250
250
|
'CONTENT_LENGTH' => io.length
|
251
251
|
)
|
252
|
-
subject.env['rack.request.form_hash'].
|
252
|
+
expect(subject.env['rack.request.form_hash']).to be_nil
|
253
253
|
end
|
254
254
|
end
|
255
255
|
end
|
@@ -8,7 +8,7 @@ describe Grape::Middleware::Versioner::AcceptVersionHeader do
|
|
8
8
|
@options = {
|
9
9
|
version_options: {
|
10
10
|
using: :accept_version_header
|
11
|
-
}
|
11
|
+
}
|
12
12
|
}
|
13
13
|
end
|
14
14
|
|
@@ -19,14 +19,14 @@ describe Grape::Middleware::Versioner::AcceptVersionHeader do
|
|
19
19
|
|
20
20
|
it 'is set' do
|
21
21
|
status, _, env = subject.call('HTTP_ACCEPT_VERSION' => 'v1')
|
22
|
-
env['api.version'].
|
23
|
-
status.
|
22
|
+
expect(env['api.version']).to eql 'v1'
|
23
|
+
expect(status).to eq(200)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'is set if format provided' do
|
27
27
|
status, _, env = subject.call('HTTP_ACCEPT_VERSION' => 'v1')
|
28
|
-
env['api.version'].
|
29
|
-
status.
|
28
|
+
expect(env['api.version']).to eql 'v1'
|
29
|
+
expect(status).to eq(200)
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'fails with 406 Not Acceptable if version is not supported' do
|
@@ -42,14 +42,14 @@ describe Grape::Middleware::Versioner::AcceptVersionHeader do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'succeeds if :strict is not set' do
|
45
|
-
subject.call('HTTP_ACCEPT_VERSION' => '').first.
|
46
|
-
subject.call({}).first.
|
45
|
+
expect(subject.call('HTTP_ACCEPT_VERSION' => '').first).to eq(200)
|
46
|
+
expect(subject.call({}).first).to eq(200)
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'succeeds if :strict is set to false' do
|
50
50
|
@options[:version_options][:strict] = false
|
51
|
-
subject.call('HTTP_ACCEPT_VERSION' => '').first.
|
52
|
-
subject.call({}).first.
|
51
|
+
expect(subject.call('HTTP_ACCEPT_VERSION' => '').first).to eq(200)
|
52
|
+
expect(subject.call({}).first).to eq(200)
|
53
53
|
end
|
54
54
|
|
55
55
|
context 'when :strict is set' do
|
@@ -81,7 +81,7 @@ describe Grape::Middleware::Versioner::AcceptVersionHeader do
|
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'succeeds if proper header is set' do
|
84
|
-
subject.call('HTTP_ACCEPT_VERSION' => 'v1').first.
|
84
|
+
expect(subject.call('HTTP_ACCEPT_VERSION' => 'v1').first).to eq(200)
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -115,7 +115,7 @@ describe Grape::Middleware::Versioner::AcceptVersionHeader do
|
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'succeeds if proper header is set' do
|
118
|
-
subject.call('HTTP_ACCEPT_VERSION' => 'v1').first.
|
118
|
+
expect(subject.call('HTTP_ACCEPT_VERSION' => 'v1').first).to eq(200)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
@@ -8,45 +8,45 @@ describe Grape::Middleware::Versioner::Header do
|
|
8
8
|
@options = {
|
9
9
|
version_options: {
|
10
10
|
using: :header,
|
11
|
-
vendor: 'vendor'
|
12
|
-
}
|
11
|
+
vendor: 'vendor'
|
12
|
+
}
|
13
13
|
}
|
14
14
|
end
|
15
15
|
|
16
16
|
context 'api.type and api.subtype' do
|
17
17
|
it 'sets type and subtype to first choice of content type if no preference given' do
|
18
18
|
status, _, env = subject.call('HTTP_ACCEPT' => '*/*')
|
19
|
-
env['api.type'].
|
20
|
-
env['api.subtype'].
|
21
|
-
status.
|
19
|
+
expect(env['api.type']).to eql 'application'
|
20
|
+
expect(env['api.subtype']).to eql 'vnd.vendor+xml'
|
21
|
+
expect(status).to eq(200)
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'sets preferred type' do
|
25
25
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/*')
|
26
|
-
env['api.type'].
|
27
|
-
env['api.subtype'].
|
28
|
-
status.
|
26
|
+
expect(env['api.type']).to eql 'application'
|
27
|
+
expect(env['api.subtype']).to eql 'vnd.vendor+xml'
|
28
|
+
expect(status).to eq(200)
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'sets preferred type and subtype' do
|
32
32
|
status, _, env = subject.call('HTTP_ACCEPT' => 'text/plain')
|
33
|
-
env['api.type'].
|
34
|
-
env['api.subtype'].
|
35
|
-
status.
|
33
|
+
expect(env['api.type']).to eql 'text'
|
34
|
+
expect(env['api.subtype']).to eql 'plain'
|
35
|
+
expect(status).to eq(200)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
context 'api.format' do
|
40
40
|
it 'is set' do
|
41
41
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor+json')
|
42
|
-
env['api.format'].
|
43
|
-
status.
|
42
|
+
expect(env['api.format']).to eql 'json'
|
43
|
+
expect(status).to eq(200)
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'is nil if not provided' do
|
47
47
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor')
|
48
|
-
env['api.format'].
|
49
|
-
status.
|
48
|
+
expect(env['api.format']).to eql nil
|
49
|
+
expect(status).to eq(200)
|
50
50
|
end
|
51
51
|
|
52
52
|
['v1', :v1].each do |version|
|
@@ -57,14 +57,14 @@ describe Grape::Middleware::Versioner::Header do
|
|
57
57
|
|
58
58
|
it 'is set' do
|
59
59
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json')
|
60
|
-
env['api.format'].
|
61
|
-
status.
|
60
|
+
expect(env['api.format']).to eql 'json'
|
61
|
+
expect(status).to eq(200)
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'is nil if not provided' do
|
65
65
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1')
|
66
|
-
env['api.format'].
|
67
|
-
status.
|
66
|
+
expect(env['api.format']).to eql nil
|
67
|
+
expect(status).to eq(200)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
@@ -73,14 +73,14 @@ describe Grape::Middleware::Versioner::Header do
|
|
73
73
|
context 'api.vendor' do
|
74
74
|
it 'is set' do
|
75
75
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor')
|
76
|
-
env['api.vendor'].
|
77
|
-
status.
|
76
|
+
expect(env['api.vendor']).to eql 'vendor'
|
77
|
+
expect(status).to eq(200)
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'is set if format provided' do
|
81
81
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor+json')
|
82
|
-
env['api.vendor'].
|
83
|
-
status.
|
82
|
+
expect(env['api.vendor']).to eql 'vendor'
|
83
|
+
expect(status).to eq(200)
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'fails with 406 Not Acceptable if vendor is invalid' do
|
@@ -101,14 +101,14 @@ describe Grape::Middleware::Versioner::Header do
|
|
101
101
|
|
102
102
|
it 'is set' do
|
103
103
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1')
|
104
|
-
env['api.vendor'].
|
105
|
-
status.
|
104
|
+
expect(env['api.vendor']).to eql 'vendor'
|
105
|
+
expect(status).to eq(200)
|
106
106
|
end
|
107
107
|
|
108
108
|
it 'is set if format provided' do
|
109
109
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json')
|
110
|
-
env['api.vendor'].
|
111
|
-
status.
|
110
|
+
expect(env['api.vendor']).to eql 'vendor'
|
111
|
+
expect(status).to eq(200)
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'fails with 406 Not Acceptable if vendor is invalid' do
|
@@ -131,14 +131,14 @@ describe Grape::Middleware::Versioner::Header do
|
|
131
131
|
|
132
132
|
it 'is set' do
|
133
133
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1')
|
134
|
-
env['api.version'].
|
135
|
-
status.
|
134
|
+
expect(env['api.version']).to eql 'v1'
|
135
|
+
expect(status).to eq(200)
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'is set if format provided' do
|
139
139
|
status, _, env = subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json')
|
140
|
-
env['api.version'].
|
141
|
-
status.
|
140
|
+
expect(env['api.version']).to eql 'v1'
|
141
|
+
expect(status).to eq(200)
|
142
142
|
end
|
143
143
|
|
144
144
|
it 'fails with 406 Not Acceptable if version is invalid' do
|
@@ -154,14 +154,14 @@ describe Grape::Middleware::Versioner::Header do
|
|
154
154
|
end
|
155
155
|
|
156
156
|
it 'succeeds if :strict is not set' do
|
157
|
-
subject.call('HTTP_ACCEPT' => '').first.
|
158
|
-
subject.call({}).first.
|
157
|
+
expect(subject.call('HTTP_ACCEPT' => '').first).to eq(200)
|
158
|
+
expect(subject.call({}).first).to eq(200)
|
159
159
|
end
|
160
160
|
|
161
161
|
it 'succeeds if :strict is set to false' do
|
162
162
|
@options[:version_options][:strict] = false
|
163
|
-
subject.call('HTTP_ACCEPT' => '').first.
|
164
|
-
subject.call({}).first.
|
163
|
+
expect(subject.call('HTTP_ACCEPT' => '').first).to eq(200)
|
164
|
+
expect(subject.call({}).first).to eq(200)
|
165
165
|
end
|
166
166
|
|
167
167
|
context 'when :strict is set' do
|
@@ -215,7 +215,7 @@ describe Grape::Middleware::Versioner::Header do
|
|
215
215
|
end
|
216
216
|
|
217
217
|
it 'succeeds if proper header is set' do
|
218
|
-
subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first.
|
218
|
+
expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200)
|
219
219
|
end
|
220
220
|
end
|
221
221
|
|
@@ -271,7 +271,7 @@ describe Grape::Middleware::Versioner::Header do
|
|
271
271
|
end
|
272
272
|
|
273
273
|
it 'succeeds if proper header is set' do
|
274
|
-
subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first.
|
274
|
+
expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200)
|
275
275
|
end
|
276
276
|
end
|
277
277
|
|
@@ -281,11 +281,11 @@ describe Grape::Middleware::Versioner::Header do
|
|
281
281
|
end
|
282
282
|
|
283
283
|
it 'succeeds with v1' do
|
284
|
-
subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first.
|
284
|
+
expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200)
|
285
285
|
end
|
286
286
|
|
287
287
|
it 'succeeds with v2' do
|
288
|
-
subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').first.
|
288
|
+
expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').first).to eq(200)
|
289
289
|
end
|
290
290
|
|
291
291
|
it 'fails with another version' do
|