grape 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Appraisals +1 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +25 -25
- data/README.md +15 -4
- data/UPGRADING.md +6 -0
- data/gemfiles/multi_json.gemfile +1 -1
- data/gemfiles/multi_xml.gemfile +1 -1
- data/gemfiles/rack_1.5.2.gemfile +1 -1
- data/gemfiles/rack_edge.gemfile +1 -1
- data/gemfiles/rails_3.gemfile +1 -1
- data/gemfiles/rails_4.gemfile +1 -1
- data/gemfiles/rails_5.gemfile +1 -1
- data/gemfiles/rails_edge.gemfile +2 -2
- data/grape.gemspec +1 -1
- data/lib/grape/middleware/error.rb +4 -0
- data/lib/grape/middleware/formatter.rb +4 -2
- data/lib/grape/validations/params_scope.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/pkg/grape-0.17.0.gem +0 -0
- data/pkg/grape-0.19.0.gem +0 -0
- data/spec/grape/api_spec.rb +26 -2
- data/spec/grape/endpoint_spec.rb +11 -7
- data/spec/grape/middleware/exception_spec.rb +4 -4
- data/spec/grape/middleware/formatter_spec.rb +74 -0
- data/spec/grape/validations/params_scope_spec.rb +18 -0
- metadata +5 -4
- data/pkg/grape-1.0.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7768f2318b0b1045ec81b3a83cb08b5d80676da77aaa30f059fb056175578781
|
4
|
+
data.tar.gz: e19ecc4e39b33a19e43e7831ceab4d5a13fd186677cef84547066e48d24d98d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afc16b3f2a5036029bb22615ded000eefb2c24f396efa1f2bc22b253bb84d1adb2a4f2ea7dad63a8d4f98a0c69e7720b828072e57bd8e5ce281c1d158f25cb02
|
7
|
+
data.tar.gz: b650ba30bc697feea23a4aa03a50e525b135e25c14707b85f4e95b7a95c5ba37e1565ddce147148885467516c1a7d48e74d58cabb1172679978dcbe28216674a
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
### 1.1.0 (8/4/2018)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* [#1759](https://github.com/ruby-grape/grape/pull/1759): Instrument serialization as `'format_response.grape'` - [@zvkemp](https://github.com/zvkemp).
|
6
|
+
|
7
|
+
#### Fixes
|
8
|
+
|
9
|
+
|
10
|
+
* [#1762](https://github.com/ruby-grape/grape/pull/1763): Fix unsafe HTML rendering on errors - [@ctennis](https://github.com/ctennis).
|
11
|
+
* [#1759](https://github.com/ruby-grape/grape/pull/1759): Update appraisal for rails_edge - [@zvkemp](https://github.com/zvkemp).
|
12
|
+
* [#1758](https://github.com/ruby-grape/grape/pull/1758): Fix expanding load_path in gemspec - [@2maz](https://github.com/2maz).
|
13
|
+
* [#1765](https://github.com/ruby-grape/grape/pull/1765): Use 415 when request body is of an unsupported media type - [@jdmurphy](https://github.com/jdmurphy).
|
14
|
+
* [#1771](https://github.com/ruby-grape/grape/pull/1771): Fix param aliases with 'given' blocks - [@jereynolds](https://github.com/jereynolds).
|
15
|
+
|
1
16
|
### 1.0.3 (4/23/2018)
|
2
17
|
|
3
18
|
#### Fixes
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
grape (1.0
|
4
|
+
grape (1.1.0)
|
5
5
|
activesupport
|
6
6
|
builder
|
7
7
|
mustermann-grape (~> 1.0.0)
|
@@ -12,9 +12,9 @@ PATH
|
|
12
12
|
GEM
|
13
13
|
remote: https://rubygems.org/
|
14
14
|
specs:
|
15
|
-
activesupport (5.
|
15
|
+
activesupport (5.2.0)
|
16
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
|
-
i18n (
|
17
|
+
i18n (>= 0.7, < 2)
|
18
18
|
minitest (~> 5.1)
|
19
19
|
tzinfo (~> 1.1)
|
20
20
|
addressable (2.5.2)
|
@@ -44,9 +44,9 @@ GEM
|
|
44
44
|
cookiejar (0.3.3)
|
45
45
|
cork (0.3.0)
|
46
46
|
colored2 (~> 3.1)
|
47
|
-
coveralls (0.8.
|
47
|
+
coveralls (0.8.22)
|
48
48
|
json (>= 1.8, < 3)
|
49
|
-
simplecov (~> 0.
|
49
|
+
simplecov (~> 0.16.1)
|
50
50
|
term-ansicolor (~> 1.3)
|
51
51
|
thor (~> 0.19.4)
|
52
52
|
tins (~> 1.6)
|
@@ -72,15 +72,15 @@ GEM
|
|
72
72
|
descendants_tracker (0.0.4)
|
73
73
|
thread_safe (~> 0.3, >= 0.3.1)
|
74
74
|
diff-lcs (1.3)
|
75
|
-
docile (1.1
|
75
|
+
docile (1.3.1)
|
76
76
|
equalizer (0.0.11)
|
77
|
-
faraday (0.
|
77
|
+
faraday (0.15.2)
|
78
78
|
multipart-post (>= 1.2, < 3)
|
79
79
|
faraday-http-cache (1.3.1)
|
80
80
|
faraday (~> 0.8)
|
81
|
-
ffi (1.9.
|
81
|
+
ffi (1.9.25)
|
82
82
|
formatador (0.2.5)
|
83
|
-
git (1.
|
83
|
+
git (1.4.0)
|
84
84
|
grape-entity (0.7.1)
|
85
85
|
activesupport (>= 4.0)
|
86
86
|
multi_json (>= 1.3.2)
|
@@ -102,16 +102,16 @@ GEM
|
|
102
102
|
guard (~> 2.0)
|
103
103
|
rubocop (~> 0.20)
|
104
104
|
hashie (3.5.7)
|
105
|
-
i18n (0.
|
105
|
+
i18n (1.0.1)
|
106
106
|
concurrent-ruby (~> 1.0)
|
107
107
|
ice_nine (0.11.2)
|
108
108
|
json (2.1.0)
|
109
|
-
kramdown (1.
|
109
|
+
kramdown (1.17.0)
|
110
110
|
listen (3.1.5)
|
111
111
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
112
112
|
rb-inotify (~> 0.9, >= 0.9.7)
|
113
113
|
ruby_dep (~> 1.2)
|
114
|
-
lumberjack (1.0.
|
114
|
+
lumberjack (1.0.13)
|
115
115
|
maruku (0.7.3)
|
116
116
|
method_source (0.9.0)
|
117
117
|
mime-types (3.1)
|
@@ -120,7 +120,7 @@ GEM
|
|
120
120
|
minitest (5.11.3)
|
121
121
|
multi_json (1.13.1)
|
122
122
|
multipart-post (2.0.0)
|
123
|
-
mustermann (1.0.
|
123
|
+
mustermann (1.0.2)
|
124
124
|
mustermann-grape (1.0.0)
|
125
125
|
mustermann (~> 1.0.0)
|
126
126
|
nap (1.1.0)
|
@@ -128,18 +128,18 @@ GEM
|
|
128
128
|
notiffany (0.1.1)
|
129
129
|
nenv (~> 0.1)
|
130
130
|
shellany (~> 0.0)
|
131
|
-
octokit (4.
|
131
|
+
octokit (4.9.0)
|
132
132
|
sawyer (~> 0.8.0, >= 0.5.3)
|
133
133
|
open4 (1.3.4)
|
134
134
|
parallel (1.12.1)
|
135
|
-
parser (2.
|
136
|
-
ast (~> 2.
|
137
|
-
powerpack (0.1.
|
135
|
+
parser (2.5.1.2)
|
136
|
+
ast (~> 2.4.0)
|
137
|
+
powerpack (0.1.2)
|
138
138
|
pry (0.11.3)
|
139
139
|
coderay (~> 1.1.0)
|
140
140
|
method_source (~> 0.9.0)
|
141
|
-
public_suffix (3.0.
|
142
|
-
rack (2.0.
|
141
|
+
public_suffix (3.0.2)
|
142
|
+
rack (2.0.5)
|
143
143
|
rack-accept (0.4.5)
|
144
144
|
rack (>= 0.4)
|
145
145
|
rack-jsonp (1.3.1)
|
@@ -148,8 +148,8 @@ GEM
|
|
148
148
|
rack (>= 1.0)
|
149
149
|
rainbow (2.2.2)
|
150
150
|
rake
|
151
|
-
rake (12.3.
|
152
|
-
rb-fsevent (0.10.
|
151
|
+
rake (12.3.1)
|
152
|
+
rb-fsevent (0.10.3)
|
153
153
|
rb-inotify (0.9.10)
|
154
154
|
ffi (>= 0.5.0, < 2)
|
155
155
|
rspec (3.7.0)
|
@@ -181,8 +181,8 @@ GEM
|
|
181
181
|
addressable (>= 2.3.5, < 2.6)
|
182
182
|
faraday (~> 0.8, < 1.0)
|
183
183
|
shellany (0.0.1)
|
184
|
-
simplecov (0.
|
185
|
-
docile (~> 1.1
|
184
|
+
simplecov (0.16.1)
|
185
|
+
docile (~> 1.1)
|
186
186
|
json (>= 1.8, < 3)
|
187
187
|
simplecov-html (~> 0.10.0)
|
188
188
|
simplecov-html (0.10.2)
|
@@ -195,7 +195,7 @@ GEM
|
|
195
195
|
tins (1.16.3)
|
196
196
|
tzinfo (1.2.5)
|
197
197
|
thread_safe (~> 0.1)
|
198
|
-
unicode-display_width (1.
|
198
|
+
unicode-display_width (1.4.0)
|
199
199
|
virtus (1.0.5)
|
200
200
|
axiom-types (~> 0.1)
|
201
201
|
coercible (~> 1.0)
|
@@ -228,4 +228,4 @@ DEPENDENCIES
|
|
228
228
|
ruby-grape-danger (~> 0.1.0)
|
229
229
|
|
230
230
|
BUNDLED WITH
|
231
|
-
1.
|
231
|
+
1.16.3
|
data/README.md
CHANGED
@@ -129,6 +129,7 @@
|
|
129
129
|
- [endpoint_render.grape](#endpoint_rendergrape)
|
130
130
|
- [endpoint_run_filters.grape](#endpoint_run_filtersgrape)
|
131
131
|
- [endpoint_run_validators.grape](#endpoint_run_validatorsgrape)
|
132
|
+
- [format_response.grape](#format_responsegrape)
|
132
133
|
- [Monitoring Products](#monitoring-products)
|
133
134
|
- [Contributing to Grape](#contributing-to-grape)
|
134
135
|
- [License](#license)
|
@@ -144,7 +145,7 @@ content negotiation, versioning and much more.
|
|
144
145
|
|
145
146
|
## Stable Release
|
146
147
|
|
147
|
-
You're reading the documentation for the stable release of Grape, **1.0
|
148
|
+
You're reading the documentation for the stable release of Grape, **1.1.0**.
|
148
149
|
Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
149
150
|
|
150
151
|
## Project Resources
|
@@ -1815,8 +1816,8 @@ module SharedParams
|
|
1815
1816
|
extend Grape::API::Helpers
|
1816
1817
|
|
1817
1818
|
params :order do |options|
|
1818
|
-
optional :order_by, type:Symbol, values:options[:order_by], default:options[:default_order_by]
|
1819
|
-
optional :order, type:Symbol, values
|
1819
|
+
optional :order_by, type: Symbol, values: options[:order_by], default: options[:default_order_by]
|
1820
|
+
optional :order, type: Symbol, values: %i(asc desc), default: options[:default_order]
|
1820
1821
|
end
|
1821
1822
|
end
|
1822
1823
|
|
@@ -1825,7 +1826,7 @@ class API < Grape::API
|
|
1825
1826
|
|
1826
1827
|
desc 'Get a sorted collection.'
|
1827
1828
|
params do
|
1828
|
-
use :order, order_by
|
1829
|
+
use :order, order_by: %i(id created_at), default_order_by: :created_at, default_order: :asc
|
1829
1830
|
end
|
1830
1831
|
|
1831
1832
|
get do
|
@@ -2549,6 +2550,9 @@ Built-in formatters are the following.
|
|
2549
2550
|
* `:serializable_hash`: use object's `serializable_hash` when available, otherwise fallback to `:json`
|
2550
2551
|
* `:binary`: data will be returned "as is"
|
2551
2552
|
|
2553
|
+
If a body is present in a request to an API, with a Content-Type header value that is of an unsupported type a
|
2554
|
+
"415 Unsupported Media Type" error code will be returned by Grape.
|
2555
|
+
|
2552
2556
|
Response statuses that indicate no content as defined by [Rack](https://github.com/rack)
|
2553
2557
|
[here](https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L567)
|
2554
2558
|
will bypass serialization and the body entity - though there should be none -
|
@@ -3483,6 +3487,13 @@ The execution of validators.
|
|
3483
3487
|
* *validators* - The validators being executed
|
3484
3488
|
* *request* - The request being validated
|
3485
3489
|
|
3490
|
+
#### format_response.grape
|
3491
|
+
|
3492
|
+
Serialization or template rendering.
|
3493
|
+
|
3494
|
+
* *env* - The request environment
|
3495
|
+
* *formatter* - The formatter object (e.g., `Grape::Formatter::Json`)
|
3496
|
+
|
3486
3497
|
See the [ActiveSupport::Notifications documentation](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) for information on how to subscribe to these events.
|
3487
3498
|
|
3488
3499
|
### Monitoring Products
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
Upgrading Grape
|
2
2
|
===============
|
3
3
|
|
4
|
+
### Upgrading to >= 1.1.0
|
5
|
+
|
6
|
+
#### Changes in HTTP Response Code for Unsupported Content Type
|
7
|
+
|
8
|
+
For PUT, POST, PATCH, and DELETE requests where a non-empty body and a "Content-Type" header is supplied that is not supported by the Grape API, Grape will no longer return a 406 "Not Acceptable" HTTP status code and will instead return a 415 "Unsupported Media Type" so that the usage of HTTP status code falls more in line with the specification of [RFC 2616](https://www.ietf.org/rfc/rfc2616.txt).
|
9
|
+
|
4
10
|
### Upgrading to >= 1.0.0
|
5
11
|
|
6
12
|
#### Changes in XML and JSON Parsers
|
data/gemfiles/multi_json.gemfile
CHANGED
data/gemfiles/multi_xml.gemfile
CHANGED
data/gemfiles/rack_1.5.2.gemfile
CHANGED
data/gemfiles/rack_edge.gemfile
CHANGED
data/gemfiles/rails_3.gemfile
CHANGED
data/gemfiles/rails_4.gemfile
CHANGED
data/gemfiles/rails_5.gemfile
CHANGED
data/gemfiles/rails_edge.gemfile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem '
|
5
|
+
gem 'rails', github: 'rails/rails'
|
6
6
|
|
7
7
|
group :development, :test do
|
8
8
|
gem 'bundler'
|
@@ -22,7 +22,7 @@ end
|
|
22
22
|
group :test do
|
23
23
|
gem 'cookiejar'
|
24
24
|
gem 'coveralls', '~> 0.8.17', require: false
|
25
|
-
gem 'danger-toc', '~> 0.1.
|
25
|
+
gem 'danger-toc', '~> 0.1.2'
|
26
26
|
gem 'grape-entity', '~> 0.6'
|
27
27
|
gem 'maruku'
|
28
28
|
gem 'mime-types'
|
data/grape.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'grape/middleware/base'
|
2
|
+
require 'active_support/core_ext/string/output_safety'
|
2
3
|
|
3
4
|
module Grape
|
4
5
|
module Middleware
|
@@ -69,6 +70,9 @@ module Grape
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def rack_response(message, status = options[:default_status], headers = { Grape::Http::Headers::CONTENT_TYPE => content_type })
|
73
|
+
if headers[Grape::Http::Headers::CONTENT_TYPE] == TEXT_HTML
|
74
|
+
message = ERB::Util.html_escape(message)
|
75
|
+
end
|
72
76
|
Rack::Response.new([message], status, headers).finish
|
73
77
|
end
|
74
78
|
|
@@ -41,7 +41,9 @@ module Grape
|
|
41
41
|
else
|
42
42
|
# Allow content-type to be explicitly overwritten
|
43
43
|
formatter = fetch_formatter(headers, options)
|
44
|
-
bodymap =
|
44
|
+
bodymap = ActiveSupport::Notifications.instrument('format_response.grape', formatter: formatter, env: env) do
|
45
|
+
bodies.collect { |body| formatter.call(body, env) }
|
46
|
+
end
|
45
47
|
Rack::Response.new(bodymap, status, headers)
|
46
48
|
end
|
47
49
|
rescue Grape::Exceptions::InvalidFormatter => e
|
@@ -93,7 +95,7 @@ module Grape
|
|
93
95
|
fmt = request.media_type ? mime_types[request.media_type] : options[:default_format]
|
94
96
|
|
95
97
|
unless content_type_for(fmt)
|
96
|
-
throw :error, status:
|
98
|
+
throw :error, status: 415, message: "The provided content-type '#{request.media_type}' is not supported."
|
97
99
|
end
|
98
100
|
parser = Grape::Parser.parser_for fmt, options
|
99
101
|
if parser
|
@@ -116,7 +116,7 @@ module Grape
|
|
116
116
|
# @param attrs [Array] (see Grape::DSL::Parameters#requires)
|
117
117
|
def push_declared_params(attrs, **opts)
|
118
118
|
if lateral?
|
119
|
-
@parent.push_declared_params(attrs)
|
119
|
+
@parent.push_declared_params(attrs, opts)
|
120
120
|
else
|
121
121
|
if opts && opts[:as]
|
122
122
|
@api.route_setting(:aliased_params, @api.route_setting(:aliased_params) || [])
|
data/lib/grape/version.rb
CHANGED
Binary file
|
Binary file
|
data/spec/grape/api_spec.rb
CHANGED
@@ -2142,7 +2142,11 @@ XML
|
|
2142
2142
|
end
|
2143
2143
|
get '/excel.json'
|
2144
2144
|
expect(last_response.status).to eq(406)
|
2145
|
-
|
2145
|
+
if ActiveSupport::VERSION::MAJOR == 3
|
2146
|
+
expect(last_response.body).to eq('The requested format 'txt' is not supported.')
|
2147
|
+
else
|
2148
|
+
expect(last_response.body).to eq('The requested format 'txt' is not supported.')
|
2149
|
+
end
|
2146
2150
|
end
|
2147
2151
|
end
|
2148
2152
|
|
@@ -3524,7 +3528,27 @@ XML
|
|
3524
3528
|
end
|
3525
3529
|
get '/something'
|
3526
3530
|
expect(last_response.status).to eq(406)
|
3527
|
-
|
3531
|
+
if ActiveSupport::VERSION::MAJOR == 3
|
3532
|
+
expect(last_response.body).to eq('{"error":"The requested format 'txt' is not supported."}')
|
3533
|
+
else
|
3534
|
+
expect(last_response.body).to eq('{"error":"The requested format 'txt' is not supported."}')
|
3535
|
+
end
|
3536
|
+
end
|
3537
|
+
end
|
3538
|
+
|
3539
|
+
context 'with unsafe HTML format specified' do
|
3540
|
+
it 'escapes the HTML' do
|
3541
|
+
subject.content_type :json, 'application/json'
|
3542
|
+
subject.get '/something' do
|
3543
|
+
'foo'
|
3544
|
+
end
|
3545
|
+
get '/something?format=<script>blah</script>'
|
3546
|
+
expect(last_response.status).to eq(406)
|
3547
|
+
if ActiveSupport::VERSION::MAJOR == 3
|
3548
|
+
expect(last_response.body).to eq('The requested format '<script>blah</script>' is not supported.')
|
3549
|
+
else
|
3550
|
+
expect(last_response.body).to eq('The requested format '<script>blah</script>' is not supported.')
|
3551
|
+
end
|
3528
3552
|
end
|
3529
3553
|
end
|
3530
3554
|
|
data/spec/grape/endpoint_spec.rb
CHANGED
@@ -941,15 +941,15 @@ describe Grape::Endpoint do
|
|
941
941
|
end
|
942
942
|
end
|
943
943
|
|
944
|
-
it 'responds with a
|
944
|
+
it 'responds with a 415 for an unsupported content-type' do
|
945
945
|
subject.format :json
|
946
946
|
# subject.content_type :json, "application/json"
|
947
947
|
subject.put '/request_body' do
|
948
948
|
params[:user]
|
949
949
|
end
|
950
950
|
put '/request_body', '<user>Bobby T.</user>', 'CONTENT_TYPE' => 'application/xml'
|
951
|
-
expect(last_response.status).to eq(
|
952
|
-
expect(last_response.body).to eq('{"error":"The
|
951
|
+
expect(last_response.status).to eq(415)
|
952
|
+
expect(last_response.body).to eq('{"error":"The provided content-type \'application/xml\' is not supported."}')
|
953
953
|
end
|
954
954
|
|
955
955
|
it 'does not accept text/plain in JSON format if application/json is specified as content type' do
|
@@ -960,8 +960,8 @@ describe Grape::Endpoint do
|
|
960
960
|
end
|
961
961
|
put '/request_body', ::Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'text/plain'
|
962
962
|
|
963
|
-
expect(last_response.status).to eq(
|
964
|
-
expect(last_response.body).to eq('{"error":"The
|
963
|
+
expect(last_response.status).to eq(415)
|
964
|
+
expect(last_response.body).to eq('{"error":"The provided content-type \'text/plain\' is not supported."}')
|
965
965
|
end
|
966
966
|
|
967
967
|
context 'content type with params' do
|
@@ -1493,7 +1493,9 @@ describe Grape::Endpoint do
|
|
1493
1493
|
filters: [],
|
1494
1494
|
type: :after }),
|
1495
1495
|
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(Grape::Endpoint),
|
1496
|
-
env: an_instance_of(Hash) })
|
1496
|
+
env: an_instance_of(Hash) }),
|
1497
|
+
have_attributes(name: 'format_response.grape', payload: { env: an_instance_of(Hash),
|
1498
|
+
formatter: a_kind_of(Module) })
|
1497
1499
|
)
|
1498
1500
|
|
1499
1501
|
# In order that events were initialized
|
@@ -1515,7 +1517,9 @@ describe Grape::Endpoint do
|
|
1515
1517
|
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(Grape::Endpoint) }),
|
1516
1518
|
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(Grape::Endpoint),
|
1517
1519
|
filters: [],
|
1518
|
-
type: :after })
|
1520
|
+
type: :after }),
|
1521
|
+
have_attributes(name: 'format_response.grape', payload: { env: an_instance_of(Hash),
|
1522
|
+
formatter: a_kind_of(Module) })
|
1519
1523
|
)
|
1520
1524
|
end
|
1521
1525
|
end
|
@@ -192,7 +192,7 @@ describe Grape::Middleware::Error do
|
|
192
192
|
end
|
193
193
|
it 'is possible to return errors in jsonapi format' do
|
194
194
|
get '/'
|
195
|
-
expect(last_response.body).to eq('{
|
195
|
+
expect(last_response.body).to eq('{"error":"rain!"}')
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
@@ -207,8 +207,8 @@ describe Grape::Middleware::Error do
|
|
207
207
|
|
208
208
|
it 'is possible to return hash errors in jsonapi format' do
|
209
209
|
get '/'
|
210
|
-
expect(['{
|
211
|
-
'{
|
210
|
+
expect(['{"error":"rain!","detail":"missing widget"}',
|
211
|
+
'{"detail":"missing widget","error":"rain!"}']).to include(last_response.body)
|
212
212
|
end
|
213
213
|
end
|
214
214
|
|
@@ -258,7 +258,7 @@ describe Grape::Middleware::Error do
|
|
258
258
|
end
|
259
259
|
it 'is possible to specify a custom formatter' do
|
260
260
|
get '/'
|
261
|
-
expect(last_response.body).to eq('{:custom_formatter
|
261
|
+
expect(last_response.body).to eq('{:custom_formatter=>"rain!"}')
|
262
262
|
end
|
263
263
|
end
|
264
264
|
|
@@ -224,6 +224,80 @@ describe Grape::Middleware::Formatter do
|
|
224
224
|
|
225
225
|
context 'input' do
|
226
226
|
%w[POST PATCH PUT DELETE].each do |method|
|
227
|
+
context 'when body is not nil or empty' do
|
228
|
+
context 'when Content-Type is supported' do
|
229
|
+
let(:io) { StringIO.new('{"is_boolean":true,"string":"thing"}') }
|
230
|
+
let(:content_type) { 'application/json' }
|
231
|
+
|
232
|
+
it "parses the body from #{method} and copies values into rack.request.form_hash" do
|
233
|
+
subject.call(
|
234
|
+
'PATH_INFO' => '/info',
|
235
|
+
'REQUEST_METHOD' => method,
|
236
|
+
'CONTENT_TYPE' => content_type,
|
237
|
+
'rack.input' => io,
|
238
|
+
'CONTENT_LENGTH' => io.length
|
239
|
+
)
|
240
|
+
expect(subject.env['rack.request.form_hash']['is_boolean']).to be true
|
241
|
+
expect(subject.env['rack.request.form_hash']['string']).to eq('thing')
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'when Content-Type is not supported' do
|
246
|
+
let(:io) { StringIO.new('{"is_boolean":true,"string":"thing"}') }
|
247
|
+
let(:content_type) { 'application/atom+xml' }
|
248
|
+
|
249
|
+
it 'returns a 415 HTTP error status' do
|
250
|
+
error = catch(:error) {
|
251
|
+
subject.call(
|
252
|
+
'PATH_INFO' => '/info',
|
253
|
+
'REQUEST_METHOD' => method,
|
254
|
+
'CONTENT_TYPE' => content_type,
|
255
|
+
'rack.input' => io,
|
256
|
+
'CONTENT_LENGTH' => io.length
|
257
|
+
)
|
258
|
+
}
|
259
|
+
expect(error[:status]).to eq(415)
|
260
|
+
expect(error[:message]).to eq("The provided content-type 'application/atom+xml' is not supported.")
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context 'when body is nil' do
|
266
|
+
let(:io) { double }
|
267
|
+
before do
|
268
|
+
allow(io).to receive_message_chain(:rewind, :read).and_return(nil)
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'does not read and parse the body' do
|
272
|
+
expect(subject).not_to receive(:read_rack_input)
|
273
|
+
subject.call(
|
274
|
+
'PATH_INFO' => '/info',
|
275
|
+
'REQUEST_METHOD' => method,
|
276
|
+
'CONTENT_TYPE' => 'application/json',
|
277
|
+
'rack.input' => io,
|
278
|
+
'CONTENT_LENGTH' => 0
|
279
|
+
)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context 'when body is empty' do
|
284
|
+
let(:io) { double }
|
285
|
+
before do
|
286
|
+
allow(io).to receive_message_chain(:rewind, :read).and_return('')
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'does not read and parse the body' do
|
290
|
+
expect(subject).not_to receive(:read_rack_input)
|
291
|
+
subject.call(
|
292
|
+
'PATH_INFO' => '/info',
|
293
|
+
'REQUEST_METHOD' => method,
|
294
|
+
'CONTENT_TYPE' => 'application/json',
|
295
|
+
'rack.input' => io,
|
296
|
+
'CONTENT_LENGTH' => 0
|
297
|
+
)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
227
301
|
['application/json', 'application/json; charset=utf-8'].each do |content_type|
|
228
302
|
context content_type do
|
229
303
|
it "parses the body from #{method} and copies values into rack.request.form_hash" do
|
@@ -479,6 +479,24 @@ describe Grape::Validations::ParamsScope do
|
|
479
479
|
end.to_not raise_error
|
480
480
|
end
|
481
481
|
|
482
|
+
it 'allows aliasing of dependent parameters' do
|
483
|
+
subject.params do
|
484
|
+
optional :a
|
485
|
+
given :a do
|
486
|
+
requires :b, as: :c
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
subject.get('/multiple') { declared(params).to_json }
|
491
|
+
|
492
|
+
get '/multiple', a: 'a', b: 'b'
|
493
|
+
|
494
|
+
body = JSON.parse(last_response.body)
|
495
|
+
|
496
|
+
expect(body.keys).to include('c')
|
497
|
+
expect(body.keys).to_not include('b')
|
498
|
+
end
|
499
|
+
|
482
500
|
it 'does not validate nested requires when given is false' do
|
483
501
|
subject.params do
|
484
502
|
requires :a, type: String, allow_blank: false, values: %w[x y z]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-04
|
11
|
+
date: 2018-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -250,7 +250,8 @@ files:
|
|
250
250
|
- lib/grape/validations/validators/regexp.rb
|
251
251
|
- lib/grape/validations/validators/values.rb
|
252
252
|
- lib/grape/version.rb
|
253
|
-
- pkg/grape-
|
253
|
+
- pkg/grape-0.17.0.gem
|
254
|
+
- pkg/grape-0.19.0.gem
|
254
255
|
- spec/grape/api/custom_validations_spec.rb
|
255
256
|
- spec/grape/api/deeply_included_options_spec.rb
|
256
257
|
- spec/grape/api/inherited_helpers_spec.rb
|
@@ -368,7 +369,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
368
369
|
version: '0'
|
369
370
|
requirements: []
|
370
371
|
rubyforge_project:
|
371
|
-
rubygems_version: 2.6
|
372
|
+
rubygems_version: 2.7.6
|
372
373
|
signing_key:
|
373
374
|
specification_version: 4
|
374
375
|
summary: A simple Ruby framework for building REST-like APIs.
|
data/pkg/grape-1.0.0.gem
DELETED
Binary file
|