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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5e2e2a2c3e1ed64c7c75af7d0fb52467c4e596a9
4
- data.tar.gz: a23ce793ad55115be0300f310f7ec024769275e8
2
+ SHA256:
3
+ metadata.gz: 7768f2318b0b1045ec81b3a83cb08b5d80676da77aaa30f059fb056175578781
4
+ data.tar.gz: e19ecc4e39b33a19e43e7831ceab4d5a13fd186677cef84547066e48d24d98d0
5
5
  SHA512:
6
- metadata.gz: e754bfdf8d83d12ed4e770114a3a8b5e80ca2462be2d13cbbd68a15b5c528856d897715f630f381460bc4cdc4f2715dffd24945c5c510db397183f79a281af11
7
- data.tar.gz: 25da8c7eb6ef92e5ea4ac55103fb688738f3544818b6a971408f150fab4392bbe8e0e0f2a1be56cf47e0a121aabf790bd4389876ee9dfc11c00b6b77920a40ff
6
+ metadata.gz: afc16b3f2a5036029bb22615ded000eefb2c24f396efa1f2bc22b253bb84d1adb2a4f2ea7dad63a8d4f98a0c69e7720b828072e57bd8e5ce281c1d158f25cb02
7
+ data.tar.gz: b650ba30bc697feea23a4aa03a50e525b135e25c14707b85f4e95b7a95c5ba37e1565ddce147148885467516c1a7d48e74d58cabb1172679978dcbe28216674a
data/Appraisals CHANGED
@@ -16,7 +16,7 @@ appraise 'rack-1.5.2' do
16
16
  end
17
17
 
18
18
  appraise 'rails-edge' do
19
- gem 'arel', github: 'rails/arel'
19
+ gem 'rails', github: 'rails/rails'
20
20
  end
21
21
 
22
22
  appraise 'rack-edge' do
@@ -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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grape (1.0.3)
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.1.4)
15
+ activesupport (5.2.0)
16
16
  concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (~> 0.7)
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.21)
47
+ coveralls (0.8.22)
48
48
  json (>= 1.8, < 3)
49
- simplecov (~> 0.14.1)
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.5)
75
+ docile (1.3.1)
76
76
  equalizer (0.0.11)
77
- faraday (0.14.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.21)
81
+ ffi (1.9.25)
82
82
  formatador (0.2.5)
83
- git (1.3.0)
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.9.4)
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.16.2)
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.12)
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.1)
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.8.0)
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.4.0.2)
136
- ast (~> 2.3)
137
- powerpack (0.1.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.1)
142
- rack (2.0.4)
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.0)
152
- rb-fsevent (0.10.2)
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.14.1)
185
- docile (~> 1.1.0)
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.3.0)
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.15.3
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.3**.
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:%i(asc desc), default:options[:default_order]
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:%i(id created_at), default_order_by: :created_at, default_order: :asc
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
@@ -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
@@ -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.0'
25
+ gem 'danger-toc', '~> 0.1.2'
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
28
  gem 'mime-types'
@@ -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.0'
25
+ gem 'danger-toc', '~> 0.1.2'
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
28
  gem 'mime-types'
@@ -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.0'
25
+ gem 'danger-toc', '~> 0.1.2'
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
28
  gem 'mime-types'
@@ -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.0'
25
+ gem 'danger-toc', '~> 0.1.2'
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
28
  gem 'mime-types'
@@ -23,7 +23,7 @@ end
23
23
  group :test do
24
24
  gem 'cookiejar'
25
25
  gem 'coveralls', '~> 0.8.17', require: false
26
- gem 'danger-toc', '~> 0.1.0'
26
+ gem 'danger-toc', '~> 0.1.2'
27
27
  gem 'grape-entity', '~> 0.6'
28
28
  gem 'maruku'
29
29
  gem 'mime-types'
@@ -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.0'
25
+ gem 'danger-toc', '~> 0.1.2'
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
28
  gem 'mime-types'
@@ -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.0'
25
+ gem 'danger-toc', '~> 0.1.2'
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
28
  gem 'mime-types'
@@ -2,7 +2,7 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- gem 'arel', github: 'rails/arel'
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.0'
25
+ gem 'danger-toc', '~> 0.1.2'
26
26
  gem 'grape-entity', '~> 0.6'
27
27
  gem 'maruku'
28
28
  gem 'mime-types'
@@ -1,4 +1,4 @@
1
- $LOAD_PATH.push File.expand_path('../lib', __FILE__)
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
2
  require 'grape/version'
3
3
 
4
4
  Gem::Specification.new do |s|
@@ -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 = bodies.collect { |body| formatter.call(body, env) }
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: 406, message: "The requested content-type '#{request.media_type}' is not supported."
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) || [])
@@ -1,4 +1,4 @@
1
1
  module Grape
2
2
  # The current version of Grape.
3
- VERSION = '1.0.3'.freeze
3
+ VERSION = '1.1.0'.freeze
4
4
  end
Binary file
Binary file
@@ -2142,7 +2142,11 @@ XML
2142
2142
  end
2143
2143
  get '/excel.json'
2144
2144
  expect(last_response.status).to eq(406)
2145
- expect(last_response.body).to eq("The requested format 'txt' is not supported.")
2145
+ if ActiveSupport::VERSION::MAJOR == 3
2146
+ expect(last_response.body).to eq('The requested format &#x27;txt&#x27; is not supported.')
2147
+ else
2148
+ expect(last_response.body).to eq('The requested format &#39;txt&#39; 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
- expect(last_response.body).to eq("{\"error\":\"The requested format 'txt' is not supported.\"}")
3531
+ if ActiveSupport::VERSION::MAJOR == 3
3532
+ expect(last_response.body).to eq('{&quot;error&quot;:&quot;The requested format &#x27;txt&#x27; is not supported.&quot;}')
3533
+ else
3534
+ expect(last_response.body).to eq('{&quot;error&quot;:&quot;The requested format &#39;txt&#39; is not supported.&quot;}')
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 &#x27;&lt;script&gt;blah&lt;/script&gt;&#x27; is not supported.')
3549
+ else
3550
+ expect(last_response.body).to eq('The requested format &#39;&lt;script&gt;blah&lt;/script&gt;&#39; is not supported.')
3551
+ end
3528
3552
  end
3529
3553
  end
3530
3554
 
@@ -941,15 +941,15 @@ describe Grape::Endpoint do
941
941
  end
942
942
  end
943
943
 
944
- it 'responds with a 406 for an unsupported content-type' do
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(406)
952
- expect(last_response.body).to eq('{"error":"The requested content-type \'application/xml\' is not supported."}')
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(406)
964
- expect(last_response.body).to eq('{"error":"The requested content-type \'text/plain\' is not supported."}')
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('{"error":"rain!"}')
195
+ expect(last_response.body).to eq('{&quot;error&quot;:&quot;rain!&quot;}')
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(['{"error":"rain!","detail":"missing widget"}',
211
- '{"detail":"missing widget","error":"rain!"}']).to include(last_response.body)
210
+ expect(['{&quot;error&quot;:&quot;rain!&quot;,&quot;detail&quot;:&quot;missing widget&quot;}',
211
+ '{&quot;detail&quot;:&quot;missing widget&quot;,&quot;error&quot;:&quot;rain!&quot;}']).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=>"rain!"}')
261
+ expect(last_response.body).to eq('{:custom_formatter=&gt;&quot;rain!&quot;}')
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.3
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-23 00:00:00.000000000 Z
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-1.0.0.gem
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.12
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.
Binary file