grape 1.4.0 → 1.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -3
- data/README.md +56 -8
- data/UPGRADING.md +43 -4
- data/lib/grape/api.rb +2 -2
- data/lib/grape/dsl/helpers.rb +1 -0
- data/lib/grape/dsl/inside_route.rb +26 -38
- data/lib/grape/dsl/routing.rb +2 -4
- data/lib/grape/middleware/base.rb +2 -1
- data/lib/grape/middleware/error.rb +10 -12
- data/lib/grape/middleware/stack.rb +17 -4
- data/lib/grape/request.rb +1 -1
- data/lib/grape/router.rb +1 -1
- data/lib/grape/router/attribute_translator.rb +2 -2
- data/lib/grape/util/base_inheritable.rb +2 -2
- data/lib/grape/util/lazy_value.rb +1 -0
- data/lib/grape/validations/params_scope.rb +2 -1
- data/lib/grape/validations/types/custom_type_coercer.rb +13 -1
- data/lib/grape/validations/validators/as.rb +1 -1
- data/lib/grape/validations/validators/base.rb +2 -4
- data/lib/grape/validations/validators/default.rb +3 -4
- data/lib/grape/validations/validators/except_values.rb +1 -1
- data/lib/grape/validations/validators/values.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +10 -0
- data/spec/grape/dsl/inside_route_spec.rb +7 -0
- data/spec/grape/endpoint/declared_spec.rb +590 -0
- data/spec/grape/endpoint_spec.rb +0 -534
- data/spec/grape/entity_spec.rb +6 -0
- data/spec/grape/middleware/error_spec.rb +1 -1
- data/spec/grape/middleware/stack_spec.rb +3 -1
- data/spec/grape/validations/params_scope_spec.rb +26 -0
- data/spec/grape/validations/validators/coerce_spec.rb +24 -0
- data/spec/grape/validations/validators/default_spec.rb +49 -0
- data/spec/grape/validations/validators/except_values_spec.rb +1 -0
- data/spec/spec_helper.rb +0 -10
- data/spec/support/chunks.rb +14 -0
- data/spec/support/versioned_helpers.rb +3 -5
- metadata +9 -5
data/spec/grape/endpoint_spec.rb
CHANGED
@@ -280,540 +280,6 @@ describe Grape::Endpoint do
|
|
280
280
|
end
|
281
281
|
end
|
282
282
|
|
283
|
-
describe '#declared' do
|
284
|
-
before do
|
285
|
-
subject.format :json
|
286
|
-
subject.params do
|
287
|
-
requires :first
|
288
|
-
optional :second
|
289
|
-
optional :third, default: 'third-default'
|
290
|
-
optional :nested, type: Hash do
|
291
|
-
optional :fourth
|
292
|
-
optional :fifth
|
293
|
-
optional :nested_two, type: Hash do
|
294
|
-
optional :sixth
|
295
|
-
optional :nested_three, type: Hash do
|
296
|
-
optional :seventh
|
297
|
-
end
|
298
|
-
end
|
299
|
-
optional :nested_arr, type: Array do
|
300
|
-
optional :eighth
|
301
|
-
end
|
302
|
-
end
|
303
|
-
optional :arr, type: Array do
|
304
|
-
optional :nineth
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
context 'when params are not built with default class' do
|
310
|
-
it 'returns an object that corresponds with the params class - hash with indifferent access' do
|
311
|
-
subject.params do
|
312
|
-
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
|
313
|
-
end
|
314
|
-
subject.get '/declared' do
|
315
|
-
d = declared(params, include_missing: true)
|
316
|
-
{ declared_class: d.class.to_s }
|
317
|
-
end
|
318
|
-
|
319
|
-
get '/declared?first=present'
|
320
|
-
expect(JSON.parse(last_response.body)['declared_class']).to eq('ActiveSupport::HashWithIndifferentAccess')
|
321
|
-
end
|
322
|
-
|
323
|
-
it 'returns an object that corresponds with the params class - hashie mash' do
|
324
|
-
subject.params do
|
325
|
-
build_with Grape::Extensions::Hashie::Mash::ParamBuilder
|
326
|
-
end
|
327
|
-
subject.get '/declared' do
|
328
|
-
d = declared(params, include_missing: true)
|
329
|
-
{ declared_class: d.class.to_s }
|
330
|
-
end
|
331
|
-
|
332
|
-
get '/declared?first=present'
|
333
|
-
expect(JSON.parse(last_response.body)['declared_class']).to eq('Hashie::Mash')
|
334
|
-
end
|
335
|
-
|
336
|
-
it 'returns an object that corresponds with the params class - hash' do
|
337
|
-
subject.params do
|
338
|
-
build_with Grape::Extensions::Hash::ParamBuilder
|
339
|
-
end
|
340
|
-
subject.get '/declared' do
|
341
|
-
d = declared(params, include_missing: true)
|
342
|
-
{ declared_class: d.class.to_s }
|
343
|
-
end
|
344
|
-
|
345
|
-
get '/declared?first=present'
|
346
|
-
expect(JSON.parse(last_response.body)['declared_class']).to eq('Hash')
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
it 'should show nil for nested params if include_missing is true' do
|
351
|
-
subject.get '/declared' do
|
352
|
-
declared(params, include_missing: true)
|
353
|
-
end
|
354
|
-
|
355
|
-
get '/declared?first=present'
|
356
|
-
expect(last_response.status).to eq(200)
|
357
|
-
expect(JSON.parse(last_response.body)['nested']['fourth']).to be_nil
|
358
|
-
end
|
359
|
-
|
360
|
-
it 'does not work in a before filter' do
|
361
|
-
subject.before do
|
362
|
-
declared(params)
|
363
|
-
end
|
364
|
-
subject.get('/declared') { declared(params) }
|
365
|
-
|
366
|
-
expect { get('/declared') }.to raise_error(
|
367
|
-
Grape::DSL::InsideRoute::MethodNotYetAvailable
|
368
|
-
)
|
369
|
-
end
|
370
|
-
|
371
|
-
it 'has as many keys as there are declared params' do
|
372
|
-
subject.get '/declared' do
|
373
|
-
declared(params)
|
374
|
-
end
|
375
|
-
get '/declared?first=present'
|
376
|
-
expect(last_response.status).to eq(200)
|
377
|
-
expect(JSON.parse(last_response.body).keys.size).to eq(5)
|
378
|
-
end
|
379
|
-
|
380
|
-
it 'has a optional param with default value all the time' do
|
381
|
-
subject.get '/declared' do
|
382
|
-
declared(params)
|
383
|
-
end
|
384
|
-
get '/declared?first=one'
|
385
|
-
expect(last_response.status).to eq(200)
|
386
|
-
expect(JSON.parse(last_response.body)['third']).to eql('third-default')
|
387
|
-
end
|
388
|
-
|
389
|
-
it 'builds nested params' do
|
390
|
-
subject.get '/declared' do
|
391
|
-
declared(params)
|
392
|
-
end
|
393
|
-
|
394
|
-
get '/declared?first=present&nested[fourth]=1'
|
395
|
-
expect(last_response.status).to eq(200)
|
396
|
-
expect(JSON.parse(last_response.body)['nested'].keys.size).to eq 4
|
397
|
-
end
|
398
|
-
|
399
|
-
it 'builds nested params when given array' do
|
400
|
-
subject.get '/dummy' do
|
401
|
-
end
|
402
|
-
subject.params do
|
403
|
-
requires :first
|
404
|
-
optional :second
|
405
|
-
optional :third, default: 'third-default'
|
406
|
-
optional :nested, type: Array do
|
407
|
-
optional :fourth
|
408
|
-
end
|
409
|
-
end
|
410
|
-
subject.get '/declared' do
|
411
|
-
declared(params)
|
412
|
-
end
|
413
|
-
|
414
|
-
get '/declared?first=present&nested[][fourth]=1&nested[][fourth]=2'
|
415
|
-
expect(last_response.status).to eq(200)
|
416
|
-
expect(JSON.parse(last_response.body)['nested'].size).to eq 2
|
417
|
-
end
|
418
|
-
|
419
|
-
context 'sets nested objects when the param is missing' do
|
420
|
-
it 'to be a hash when include_missing is true' do
|
421
|
-
subject.get '/declared' do
|
422
|
-
declared(params, include_missing: true)
|
423
|
-
end
|
424
|
-
|
425
|
-
get '/declared?first=present'
|
426
|
-
expect(last_response.status).to eq(200)
|
427
|
-
expect(JSON.parse(last_response.body)['nested']).to eq({})
|
428
|
-
end
|
429
|
-
|
430
|
-
it 'to be an array when include_missing is true' do
|
431
|
-
subject.get '/declared' do
|
432
|
-
declared(params, include_missing: true)
|
433
|
-
end
|
434
|
-
|
435
|
-
get '/declared?first=present'
|
436
|
-
expect(last_response.status).to eq(200)
|
437
|
-
expect(JSON.parse(last_response.body)['arr']).to be_a(Array)
|
438
|
-
end
|
439
|
-
|
440
|
-
it 'to be an array when nested and include_missing is true' do
|
441
|
-
subject.get '/declared' do
|
442
|
-
declared(params, include_missing: true)
|
443
|
-
end
|
444
|
-
|
445
|
-
get '/declared?first=present&nested[fourth]=1'
|
446
|
-
expect(last_response.status).to eq(200)
|
447
|
-
expect(JSON.parse(last_response.body)['nested']['nested_arr']).to be_a(Array)
|
448
|
-
end
|
449
|
-
|
450
|
-
it 'to be nil when include_missing is false' do
|
451
|
-
subject.get '/declared' do
|
452
|
-
declared(params, include_missing: false)
|
453
|
-
end
|
454
|
-
|
455
|
-
get '/declared?first=present'
|
456
|
-
expect(last_response.status).to eq(200)
|
457
|
-
expect(JSON.parse(last_response.body)['nested']).to be_nil
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
it 'filters out any additional params that are given' do
|
462
|
-
subject.get '/declared' do
|
463
|
-
declared(params)
|
464
|
-
end
|
465
|
-
get '/declared?first=one&other=two'
|
466
|
-
expect(last_response.status).to eq(200)
|
467
|
-
expect(JSON.parse(last_response.body).key?(:other)).to eq false
|
468
|
-
end
|
469
|
-
|
470
|
-
it 'stringifies if that option is passed' do
|
471
|
-
subject.get '/declared' do
|
472
|
-
declared(params, stringify: true)
|
473
|
-
end
|
474
|
-
|
475
|
-
get '/declared?first=one&other=two'
|
476
|
-
expect(last_response.status).to eq(200)
|
477
|
-
expect(JSON.parse(last_response.body)['first']).to eq 'one'
|
478
|
-
end
|
479
|
-
|
480
|
-
it 'does not include missing attributes if that option is passed' do
|
481
|
-
subject.get '/declared' do
|
482
|
-
error! 'expected nil', 400 if declared(params, include_missing: false).key?(:second)
|
483
|
-
''
|
484
|
-
end
|
485
|
-
|
486
|
-
get '/declared?first=one&other=two'
|
487
|
-
expect(last_response.status).to eq(200)
|
488
|
-
end
|
489
|
-
|
490
|
-
it 'does not include renamed missing attributes if that option is passed' do
|
491
|
-
subject.params do
|
492
|
-
optional :renamed_original, as: :renamed
|
493
|
-
end
|
494
|
-
subject.get '/declared' do
|
495
|
-
error! 'expected nil', 400 if declared(params, include_missing: false).key?(:renamed)
|
496
|
-
''
|
497
|
-
end
|
498
|
-
|
499
|
-
get '/declared?first=one&other=two'
|
500
|
-
expect(last_response.status).to eq(200)
|
501
|
-
end
|
502
|
-
|
503
|
-
it 'includes attributes with value that evaluates to false' do
|
504
|
-
subject.params do
|
505
|
-
requires :first
|
506
|
-
optional :boolean
|
507
|
-
end
|
508
|
-
|
509
|
-
subject.post '/declared' do
|
510
|
-
error!('expected false', 400) if declared(params, include_missing: false)[:boolean] != false
|
511
|
-
''
|
512
|
-
end
|
513
|
-
|
514
|
-
post '/declared', ::Grape::Json.dump(first: 'one', boolean: false), 'CONTENT_TYPE' => 'application/json'
|
515
|
-
expect(last_response.status).to eq(201)
|
516
|
-
end
|
517
|
-
|
518
|
-
it 'includes attributes with value that evaluates to nil' do
|
519
|
-
subject.params do
|
520
|
-
requires :first
|
521
|
-
optional :second
|
522
|
-
end
|
523
|
-
|
524
|
-
subject.post '/declared' do
|
525
|
-
error!('expected nil', 400) unless declared(params, include_missing: false)[:second].nil?
|
526
|
-
''
|
527
|
-
end
|
528
|
-
|
529
|
-
post '/declared', ::Grape::Json.dump(first: 'one', second: nil), 'CONTENT_TYPE' => 'application/json'
|
530
|
-
expect(last_response.status).to eq(201)
|
531
|
-
end
|
532
|
-
|
533
|
-
it 'includes missing attributes with defaults when there are nested hashes' do
|
534
|
-
subject.get '/dummy' do
|
535
|
-
end
|
536
|
-
|
537
|
-
subject.params do
|
538
|
-
requires :first
|
539
|
-
optional :second
|
540
|
-
optional :third, default: nil
|
541
|
-
optional :nested, type: Hash do
|
542
|
-
optional :fourth, default: nil
|
543
|
-
optional :fifth, default: nil
|
544
|
-
requires :nested_nested, type: Hash do
|
545
|
-
optional :sixth, default: 'sixth-default'
|
546
|
-
optional :seven, default: nil
|
547
|
-
end
|
548
|
-
end
|
549
|
-
end
|
550
|
-
|
551
|
-
subject.get '/declared' do
|
552
|
-
declared(params, include_missing: false)
|
553
|
-
end
|
554
|
-
|
555
|
-
get '/declared?first=present&nested[fourth]=&nested[nested_nested][sixth]=sixth'
|
556
|
-
json = JSON.parse(last_response.body)
|
557
|
-
expect(last_response.status).to eq(200)
|
558
|
-
expect(json['first']).to eq 'present'
|
559
|
-
expect(json['nested'].keys).to eq %w[fourth fifth nested_nested]
|
560
|
-
expect(json['nested']['fourth']).to eq ''
|
561
|
-
expect(json['nested']['nested_nested'].keys).to eq %w[sixth seven]
|
562
|
-
expect(json['nested']['nested_nested']['sixth']).to eq 'sixth'
|
563
|
-
end
|
564
|
-
|
565
|
-
it 'does not include missing attributes when there are nested hashes' do
|
566
|
-
subject.get '/dummy' do
|
567
|
-
end
|
568
|
-
|
569
|
-
subject.params do
|
570
|
-
requires :first
|
571
|
-
optional :second
|
572
|
-
optional :third
|
573
|
-
optional :nested, type: Hash do
|
574
|
-
optional :fourth
|
575
|
-
optional :fifth
|
576
|
-
end
|
577
|
-
end
|
578
|
-
|
579
|
-
subject.get '/declared' do
|
580
|
-
declared(params, include_missing: false)
|
581
|
-
end
|
582
|
-
|
583
|
-
get '/declared?first=present&nested[fourth]=4'
|
584
|
-
json = JSON.parse(last_response.body)
|
585
|
-
expect(last_response.status).to eq(200)
|
586
|
-
expect(json['first']).to eq 'present'
|
587
|
-
expect(json['nested'].keys).to eq %w[fourth]
|
588
|
-
expect(json['nested']['fourth']).to eq '4'
|
589
|
-
end
|
590
|
-
end
|
591
|
-
|
592
|
-
describe '#declared; call from child namespace' do
|
593
|
-
before do
|
594
|
-
subject.format :json
|
595
|
-
subject.namespace :parent do
|
596
|
-
params do
|
597
|
-
requires :parent_name, type: String
|
598
|
-
end
|
599
|
-
|
600
|
-
namespace ':parent_name' do
|
601
|
-
params do
|
602
|
-
requires :child_name, type: String
|
603
|
-
requires :child_age, type: Integer
|
604
|
-
end
|
605
|
-
|
606
|
-
namespace ':child_name' do
|
607
|
-
params do
|
608
|
-
requires :grandchild_name, type: String
|
609
|
-
end
|
610
|
-
|
611
|
-
get ':grandchild_name' do
|
612
|
-
{
|
613
|
-
'params' => params,
|
614
|
-
'without_parent_namespaces' => declared(params, include_parent_namespaces: false),
|
615
|
-
'with_parent_namespaces' => declared(params, include_parent_namespaces: true)
|
616
|
-
}
|
617
|
-
end
|
618
|
-
end
|
619
|
-
end
|
620
|
-
end
|
621
|
-
|
622
|
-
get '/parent/foo/bar/baz', child_age: 5, extra: 'hello'
|
623
|
-
end
|
624
|
-
|
625
|
-
let(:parsed_response) { JSON.parse(last_response.body, symbolize_names: true) }
|
626
|
-
|
627
|
-
it { expect(last_response.status).to eq 200 }
|
628
|
-
|
629
|
-
context 'with include_parent_namespaces: false' do
|
630
|
-
it 'returns declared parameters only from current namespace' do
|
631
|
-
expect(parsed_response[:without_parent_namespaces]).to eq(
|
632
|
-
grandchild_name: 'baz'
|
633
|
-
)
|
634
|
-
end
|
635
|
-
end
|
636
|
-
|
637
|
-
context 'with include_parent_namespaces: true' do
|
638
|
-
it 'returns declared parameters from every parent namespace' do
|
639
|
-
expect(parsed_response[:with_parent_namespaces]).to eq(
|
640
|
-
parent_name: 'foo',
|
641
|
-
child_name: 'bar',
|
642
|
-
grandchild_name: 'baz',
|
643
|
-
child_age: 5
|
644
|
-
)
|
645
|
-
end
|
646
|
-
end
|
647
|
-
|
648
|
-
context 'without declaration' do
|
649
|
-
it 'returns all requested parameters' do
|
650
|
-
expect(parsed_response[:params]).to eq(
|
651
|
-
parent_name: 'foo',
|
652
|
-
child_name: 'bar',
|
653
|
-
grandchild_name: 'baz',
|
654
|
-
child_age: 5,
|
655
|
-
extra: 'hello'
|
656
|
-
)
|
657
|
-
end
|
658
|
-
end
|
659
|
-
end
|
660
|
-
|
661
|
-
describe '#declared; from a nested mounted endpoint' do
|
662
|
-
before do
|
663
|
-
doubly_mounted = Class.new(Grape::API)
|
664
|
-
doubly_mounted.namespace :more do
|
665
|
-
params do
|
666
|
-
requires :y, type: Integer
|
667
|
-
end
|
668
|
-
route_param :y do
|
669
|
-
get do
|
670
|
-
{
|
671
|
-
params: params,
|
672
|
-
declared_params: declared(params)
|
673
|
-
}
|
674
|
-
end
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
|
-
mounted = Class.new(Grape::API)
|
679
|
-
mounted.namespace :another do
|
680
|
-
params do
|
681
|
-
requires :mount_space, type: Integer
|
682
|
-
end
|
683
|
-
route_param :mount_space do
|
684
|
-
mount doubly_mounted
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
subject.format :json
|
689
|
-
subject.namespace :something do
|
690
|
-
params do
|
691
|
-
requires :id, type: Integer
|
692
|
-
end
|
693
|
-
resource ':id' do
|
694
|
-
mount mounted
|
695
|
-
end
|
696
|
-
end
|
697
|
-
end
|
698
|
-
|
699
|
-
it 'can access parent attributes' do
|
700
|
-
get '/something/123/another/456/more/789'
|
701
|
-
expect(last_response.status).to eq 200
|
702
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
703
|
-
|
704
|
-
# test all three levels of params
|
705
|
-
expect(json[:declared_params][:y]).to eq 789
|
706
|
-
expect(json[:declared_params][:mount_space]).to eq 456
|
707
|
-
expect(json[:declared_params][:id]).to eq 123
|
708
|
-
end
|
709
|
-
end
|
710
|
-
|
711
|
-
describe '#declared; mixed nesting' do
|
712
|
-
before do
|
713
|
-
subject.format :json
|
714
|
-
subject.resource :users do
|
715
|
-
route_param :id, type: Integer, desc: 'ID desc' do
|
716
|
-
# Adding this causes route_setting(:declared_params) to be nil for the
|
717
|
-
# get block in namespace 'foo' below
|
718
|
-
get do
|
719
|
-
end
|
720
|
-
|
721
|
-
namespace 'foo' do
|
722
|
-
get do
|
723
|
-
{
|
724
|
-
params: params,
|
725
|
-
declared_params: declared(params),
|
726
|
-
declared_params_no_parent: declared(params, include_parent_namespaces: false)
|
727
|
-
}
|
728
|
-
end
|
729
|
-
end
|
730
|
-
end
|
731
|
-
end
|
732
|
-
end
|
733
|
-
|
734
|
-
it 'can access parent route_param' do
|
735
|
-
get '/users/123/foo', bar: 'bar'
|
736
|
-
expect(last_response.status).to eq 200
|
737
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
738
|
-
|
739
|
-
expect(json[:declared_params][:id]).to eq 123
|
740
|
-
expect(json[:declared_params_no_parent][:id]).to eq nil
|
741
|
-
end
|
742
|
-
end
|
743
|
-
|
744
|
-
describe '#declared; with multiple route_param' do
|
745
|
-
before do
|
746
|
-
mounted = Class.new(Grape::API)
|
747
|
-
mounted.namespace :albums do
|
748
|
-
get do
|
749
|
-
declared(params)
|
750
|
-
end
|
751
|
-
end
|
752
|
-
|
753
|
-
subject.format :json
|
754
|
-
subject.namespace :artists do
|
755
|
-
route_param :id, type: Integer do
|
756
|
-
get do
|
757
|
-
declared(params)
|
758
|
-
end
|
759
|
-
|
760
|
-
params do
|
761
|
-
requires :filter, type: String
|
762
|
-
end
|
763
|
-
get :some_route do
|
764
|
-
declared(params)
|
765
|
-
end
|
766
|
-
end
|
767
|
-
|
768
|
-
route_param :artist_id, type: Integer do
|
769
|
-
namespace :compositions do
|
770
|
-
get do
|
771
|
-
declared(params)
|
772
|
-
end
|
773
|
-
end
|
774
|
-
end
|
775
|
-
|
776
|
-
route_param :compositor_id, type: Integer do
|
777
|
-
mount mounted
|
778
|
-
end
|
779
|
-
end
|
780
|
-
end
|
781
|
-
|
782
|
-
it 'return only :id without :artist_id' do
|
783
|
-
get '/artists/1'
|
784
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
785
|
-
|
786
|
-
expect(json.key?(:id)).to be_truthy
|
787
|
-
expect(json.key?(:artist_id)).not_to be_truthy
|
788
|
-
end
|
789
|
-
|
790
|
-
it 'return only :artist_id without :id' do
|
791
|
-
get '/artists/1/compositions'
|
792
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
793
|
-
|
794
|
-
expect(json.key?(:artist_id)).to be_truthy
|
795
|
-
expect(json.key?(:id)).not_to be_truthy
|
796
|
-
end
|
797
|
-
|
798
|
-
it 'return :filter and :id parameters in declared for second enpoint inside route_param' do
|
799
|
-
get '/artists/1/some_route', filter: 'some_filter'
|
800
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
801
|
-
|
802
|
-
expect(json.key?(:filter)).to be_truthy
|
803
|
-
expect(json.key?(:id)).to be_truthy
|
804
|
-
expect(json.key?(:artist_id)).not_to be_truthy
|
805
|
-
end
|
806
|
-
|
807
|
-
it 'return :compositor_id for mounter in route_param' do
|
808
|
-
get '/artists/1/albums'
|
809
|
-
json = JSON.parse(last_response.body, symbolize_names: true)
|
810
|
-
|
811
|
-
expect(json.key?(:compositor_id)).to be_truthy
|
812
|
-
expect(json.key?(:id)).not_to be_truthy
|
813
|
-
expect(json.key?(:artist_id)).not_to be_truthy
|
814
|
-
end
|
815
|
-
end
|
816
|
-
|
817
283
|
describe '#params' do
|
818
284
|
it 'is available to the caller' do
|
819
285
|
subject.get('/hey') do
|