grape 1.5.3 → 1.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/CONTRIBUTING.md +2 -1
- data/README.md +31 -3
- data/UPGRADING.md +46 -4
- data/grape.gemspec +5 -5
- data/lib/grape/api/instance.rb +13 -17
- data/lib/grape/api.rb +17 -12
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dsl/desc.rb +3 -5
- data/lib/grape/dsl/headers.rb +5 -2
- data/lib/grape/dsl/helpers.rb +7 -5
- data/lib/grape/dsl/inside_route.rb +17 -8
- data/lib/grape/dsl/middleware.rb +4 -4
- data/lib/grape/dsl/parameters.rb +3 -3
- data/lib/grape/dsl/request_response.rb +9 -6
- data/lib/grape/dsl/routing.rb +2 -2
- data/lib/grape/dsl/settings.rb +5 -5
- data/lib/grape/endpoint.rb +20 -35
- data/lib/grape/error_formatter/json.rb +2 -6
- data/lib/grape/error_formatter/xml.rb +2 -6
- data/lib/grape/exceptions/validation.rb +1 -2
- data/lib/grape/formatter/json.rb +1 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -1
- data/lib/grape/formatter/xml.rb +1 -0
- data/lib/grape/middleware/auth/dsl.rb +7 -1
- data/lib/grape/middleware/base.rb +3 -1
- data/lib/grape/middleware/formatter.rb +4 -4
- data/lib/grape/middleware/stack.rb +2 -2
- data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
- data/lib/grape/middleware/versioner/header.rb +6 -4
- data/lib/grape/middleware/versioner/param.rb +1 -0
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/middleware/versioner/path.rb +2 -0
- data/lib/grape/path.rb +1 -0
- data/lib/grape/request.rb +1 -0
- data/lib/grape/router/pattern.rb +1 -1
- data/lib/grape/router/route.rb +2 -2
- data/lib/grape/router.rb +6 -0
- data/lib/grape/util/inheritable_setting.rb +1 -3
- data/lib/grape/util/lazy_value.rb +3 -2
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/params_scope.rb +88 -55
- data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
- data/lib/grape/validations/types/dry_type_coercer.rb +1 -1
- data/lib/grape/validations/types/json.rb +2 -1
- data/lib/grape/validations/types/primitive_coercer.rb +3 -3
- data/lib/grape/validations/validators/all_or_none.rb +8 -5
- data/lib/grape/validations/validators/allow_blank.rb +9 -7
- data/lib/grape/validations/validators/as.rb +6 -8
- data/lib/grape/validations/validators/at_least_one_of.rb +7 -4
- data/lib/grape/validations/validators/base.rb +75 -70
- data/lib/grape/validations/validators/coerce.rb +63 -79
- data/lib/grape/validations/validators/default.rb +37 -34
- data/lib/grape/validations/validators/exactly_one_of.rb +9 -6
- data/lib/grape/validations/validators/except_values.rb +13 -11
- data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
- data/lib/grape/validations/validators/mutual_exclusion.rb +8 -5
- data/lib/grape/validations/validators/presence.rb +7 -4
- data/lib/grape/validations/validators/regexp.rb +8 -5
- data/lib/grape/validations/validators/same_as.rb +18 -15
- data/lib/grape/validations/validators/values.rb +61 -56
- data/lib/grape/validations.rb +6 -0
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +3 -1
- data/spec/grape/api/custom_validations_spec.rb +77 -45
- data/spec/grape/api/deeply_included_options_spec.rb +3 -3
- data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -1
- data/spec/grape/api/invalid_format_spec.rb +2 -0
- data/spec/grape/api/recognize_path_spec.rb +1 -1
- data/spec/grape/api/routes_with_requirements_spec.rb +8 -8
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -15
- data/spec/grape/api_remount_spec.rb +16 -15
- data/spec/grape/api_spec.rb +440 -227
- data/spec/grape/dsl/callbacks_spec.rb +2 -1
- data/spec/grape/dsl/headers_spec.rb +39 -9
- data/spec/grape/dsl/helpers_spec.rb +3 -2
- data/spec/grape/dsl/inside_route_spec.rb +6 -4
- data/spec/grape/dsl/logger_spec.rb +16 -18
- data/spec/grape/dsl/middleware_spec.rb +2 -1
- data/spec/grape/dsl/parameters_spec.rb +2 -0
- data/spec/grape/dsl/request_response_spec.rb +1 -0
- data/spec/grape/dsl/routing_spec.rb +10 -7
- data/spec/grape/endpoint/declared_spec.rb +259 -12
- data/spec/grape/endpoint_spec.rb +64 -55
- data/spec/grape/entity_spec.rb +22 -22
- data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -0
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -22
- data/spec/grape/exceptions/validation_errors_spec.rb +13 -10
- data/spec/grape/exceptions/validation_spec.rb +5 -3
- data/spec/grape/extensions/param_builders/hash_spec.rb +7 -7
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -8
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -8
- data/spec/grape/integration/rack_sendfile_spec.rb +1 -1
- data/spec/grape/loading_spec.rb +8 -8
- data/spec/grape/middleware/auth/dsl_spec.rb +15 -6
- data/spec/grape/middleware/auth/strategies_spec.rb +60 -20
- data/spec/grape/middleware/base_spec.rb +24 -15
- data/spec/grape/middleware/error_spec.rb +2 -2
- data/spec/grape/middleware/exception_spec.rb +111 -161
- data/spec/grape/middleware/formatter_spec.rb +27 -6
- data/spec/grape/middleware/globals_spec.rb +7 -4
- data/spec/grape/middleware/stack_spec.rb +14 -12
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -1
- data/spec/grape/middleware/versioner/header_spec.rb +14 -13
- data/spec/grape/middleware/versioner/param_spec.rb +7 -1
- data/spec/grape/middleware/versioner/path_spec.rb +5 -1
- data/spec/grape/middleware/versioner_spec.rb +1 -1
- data/spec/grape/parser_spec.rb +4 -0
- data/spec/grape/path_spec.rb +52 -52
- data/spec/grape/presenters/presenter_spec.rb +7 -6
- data/spec/grape/request_spec.rb +6 -4
- data/spec/grape/util/inheritable_setting_spec.rb +7 -7
- data/spec/grape/util/inheritable_values_spec.rb +3 -2
- data/spec/grape/util/reverse_stackable_values_spec.rb +3 -1
- data/spec/grape/util/stackable_values_spec.rb +7 -5
- data/spec/grape/validations/instance_behaivour_spec.rb +9 -10
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -0
- data/spec/grape/validations/params_scope_spec.rb +46 -10
- data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -1
- data/spec/grape/validations/types/primitive_coercer_spec.rb +4 -4
- data/spec/grape/validations/types_spec.rb +8 -8
- data/spec/grape/validations/validators/all_or_none_spec.rb +50 -56
- data/spec/grape/validations/validators/allow_blank_spec.rb +136 -140
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -56
- data/spec/grape/validations/validators/coerce_spec.rb +23 -22
- data/spec/grape/validations/validators/default_spec.rb +72 -78
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -77
- data/spec/grape/validations/validators/except_values_spec.rb +3 -3
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -77
- data/spec/grape/validations/validators/presence_spec.rb +16 -1
- data/spec/grape/validations/validators/regexp_spec.rb +25 -31
- data/spec/grape/validations/validators/same_as_spec.rb +14 -20
- data/spec/grape/validations/validators/values_spec.rb +183 -178
- data/spec/grape/validations_spec.rb +99 -58
- data/spec/integration/eager_load/eager_load_spec.rb +2 -2
- data/spec/integration/multi_json/json_spec.rb +1 -1
- data/spec/integration/multi_xml/xml_spec.rb +1 -1
- data/spec/shared/versioning_examples.rb +12 -9
- data/spec/spec_helper.rb +12 -2
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- metadata +103 -103
data/spec/grape/endpoint_spec.rb
CHANGED
@@ -10,32 +10,32 @@ describe Grape::Endpoint do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe '.before_each' do
|
13
|
-
after {
|
13
|
+
after { described_class.before_each.clear }
|
14
14
|
|
15
15
|
it 'is settable via block' do
|
16
16
|
block = ->(_endpoint) { 'noop' }
|
17
|
-
|
18
|
-
expect(
|
17
|
+
described_class.before_each(&block)
|
18
|
+
expect(described_class.before_each.first).to eq(block)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'is settable via reference' do
|
22
22
|
block = ->(_endpoint) { 'noop' }
|
23
|
-
|
24
|
-
expect(
|
23
|
+
described_class.before_each block
|
24
|
+
expect(described_class.before_each.first).to eq(block)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'is able to override a helper' do
|
28
28
|
subject.get('/') { current_user }
|
29
29
|
expect { get '/' }.to raise_error(NameError)
|
30
30
|
|
31
|
-
|
31
|
+
described_class.before_each do |endpoint|
|
32
32
|
allow(endpoint).to receive(:current_user).and_return('Bob')
|
33
33
|
end
|
34
34
|
|
35
35
|
get '/'
|
36
36
|
expect(last_response.body).to eq('Bob')
|
37
37
|
|
38
|
-
|
38
|
+
described_class.before_each(nil)
|
39
39
|
expect { get '/' }.to raise_error(NameError)
|
40
40
|
end
|
41
41
|
|
@@ -46,18 +46,18 @@ describe Grape::Endpoint do
|
|
46
46
|
end
|
47
47
|
expect { get '/' }.to raise_error(NameError)
|
48
48
|
|
49
|
-
|
49
|
+
described_class.before_each do |endpoint|
|
50
50
|
allow(endpoint).to receive(:current_user).and_return('Bob')
|
51
51
|
end
|
52
52
|
|
53
|
-
|
53
|
+
described_class.before_each do |endpoint|
|
54
54
|
allow(endpoint).to receive(:authenticate_user!).and_return(true)
|
55
55
|
end
|
56
56
|
|
57
57
|
get '/'
|
58
58
|
expect(last_response.body).to eq('Bob')
|
59
59
|
|
60
|
-
|
60
|
+
described_class.before_each(nil)
|
61
61
|
expect { get '/' }.to raise_error(NameError)
|
62
62
|
end
|
63
63
|
end
|
@@ -66,7 +66,7 @@ describe Grape::Endpoint do
|
|
66
66
|
it 'takes a settings stack, options, and a block' do
|
67
67
|
p = proc {}
|
68
68
|
expect do
|
69
|
-
|
69
|
+
described_class.new(Grape::Util::InheritableSetting.new, {
|
70
70
|
path: '/',
|
71
71
|
method: :get
|
72
72
|
}, &p)
|
@@ -77,7 +77,7 @@ describe Grape::Endpoint do
|
|
77
77
|
it 'sets itself in the env upon call' do
|
78
78
|
subject.get('/') { 'Hello world.' }
|
79
79
|
get '/'
|
80
|
-
expect(last_request.env['api.endpoint']).to be_kind_of(
|
80
|
+
expect(last_request.env['api.endpoint']).to be_kind_of(described_class)
|
81
81
|
end
|
82
82
|
|
83
83
|
describe '#status' do
|
@@ -137,6 +137,7 @@ describe Grape::Endpoint do
|
|
137
137
|
headers.to_json
|
138
138
|
end
|
139
139
|
end
|
140
|
+
|
140
141
|
it 'includes request headers' do
|
141
142
|
get '/headers'
|
142
143
|
expect(JSON.parse(last_response.body)).to eq(
|
@@ -144,13 +145,15 @@ describe Grape::Endpoint do
|
|
144
145
|
'Cookie' => ''
|
145
146
|
)
|
146
147
|
end
|
148
|
+
|
147
149
|
it 'includes additional request headers' do
|
148
150
|
get '/headers', nil, 'HTTP_X_GRAPE_CLIENT' => '1'
|
149
151
|
expect(JSON.parse(last_response.body)['X-Grape-Client']).to eq('1')
|
150
152
|
end
|
153
|
+
|
151
154
|
it 'includes headers passed as symbols' do
|
152
155
|
env = Rack::MockRequest.env_for('/headers')
|
153
|
-
env[
|
156
|
+
env[:HTTP_SYMBOL_HEADER] = 'Goliath passes symbols'
|
154
157
|
body = read_chunks(subject.call(env)[2]).join
|
155
158
|
expect(JSON.parse(body)['Symbol-Header']).to eq('Goliath passes symbols')
|
156
159
|
end
|
@@ -212,10 +215,10 @@ describe Grape::Endpoint do
|
|
212
215
|
end
|
213
216
|
get '/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2'
|
214
217
|
expect(last_response.body).to eq('3')
|
215
|
-
cookies =
|
218
|
+
cookies = last_response.headers['Set-Cookie'].split("\n").map do |set_cookie|
|
216
219
|
cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie
|
217
220
|
[cookie.name, cookie]
|
218
|
-
end
|
221
|
+
end.to_h
|
219
222
|
expect(cookies.size).to eq(2)
|
220
223
|
%w[and_this delete_this_cookie].each do |cookie_name|
|
221
224
|
cookie = cookies[cookie_name]
|
@@ -236,10 +239,10 @@ describe Grape::Endpoint do
|
|
236
239
|
end
|
237
240
|
get('/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2')
|
238
241
|
expect(last_response.body).to eq('3')
|
239
|
-
cookies =
|
242
|
+
cookies = last_response.headers['Set-Cookie'].split("\n").map do |set_cookie|
|
240
243
|
cookie = CookieJar::Cookie.from_set_cookie 'http://localhost/test', set_cookie
|
241
244
|
[cookie.name, cookie]
|
242
|
-
end
|
245
|
+
end.to_h
|
243
246
|
expect(cookies.size).to eq(2)
|
244
247
|
%w[and_this delete_this_cookie].each do |cookie_name|
|
245
248
|
cookie = cookies[cookie_name]
|
@@ -253,7 +256,7 @@ describe Grape::Endpoint do
|
|
253
256
|
|
254
257
|
describe '#params' do
|
255
258
|
context 'default class' do
|
256
|
-
it '
|
259
|
+
it 'is a ActiveSupport::HashWithIndifferentAccess' do
|
257
260
|
subject.get '/foo' do
|
258
261
|
params.class
|
259
262
|
end
|
@@ -339,7 +342,7 @@ describe Grape::Endpoint do
|
|
339
342
|
end
|
340
343
|
|
341
344
|
context 'namespace requirements' do
|
342
|
-
before
|
345
|
+
before do
|
343
346
|
subject.namespace :outer, requirements: { person_email: /abc@(.*).com/ } do
|
344
347
|
get('/:person_email') do
|
345
348
|
params[:person_email]
|
@@ -358,7 +361,7 @@ describe Grape::Endpoint do
|
|
358
361
|
expect(last_response.body).to eq('abc@example.com')
|
359
362
|
end
|
360
363
|
|
361
|
-
it "
|
364
|
+
it "overrides outer namespace's requirements" do
|
362
365
|
get '/outer/inner/someone@testing.wrong/test/1'
|
363
366
|
expect(last_response.status).to eq(404)
|
364
367
|
|
@@ -370,7 +373,7 @@ describe Grape::Endpoint do
|
|
370
373
|
end
|
371
374
|
|
372
375
|
context 'from body parameters' do
|
373
|
-
before
|
376
|
+
before do
|
374
377
|
subject.post '/request_body' do
|
375
378
|
params[:user]
|
376
379
|
end
|
@@ -469,11 +472,11 @@ describe Grape::Endpoint do
|
|
469
472
|
post '/', ::Grape::Json.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json'
|
470
473
|
end
|
471
474
|
|
472
|
-
it '
|
475
|
+
it 'does not response with 406 for same type without params' do
|
473
476
|
expect(last_response.status).not_to be 406
|
474
477
|
end
|
475
478
|
|
476
|
-
it '
|
479
|
+
it 'responses with given content type in headers' do
|
477
480
|
expect(last_response.headers['Content-Type']).to eq 'application/json; charset=utf-8'
|
478
481
|
end
|
479
482
|
end
|
@@ -709,16 +712,18 @@ describe Grape::Endpoint do
|
|
709
712
|
describe '.generate_api_method' do
|
710
713
|
it 'raises NameError if the method name is already in use' do
|
711
714
|
expect do
|
712
|
-
|
715
|
+
described_class.generate_api_method('version', &proc {})
|
713
716
|
end.to raise_error(NameError)
|
714
717
|
end
|
718
|
+
|
715
719
|
it 'raises ArgumentError if a block is not given' do
|
716
720
|
expect do
|
717
|
-
|
721
|
+
described_class.generate_api_method('GET without a block method')
|
718
722
|
end.to raise_error(ArgumentError)
|
719
723
|
end
|
724
|
+
|
720
725
|
it 'returns a Proc' do
|
721
|
-
expect(
|
726
|
+
expect(described_class.generate_api_method('GET test for a proc', &proc {})).to be_a Proc
|
722
727
|
end
|
723
728
|
end
|
724
729
|
|
@@ -777,7 +782,7 @@ describe Grape::Endpoint do
|
|
777
782
|
end
|
778
783
|
|
779
784
|
get '/error_filters'
|
780
|
-
expect(last_response.status).to
|
785
|
+
expect(last_response.status).to be 500
|
781
786
|
expect(called).to match_array %w[before before_validation]
|
782
787
|
end
|
783
788
|
|
@@ -786,8 +791,11 @@ describe Grape::Endpoint do
|
|
786
791
|
subject.before { called << 'parent' }
|
787
792
|
subject.namespace :parent do
|
788
793
|
before { called << 'prior' }
|
794
|
+
|
789
795
|
before { error! :oops, 500 }
|
796
|
+
|
790
797
|
before { called << 'subsequent' }
|
798
|
+
|
791
799
|
get :hello do
|
792
800
|
called << :endpoint
|
793
801
|
'Hello!'
|
@@ -795,7 +803,7 @@ describe Grape::Endpoint do
|
|
795
803
|
end
|
796
804
|
|
797
805
|
get '/parent/hello'
|
798
|
-
expect(last_response.status).to
|
806
|
+
expect(last_response.status).to be 500
|
799
807
|
expect(called).to match_array %w[parent prior]
|
800
808
|
end
|
801
809
|
end
|
@@ -806,19 +814,19 @@ describe Grape::Endpoint do
|
|
806
814
|
it 'allows for the anchoring option with a delete method' do
|
807
815
|
subject.send(:delete, '/example', anchor: true) {}
|
808
816
|
send(:delete, '/example/and/some/more')
|
809
|
-
expect(last_response.status).to
|
817
|
+
expect(last_response.status).to be 404
|
810
818
|
end
|
811
819
|
|
812
820
|
it 'anchors paths by default for the delete method' do
|
813
821
|
subject.send(:delete, '/example') {}
|
814
822
|
send(:delete, '/example/and/some/more')
|
815
|
-
expect(last_response.status).to
|
823
|
+
expect(last_response.status).to be 404
|
816
824
|
end
|
817
825
|
|
818
826
|
it 'responds to /example/and/some/more for the non-anchored delete method' do
|
819
827
|
subject.send(:delete, '/example', anchor: false) {}
|
820
828
|
send(:delete, '/example/and/some/more')
|
821
|
-
expect(last_response.status).to
|
829
|
+
expect(last_response.status).to be 204
|
822
830
|
expect(last_response.body).to be_empty
|
823
831
|
end
|
824
832
|
end
|
@@ -830,7 +838,7 @@ describe Grape::Endpoint do
|
|
830
838
|
body 'deleted'
|
831
839
|
end
|
832
840
|
send(:delete, '/example/and/some/more')
|
833
|
-
expect(last_response.status).to
|
841
|
+
expect(last_response.status).to be 200
|
834
842
|
expect(last_response.body).not_to be_empty
|
835
843
|
end
|
836
844
|
end
|
@@ -839,7 +847,7 @@ describe Grape::Endpoint do
|
|
839
847
|
it 'responds to /example delete method' do
|
840
848
|
subject.delete(:example) { 'deleted' }
|
841
849
|
delete '/example'
|
842
|
-
expect(last_response.status).to
|
850
|
+
expect(last_response.status).to be 200
|
843
851
|
expect(last_response.body).not_to be_empty
|
844
852
|
end
|
845
853
|
end
|
@@ -848,7 +856,7 @@ describe Grape::Endpoint do
|
|
848
856
|
it 'responds to /example delete method' do
|
849
857
|
subject.delete(:example) { nil }
|
850
858
|
delete '/example'
|
851
|
-
expect(last_response.status).to
|
859
|
+
expect(last_response.status).to be 204
|
852
860
|
expect(last_response.body).to be_empty
|
853
861
|
end
|
854
862
|
end
|
@@ -857,7 +865,7 @@ describe Grape::Endpoint do
|
|
857
865
|
it 'responds to /example delete method' do
|
858
866
|
subject.delete(:example) { '' }
|
859
867
|
delete '/example'
|
860
|
-
expect(last_response.status).to
|
868
|
+
expect(last_response.status).to be 204
|
861
869
|
expect(last_response.body).to be_empty
|
862
870
|
end
|
863
871
|
end
|
@@ -869,7 +877,7 @@ describe Grape::Endpoint do
|
|
869
877
|
verb
|
870
878
|
end
|
871
879
|
send(verb, '/example/and/some/more')
|
872
|
-
expect(last_response.status).to
|
880
|
+
expect(last_response.status).to be 404
|
873
881
|
end
|
874
882
|
|
875
883
|
it "anchors paths by default for the #{verb.upcase} method" do
|
@@ -877,7 +885,7 @@ describe Grape::Endpoint do
|
|
877
885
|
verb
|
878
886
|
end
|
879
887
|
send(verb, '/example/and/some/more')
|
880
|
-
expect(last_response.status).to
|
888
|
+
expect(last_response.status).to be 404
|
881
889
|
end
|
882
890
|
|
883
891
|
it "responds to /example/and/some/more for the non-anchored #{verb.upcase} method" do
|
@@ -900,8 +908,9 @@ describe Grape::Endpoint do
|
|
900
908
|
get '/url'
|
901
909
|
expect(last_response.body).to eq('http://example.org/url')
|
902
910
|
end
|
911
|
+
|
903
912
|
['v1', :v1].each do |version|
|
904
|
-
it "
|
913
|
+
it "includes version #{version}" do
|
905
914
|
subject.version version, using: :path
|
906
915
|
subject.get('/url') do
|
907
916
|
request.url
|
@@ -910,7 +919,7 @@ describe Grape::Endpoint do
|
|
910
919
|
expect(last_response.body).to eq("http://example.org/#{version}/url")
|
911
920
|
end
|
912
921
|
end
|
913
|
-
it '
|
922
|
+
it 'includes prefix' do
|
914
923
|
subject.version 'v1', using: :path
|
915
924
|
subject.prefix 'api'
|
916
925
|
subject.get('/url') do
|
@@ -1000,26 +1009,26 @@ describe Grape::Endpoint do
|
|
1000
1009
|
|
1001
1010
|
# In order that the events finalized (time each block ended)
|
1002
1011
|
expect(@events).to contain_exactly(
|
1003
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1012
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1004
1013
|
filters: a_collection_containing_exactly(an_instance_of(Proc)),
|
1005
1014
|
type: :before }),
|
1006
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1015
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1007
1016
|
filters: [],
|
1008
1017
|
type: :before_validation }),
|
1009
|
-
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(
|
1018
|
+
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(described_class),
|
1010
1019
|
validators: [],
|
1011
1020
|
request: a_kind_of(Grape::Request) }),
|
1012
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1021
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1013
1022
|
filters: [],
|
1014
1023
|
type: :after_validation }),
|
1015
|
-
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(
|
1016
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1024
|
+
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(described_class) }),
|
1025
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1017
1026
|
filters: [],
|
1018
1027
|
type: :after }),
|
1019
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1028
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1020
1029
|
filters: [],
|
1021
1030
|
type: :finally }),
|
1022
|
-
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(
|
1031
|
+
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(described_class),
|
1023
1032
|
env: an_instance_of(Hash) }),
|
1024
1033
|
have_attributes(name: 'format_response.grape', payload: { env: an_instance_of(Hash),
|
1025
1034
|
formatter: a_kind_of(Module) })
|
@@ -1027,25 +1036,25 @@ describe Grape::Endpoint do
|
|
1027
1036
|
|
1028
1037
|
# In order that events were initialized
|
1029
1038
|
expect(@events.sort_by(&:time)).to contain_exactly(
|
1030
|
-
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(
|
1039
|
+
have_attributes(name: 'endpoint_run.grape', payload: { endpoint: a_kind_of(described_class),
|
1031
1040
|
env: an_instance_of(Hash) }),
|
1032
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1041
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1033
1042
|
filters: a_collection_containing_exactly(an_instance_of(Proc)),
|
1034
1043
|
type: :before }),
|
1035
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1044
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1036
1045
|
filters: [],
|
1037
1046
|
type: :before_validation }),
|
1038
|
-
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(
|
1047
|
+
have_attributes(name: 'endpoint_run_validators.grape', payload: { endpoint: a_kind_of(described_class),
|
1039
1048
|
validators: [],
|
1040
1049
|
request: a_kind_of(Grape::Request) }),
|
1041
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1050
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1042
1051
|
filters: [],
|
1043
1052
|
type: :after_validation }),
|
1044
|
-
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(
|
1045
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1053
|
+
have_attributes(name: 'endpoint_render.grape', payload: { endpoint: a_kind_of(described_class) }),
|
1054
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1046
1055
|
filters: [],
|
1047
1056
|
type: :after }),
|
1048
|
-
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(
|
1057
|
+
have_attributes(name: 'endpoint_run_filters.grape', payload: { endpoint: a_kind_of(described_class),
|
1049
1058
|
filters: [],
|
1050
1059
|
type: :finally }),
|
1051
1060
|
have_attributes(name: 'format_response.grape', payload: { env: an_instance_of(Hash),
|
data/spec/grape/entity_spec.rb
CHANGED
@@ -32,7 +32,7 @@ describe Grape::Entity do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'pulls a representation from the class options if it exists' do
|
35
|
-
entity = Class.new(
|
35
|
+
entity = Class.new(described_class)
|
36
36
|
allow(entity).to receive(:represent).and_return('Hiya')
|
37
37
|
|
38
38
|
subject.represent Object, with: entity
|
@@ -44,7 +44,7 @@ describe Grape::Entity do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'pulls a representation from the class options if the presented object is a collection of objects' do
|
47
|
-
entity = Class.new(
|
47
|
+
entity = Class.new(described_class)
|
48
48
|
allow(entity).to receive(:represent).and_return('Hiya')
|
49
49
|
|
50
50
|
module EntitySpec
|
@@ -75,7 +75,7 @@ describe Grape::Entity do
|
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'pulls a representation from the class ancestor if it exists' do
|
78
|
-
entity = Class.new(
|
78
|
+
entity = Class.new(described_class)
|
79
79
|
allow(entity).to receive(:represent).and_return('Hiya')
|
80
80
|
|
81
81
|
subclass = Class.new(Object)
|
@@ -90,7 +90,7 @@ describe Grape::Entity do
|
|
90
90
|
|
91
91
|
it 'automatically uses Klass::Entity if that exists' do
|
92
92
|
some_model = Class.new
|
93
|
-
entity = Class.new(
|
93
|
+
entity = Class.new(described_class)
|
94
94
|
allow(entity).to receive(:represent).and_return('Auto-detect!')
|
95
95
|
|
96
96
|
some_model.const_set :Entity, entity
|
@@ -104,7 +104,7 @@ describe Grape::Entity do
|
|
104
104
|
|
105
105
|
it 'automatically uses Klass::Entity based on the first object in the collection being presented' do
|
106
106
|
some_model = Class.new
|
107
|
-
entity = Class.new(
|
107
|
+
entity = Class.new(described_class)
|
108
108
|
allow(entity).to receive(:represent).and_return('Auto-detect!')
|
109
109
|
|
110
110
|
some_model.const_set :Entity, entity
|
@@ -117,7 +117,7 @@ describe Grape::Entity do
|
|
117
117
|
end
|
118
118
|
|
119
119
|
it 'does not run autodetection for Entity when explicitly provided' do
|
120
|
-
entity = Class.new(
|
120
|
+
entity = Class.new(described_class)
|
121
121
|
some_array = []
|
122
122
|
|
123
123
|
subject.get '/example' do
|
@@ -129,7 +129,7 @@ describe Grape::Entity do
|
|
129
129
|
end
|
130
130
|
|
131
131
|
it 'does not use #first method on ActiveRecord::Relation to prevent needless sql query' do
|
132
|
-
entity = Class.new(
|
132
|
+
entity = Class.new(described_class)
|
133
133
|
some_relation = Class.new
|
134
134
|
some_model = Class.new
|
135
135
|
|
@@ -173,7 +173,7 @@ describe Grape::Entity do
|
|
173
173
|
|
174
174
|
%i[json serializable_hash].each do |format|
|
175
175
|
it "presents with #{format}" do
|
176
|
-
entity = Class.new(
|
176
|
+
entity = Class.new(described_class)
|
177
177
|
entity.root 'examples', 'example'
|
178
178
|
entity.expose :id
|
179
179
|
|
@@ -195,7 +195,7 @@ describe Grape::Entity do
|
|
195
195
|
end
|
196
196
|
|
197
197
|
it "presents with #{format} collection" do
|
198
|
-
entity = Class.new(
|
198
|
+
entity = Class.new(described_class)
|
199
199
|
entity.root 'examples', 'example'
|
200
200
|
entity.expose :id
|
201
201
|
|
@@ -219,7 +219,7 @@ describe Grape::Entity do
|
|
219
219
|
end
|
220
220
|
|
221
221
|
it 'presents with xml' do
|
222
|
-
entity = Class.new(
|
222
|
+
entity = Class.new(described_class)
|
223
223
|
entity.root 'examples', 'example'
|
224
224
|
entity.expose :name
|
225
225
|
|
@@ -238,18 +238,18 @@ describe Grape::Entity do
|
|
238
238
|
get '/example'
|
239
239
|
expect(last_response.status).to eq(200)
|
240
240
|
expect(last_response.headers['Content-type']).to eq('application/xml')
|
241
|
-
expect(last_response.body).to eq
|
242
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
243
|
-
<hash>
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
</hash>
|
248
|
-
XML
|
241
|
+
expect(last_response.body).to eq <<~XML
|
242
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
243
|
+
<hash>
|
244
|
+
<example>
|
245
|
+
<name>johnnyiller</name>
|
246
|
+
</example>
|
247
|
+
</hash>
|
248
|
+
XML
|
249
249
|
end
|
250
250
|
|
251
251
|
it 'presents with json' do
|
252
|
-
entity = Class.new(
|
252
|
+
entity = Class.new(described_class)
|
253
253
|
entity.root 'examples', 'example'
|
254
254
|
entity.expose :name
|
255
255
|
|
@@ -275,7 +275,7 @@ XML
|
|
275
275
|
# Include JSONP middleware
|
276
276
|
subject.use Rack::JSONP
|
277
277
|
|
278
|
-
entity = Class.new(
|
278
|
+
entity = Class.new(described_class)
|
279
279
|
entity.root 'examples', 'example'
|
280
280
|
entity.expose :name
|
281
281
|
|
@@ -315,7 +315,7 @@ XML
|
|
315
315
|
user1 = user.new(name: 'user1')
|
316
316
|
user2 = user.new(name: 'user2')
|
317
317
|
|
318
|
-
entity = Class.new(
|
318
|
+
entity = Class.new(described_class)
|
319
319
|
entity.expose :name
|
320
320
|
|
321
321
|
subject.format :json
|
@@ -326,7 +326,7 @@ XML
|
|
326
326
|
end
|
327
327
|
get '/example'
|
328
328
|
expect_response_json = {
|
329
|
-
'page'
|
329
|
+
'page' => 1,
|
330
330
|
'user1' => { 'name' => 'user1' },
|
331
331
|
'user2' => { 'name' => 'user2' }
|
332
332
|
}
|
@@ -5,6 +5,7 @@ require 'spec_helper'
|
|
5
5
|
describe Grape::Exceptions::ValidationErrors do
|
6
6
|
context 'api with rescue_from :all handler' do
|
7
7
|
subject { Class.new(Grape::API) }
|
8
|
+
|
8
9
|
before do
|
9
10
|
subject.rescue_from :all do |_e|
|
10
11
|
rack_response 'message was processed', 400
|
@@ -56,6 +57,7 @@ describe Grape::Exceptions::ValidationErrors do
|
|
56
57
|
|
57
58
|
context 'api with rescue_from :grape_exceptions handler' do
|
58
59
|
subject { Class.new(Grape::API) }
|
60
|
+
|
59
61
|
before do
|
60
62
|
subject.rescue_from :all do |_e|
|
61
63
|
rack_response 'message was processed', 400
|
@@ -93,6 +95,7 @@ describe Grape::Exceptions::ValidationErrors do
|
|
93
95
|
|
94
96
|
context 'api without a rescue handler' do
|
95
97
|
subject { Class.new(Grape::API) }
|
98
|
+
|
96
99
|
before do
|
97
100
|
subject.params do
|
98
101
|
requires :beer
|