grape 1.3.1 → 1.5.1
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 +82 -1
- data/LICENSE +1 -1
- data/README.md +104 -21
- data/UPGRADING.md +265 -39
- data/lib/grape.rb +2 -2
- data/lib/grape/api.rb +2 -2
- data/lib/grape/api/instance.rb +29 -28
- data/lib/grape/dsl/helpers.rb +1 -0
- data/lib/grape/dsl/inside_route.rb +69 -36
- data/lib/grape/dsl/parameters.rb +7 -3
- data/lib/grape/dsl/routing.rb +2 -4
- data/lib/grape/dsl/validations.rb +18 -1
- data/lib/grape/eager_load.rb +1 -1
- data/lib/grape/endpoint.rb +8 -6
- data/lib/grape/http/headers.rb +1 -0
- data/lib/grape/middleware/base.rb +2 -1
- data/lib/grape/middleware/error.rb +10 -12
- data/lib/grape/middleware/formatter.rb +3 -3
- data/lib/grape/middleware/stack.rb +21 -8
- data/lib/grape/middleware/versioner/header.rb +1 -1
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/path.rb +2 -2
- data/lib/grape/request.rb +1 -1
- data/lib/grape/router.rb +30 -43
- data/lib/grape/router/attribute_translator.rb +26 -5
- data/lib/grape/router/route.rb +3 -22
- data/lib/grape/{serve_file → serve_stream}/file_body.rb +1 -1
- data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +1 -1
- data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +8 -8
- data/lib/grape/util/base_inheritable.rb +11 -8
- data/lib/grape/util/lazy_value.rb +1 -0
- data/lib/grape/util/reverse_stackable_values.rb +3 -1
- data/lib/grape/util/stackable_values.rb +3 -1
- data/lib/grape/validations/attributes_iterator.rb +8 -0
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/params_scope.rb +8 -6
- data/lib/grape/validations/single_attribute_iterator.rb +1 -1
- data/lib/grape/validations/types.rb +6 -5
- data/lib/grape/validations/types/array_coercer.rb +14 -5
- data/lib/grape/validations/types/build_coercer.rb +5 -8
- data/lib/grape/validations/types/custom_type_coercer.rb +14 -2
- data/lib/grape/validations/types/dry_type_coercer.rb +36 -1
- data/lib/grape/validations/types/file.rb +15 -13
- data/lib/grape/validations/types/json.rb +40 -36
- data/lib/grape/validations/types/primitive_coercer.rb +11 -5
- data/lib/grape/validations/types/set_coercer.rb +6 -4
- data/lib/grape/validations/types/variant_collection_coercer.rb +1 -1
- data/lib/grape/validations/validator_factory.rb +1 -1
- data/lib/grape/validations/validators/as.rb +1 -1
- data/lib/grape/validations/validators/base.rb +4 -5
- data/lib/grape/validations/validators/coerce.rb +3 -10
- data/lib/grape/validations/validators/default.rb +3 -5
- data/lib/grape/validations/validators/except_values.rb +1 -1
- data/lib/grape/validations/validators/multiple_params_base.rb +2 -1
- data/lib/grape/validations/validators/regexp.rb +1 -1
- data/lib/grape/validations/validators/values.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api/instance_spec.rb +50 -0
- data/spec/grape/api_spec.rb +75 -0
- data/spec/grape/dsl/inside_route_spec.rb +182 -33
- data/spec/grape/endpoint/declared_spec.rb +601 -0
- data/spec/grape/endpoint_spec.rb +0 -521
- data/spec/grape/entity_spec.rb +6 -0
- data/spec/grape/integration/rack_sendfile_spec.rb +12 -8
- data/spec/grape/middleware/auth/strategies_spec.rb +1 -1
- data/spec/grape/middleware/error_spec.rb +1 -1
- data/spec/grape/middleware/formatter_spec.rb +1 -1
- data/spec/grape/middleware/stack_spec.rb +3 -1
- data/spec/grape/path_spec.rb +4 -4
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +13 -3
- data/spec/grape/validations/params_scope_spec.rb +26 -0
- data/spec/grape/validations/single_attribute_iterator_spec.rb +17 -6
- data/spec/grape/validations/types/array_coercer_spec.rb +35 -0
- data/spec/grape/validations/types/primitive_coercer_spec.rb +65 -5
- data/spec/grape/validations/types/set_coercer_spec.rb +34 -0
- data/spec/grape/validations/types_spec.rb +1 -1
- data/spec/grape/validations/validators/coerce_spec.rb +317 -29
- data/spec/grape/validations/validators/default_spec.rb +170 -0
- data/spec/grape/validations/validators/except_values_spec.rb +1 -0
- data/spec/grape/validations/validators/values_spec.rb +1 -1
- data/spec/grape/validations_spec.rb +290 -18
- data/spec/integration/eager_load/eager_load_spec.rb +15 -0
- data/spec/spec_helper.rb +0 -10
- data/spec/support/chunks.rb +14 -0
- data/spec/support/versioned_helpers.rb +3 -5
- metadata +18 -8
@@ -319,7 +319,7 @@ describe Grape::Validations::ValuesValidator do
|
|
319
319
|
expect(last_response.status).to eq 200
|
320
320
|
end
|
321
321
|
|
322
|
-
it '
|
322
|
+
it 'accepts for an optional param with a list of values' do
|
323
323
|
put('/optional_with_array_of_string_values', optional: nil)
|
324
324
|
expect(last_response.status).to eq 200
|
325
325
|
end
|
@@ -9,6 +9,10 @@ describe Grape::Validations do
|
|
9
9
|
subject
|
10
10
|
end
|
11
11
|
|
12
|
+
def declared_params
|
13
|
+
subject.namespace_stackable(:declared_params).flatten
|
14
|
+
end
|
15
|
+
|
12
16
|
describe 'params' do
|
13
17
|
context 'optional' do
|
14
18
|
before do
|
@@ -41,7 +45,7 @@ describe Grape::Validations do
|
|
41
45
|
subject.params do
|
42
46
|
optional :some_param
|
43
47
|
end
|
44
|
-
expect(
|
48
|
+
expect(declared_params).to eq([:some_param])
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
@@ -61,7 +65,7 @@ describe Grape::Validations do
|
|
61
65
|
|
62
66
|
it 'adds entity documentation to declared params' do
|
63
67
|
define_optional_using
|
64
|
-
expect(
|
68
|
+
expect(declared_params).to eq(%i[field_a field_b])
|
65
69
|
end
|
66
70
|
|
67
71
|
it 'works when field_a and field_b are not present' do
|
@@ -108,7 +112,7 @@ describe Grape::Validations do
|
|
108
112
|
subject.params do
|
109
113
|
requires :some_param
|
110
114
|
end
|
111
|
-
expect(
|
115
|
+
expect(declared_params).to eq([:some_param])
|
112
116
|
end
|
113
117
|
|
114
118
|
it 'works when required field is present but nil' do
|
@@ -193,7 +197,7 @@ describe Grape::Validations do
|
|
193
197
|
|
194
198
|
it 'adds entity documentation to declared params' do
|
195
199
|
define_requires_all
|
196
|
-
expect(
|
200
|
+
expect(declared_params).to eq(%i[required_field optional_field])
|
197
201
|
end
|
198
202
|
|
199
203
|
it 'errors when required_field is not present' do
|
@@ -228,7 +232,7 @@ describe Grape::Validations do
|
|
228
232
|
|
229
233
|
it 'adds entity documentation to declared params' do
|
230
234
|
define_requires_none
|
231
|
-
expect(
|
235
|
+
expect(declared_params).to eq(%i[required_field optional_field])
|
232
236
|
end
|
233
237
|
|
234
238
|
it 'errors when required_field is not present' do
|
@@ -258,7 +262,7 @@ describe Grape::Validations do
|
|
258
262
|
|
259
263
|
it 'adds only the entity documentation to declared params, nothing more' do
|
260
264
|
define_requires_all
|
261
|
-
expect(
|
265
|
+
expect(declared_params).to eq(%i[required_field optional_field])
|
262
266
|
end
|
263
267
|
end
|
264
268
|
|
@@ -324,7 +328,7 @@ describe Grape::Validations do
|
|
324
328
|
requires :key
|
325
329
|
end
|
326
330
|
end
|
327
|
-
expect(
|
331
|
+
expect(declared_params).to eq([items: [:key]])
|
328
332
|
end
|
329
333
|
end
|
330
334
|
|
@@ -396,7 +400,7 @@ describe Grape::Validations do
|
|
396
400
|
requires :key
|
397
401
|
end
|
398
402
|
end
|
399
|
-
expect(
|
403
|
+
expect(declared_params).to eq([items: [:key]])
|
400
404
|
end
|
401
405
|
end
|
402
406
|
|
@@ -459,7 +463,7 @@ describe Grape::Validations do
|
|
459
463
|
requires :key
|
460
464
|
end
|
461
465
|
end
|
462
|
-
expect(
|
466
|
+
expect(declared_params).to eq([items: [:key]])
|
463
467
|
end
|
464
468
|
end
|
465
469
|
|
@@ -574,7 +578,7 @@ describe Grape::Validations do
|
|
574
578
|
# NOTE: with body parameters in json or XML or similar this
|
575
579
|
# should actually fail with: children[parents][name] is missing.
|
576
580
|
expect(last_response.status).to eq(400)
|
577
|
-
expect(last_response.body).to eq('children[1][parents] is missing')
|
581
|
+
expect(last_response.body).to eq('children[1][parents] is missing, children[0][parents][1][name] is missing, children[0][parents][1][name] is empty')
|
578
582
|
end
|
579
583
|
|
580
584
|
it 'errors when a parameter is not present in array within array' do
|
@@ -615,7 +619,7 @@ describe Grape::Validations do
|
|
615
619
|
|
616
620
|
get '/within_array', children: [name: 'Jay']
|
617
621
|
expect(last_response.status).to eq(400)
|
618
|
-
expect(last_response.body).to eq('children[0][parents] is missing')
|
622
|
+
expect(last_response.body).to eq('children[0][parents] is missing, children[0][parents][0][name] is missing, children[0][parents][0][name] is empty')
|
619
623
|
end
|
620
624
|
|
621
625
|
it 'errors when param is not an Array' do
|
@@ -763,7 +767,7 @@ describe Grape::Validations do
|
|
763
767
|
expect(last_response.status).to eq(200)
|
764
768
|
put_with_json '/within_array', children: [name: 'Jay']
|
765
769
|
expect(last_response.status).to eq(400)
|
766
|
-
expect(last_response.body).to eq('children[0][parents] is missing')
|
770
|
+
expect(last_response.body).to eq('children[0][parents] is missing, children[0][parents][0][name] is missing')
|
767
771
|
end
|
768
772
|
end
|
769
773
|
|
@@ -813,7 +817,7 @@ describe Grape::Validations do
|
|
813
817
|
requires :key
|
814
818
|
end
|
815
819
|
end
|
816
|
-
expect(
|
820
|
+
expect(declared_params).to eq([items: [:key]])
|
817
821
|
end
|
818
822
|
end
|
819
823
|
|
@@ -838,7 +842,7 @@ describe Grape::Validations do
|
|
838
842
|
it 'does internal validations if the outer group is present' do
|
839
843
|
get '/nested_optional_group', items: [{ key: 'foo' }]
|
840
844
|
expect(last_response.status).to eq(400)
|
841
|
-
expect(last_response.body).to eq('items[0][required_subitems] is missing')
|
845
|
+
expect(last_response.body).to eq('items[0][required_subitems] is missing, items[0][required_subitems][0][value] is missing')
|
842
846
|
|
843
847
|
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }]
|
844
848
|
expect(last_response.status).to eq(200)
|
@@ -858,7 +862,7 @@ describe Grape::Validations do
|
|
858
862
|
it 'handles validation within arrays' do
|
859
863
|
get '/nested_optional_group', items: [{ key: 'foo' }]
|
860
864
|
expect(last_response.status).to eq(400)
|
861
|
-
expect(last_response.body).to eq('items[0][required_subitems] is missing')
|
865
|
+
expect(last_response.body).to eq('items[0][required_subitems] is missing, items[0][required_subitems][0][value] is missing')
|
862
866
|
|
863
867
|
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }]
|
864
868
|
expect(last_response.status).to eq(200)
|
@@ -877,7 +881,275 @@ describe Grape::Validations do
|
|
877
881
|
requires(:required_subitems, type: Array) { requires :value }
|
878
882
|
end
|
879
883
|
end
|
880
|
-
expect(
|
884
|
+
expect(declared_params).to eq([items: [:key, { optional_subitems: [:value] }, { required_subitems: [:value] }]])
|
885
|
+
end
|
886
|
+
|
887
|
+
context <<~DESC do
|
888
|
+
Issue occurs whenever:
|
889
|
+
* param structure with at least three levels
|
890
|
+
* 1st level item is a required Array that has >1 entry with an optional item present and >1 entry with an optional item missing
|
891
|
+
* 2nd level is an optional Array or Hash
|
892
|
+
* 3rd level is a required item (can be any type)
|
893
|
+
* additional levels do not effect the issue from occuring
|
894
|
+
DESC
|
895
|
+
|
896
|
+
it "example based off actual real world use case" do
|
897
|
+
subject.params do
|
898
|
+
requires :orders, type: Array do
|
899
|
+
requires :id, type: Integer
|
900
|
+
optional :drugs, type: Array do
|
901
|
+
requires :batches, type: Array do
|
902
|
+
requires :batch_no, type: String
|
903
|
+
end
|
904
|
+
end
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
subject.get '/validate_required_arrays_under_optional_arrays' do
|
909
|
+
'validate_required_arrays_under_optional_arrays works!'
|
910
|
+
end
|
911
|
+
|
912
|
+
data = {
|
913
|
+
orders: [
|
914
|
+
{ id: 77, drugs: [{batches: [{batch_no: "A1234567"}]}]},
|
915
|
+
{ id: 70 }
|
916
|
+
]
|
917
|
+
}
|
918
|
+
|
919
|
+
get '/validate_required_arrays_under_optional_arrays', data
|
920
|
+
expect(last_response.body).to eq("validate_required_arrays_under_optional_arrays works!")
|
921
|
+
expect(last_response.status).to eq(200)
|
922
|
+
end
|
923
|
+
|
924
|
+
it "simplest example using Arry -> Array -> Hash -> String" do
|
925
|
+
subject.params do
|
926
|
+
requires :orders, type: Array do
|
927
|
+
requires :id, type: Integer
|
928
|
+
optional :drugs, type: Array do
|
929
|
+
requires :batch_no, type: String
|
930
|
+
end
|
931
|
+
end
|
932
|
+
end
|
933
|
+
|
934
|
+
subject.get '/validate_required_arrays_under_optional_arrays' do
|
935
|
+
'validate_required_arrays_under_optional_arrays works!'
|
936
|
+
end
|
937
|
+
|
938
|
+
data = {
|
939
|
+
orders: [
|
940
|
+
{ id: 77, drugs: [{batch_no: "A1234567"}]},
|
941
|
+
{ id: 70 }
|
942
|
+
]
|
943
|
+
}
|
944
|
+
|
945
|
+
get '/validate_required_arrays_under_optional_arrays', data
|
946
|
+
expect(last_response.body).to eq("validate_required_arrays_under_optional_arrays works!")
|
947
|
+
expect(last_response.status).to eq(200)
|
948
|
+
end
|
949
|
+
|
950
|
+
it "simplest example using Arry -> Hash -> String" do
|
951
|
+
subject.params do
|
952
|
+
requires :orders, type: Array do
|
953
|
+
requires :id, type: Integer
|
954
|
+
optional :drugs, type: Hash do
|
955
|
+
requires :batch_no, type: String
|
956
|
+
end
|
957
|
+
end
|
958
|
+
end
|
959
|
+
|
960
|
+
subject.get '/validate_required_arrays_under_optional_arrays' do
|
961
|
+
'validate_required_arrays_under_optional_arrays works!'
|
962
|
+
end
|
963
|
+
|
964
|
+
data = {
|
965
|
+
orders: [
|
966
|
+
{ id: 77, drugs: {batch_no: "A1234567"}},
|
967
|
+
{ id: 70 }
|
968
|
+
]
|
969
|
+
}
|
970
|
+
|
971
|
+
get '/validate_required_arrays_under_optional_arrays', data
|
972
|
+
expect(last_response.body).to eq("validate_required_arrays_under_optional_arrays works!")
|
973
|
+
expect(last_response.status).to eq(200)
|
974
|
+
end
|
975
|
+
|
976
|
+
it "correctly indexes invalida data" do
|
977
|
+
subject.params do
|
978
|
+
requires :orders, type: Array do
|
979
|
+
requires :id, type: Integer
|
980
|
+
optional :drugs, type: Array do
|
981
|
+
requires :batch_no, type: String
|
982
|
+
requires :quantity, type: Integer
|
983
|
+
end
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
987
|
+
subject.get '/correctly_indexes' do
|
988
|
+
'correctly_indexes works!'
|
989
|
+
end
|
990
|
+
|
991
|
+
data = {
|
992
|
+
orders: [
|
993
|
+
{ id: 70 },
|
994
|
+
{ id: 77, drugs: [{batch_no: "A1234567", quantity: 12}, {batch_no: "B222222"}]}
|
995
|
+
]
|
996
|
+
}
|
997
|
+
|
998
|
+
get '/correctly_indexes', data
|
999
|
+
expect(last_response.body).to eq("orders[1][drugs][1][quantity] is missing")
|
1000
|
+
expect(last_response.status).to eq(400)
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
context "multiple levels of optional and requires settings" do
|
1004
|
+
before do
|
1005
|
+
subject.params do
|
1006
|
+
requires :top, type: Array do
|
1007
|
+
requires :top_id, type: Integer, allow_blank: false
|
1008
|
+
optional :middle_1, type: Array do
|
1009
|
+
requires :middle_1_id, type: Integer, allow_blank: false
|
1010
|
+
optional :middle_2, type: Array do
|
1011
|
+
requires :middle_2_id, type: String, allow_blank: false
|
1012
|
+
optional :bottom, type: Array do
|
1013
|
+
requires :bottom_id, type: Integer, allow_blank: false
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
end
|
1017
|
+
end
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
subject.get '/multi_level' do
|
1021
|
+
'multi_level works!'
|
1022
|
+
end
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
it "with valid data" do
|
1026
|
+
data = {
|
1027
|
+
top: [
|
1028
|
+
{ top_id: 1, middle_1: [
|
1029
|
+
{middle_1_id: 11}, {middle_1_id: 12, middle_2: [
|
1030
|
+
{middle_2_id: 121}, {middle_2_id: 122, bottom: [{bottom_id: 1221}]}]}]},
|
1031
|
+
{ top_id: 2, middle_1: [
|
1032
|
+
{middle_1_id: 21}, {middle_1_id: 22, middle_2: [
|
1033
|
+
{middle_2_id: 221}]}]},
|
1034
|
+
{ top_id: 3, middle_1: [
|
1035
|
+
{middle_1_id: 31}, {middle_1_id: 32}]},
|
1036
|
+
{ top_id: 4 }
|
1037
|
+
]
|
1038
|
+
}
|
1039
|
+
|
1040
|
+
get '/multi_level', data
|
1041
|
+
expect(last_response.body).to eq("multi_level works!")
|
1042
|
+
expect(last_response.status).to eq(200)
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
it "with invalid data" do
|
1046
|
+
data = {
|
1047
|
+
top: [
|
1048
|
+
{ top_id: 1, middle_1: [
|
1049
|
+
{middle_1_id: 11}, {middle_1_id: 12, middle_2: [
|
1050
|
+
{middle_2_id: 121}, {middle_2_id: 122, bottom: [{bottom_id: nil}]}]}]},
|
1051
|
+
{ top_id: 2, middle_1: [
|
1052
|
+
{middle_1_id: 21}, {middle_1_id: 22, middle_2: [{middle_2_id: nil}]}]},
|
1053
|
+
{ top_id: 3, middle_1: [
|
1054
|
+
{middle_1_id: nil}, {middle_1_id: 32}]},
|
1055
|
+
{ top_id: nil, missing_top_id: 4 }
|
1056
|
+
]
|
1057
|
+
}
|
1058
|
+
# debugger
|
1059
|
+
get '/multi_level', data
|
1060
|
+
expect(last_response.body.split(", ")).to match_array([
|
1061
|
+
"top[3][top_id] is empty",
|
1062
|
+
"top[2][middle_1][0][middle_1_id] is empty",
|
1063
|
+
"top[1][middle_1][1][middle_2][0][middle_2_id] is empty",
|
1064
|
+
"top[0][middle_1][1][middle_2][1][bottom][0][bottom_id] is empty"
|
1065
|
+
])
|
1066
|
+
expect(last_response.status).to eq(400)
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
it "exactly_one_of" do
|
1072
|
+
subject.params do
|
1073
|
+
requires :orders, type: Array do
|
1074
|
+
requires :id, type: Integer
|
1075
|
+
optional :drugs, type: Hash do
|
1076
|
+
optional :batch_no, type: String
|
1077
|
+
optional :batch_id, type: String
|
1078
|
+
exactly_one_of :batch_no, :batch_id
|
1079
|
+
end
|
1080
|
+
end
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
subject.get '/exactly_one_of' do
|
1084
|
+
'exactly_one_of works!'
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
data = {
|
1088
|
+
orders: [
|
1089
|
+
{ id: 77, drugs: {batch_no: "A1234567"}},
|
1090
|
+
{ id: 70 }
|
1091
|
+
]
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
get '/exactly_one_of', data
|
1095
|
+
expect(last_response.body).to eq("exactly_one_of works!")
|
1096
|
+
expect(last_response.status).to eq(200)
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
it "at_least_one_of" do
|
1100
|
+
subject.params do
|
1101
|
+
requires :orders, type: Array do
|
1102
|
+
requires :id, type: Integer
|
1103
|
+
optional :drugs, type: Hash do
|
1104
|
+
optional :batch_no, type: String
|
1105
|
+
optional :batch_id, type: String
|
1106
|
+
at_least_one_of :batch_no, :batch_id
|
1107
|
+
end
|
1108
|
+
end
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
subject.get '/at_least_one_of' do
|
1112
|
+
'at_least_one_of works!'
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
data = {
|
1116
|
+
orders: [
|
1117
|
+
{ id: 77, drugs: {batch_no: "A1234567"}},
|
1118
|
+
{ id: 70 }
|
1119
|
+
]
|
1120
|
+
}
|
1121
|
+
|
1122
|
+
get '/at_least_one_of', data
|
1123
|
+
expect(last_response.body).to eq("at_least_one_of works!")
|
1124
|
+
expect(last_response.status).to eq(200)
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
it "all_or_none_of" do
|
1128
|
+
subject.params do
|
1129
|
+
requires :orders, type: Array do
|
1130
|
+
requires :id, type: Integer
|
1131
|
+
optional :drugs, type: Hash do
|
1132
|
+
optional :batch_no, type: String
|
1133
|
+
optional :batch_id, type: String
|
1134
|
+
all_or_none_of :batch_no, :batch_id
|
1135
|
+
end
|
1136
|
+
end
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
subject.get '/all_or_none_of' do
|
1140
|
+
'all_or_none_of works!'
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
data = {
|
1144
|
+
orders: [
|
1145
|
+
{ id: 77, drugs: {batch_no: "A1234567", batch_id: "12"}},
|
1146
|
+
{ id: 70 }
|
1147
|
+
]
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
get '/all_or_none_of', data
|
1151
|
+
expect(last_response.body).to eq("all_or_none_of works!")
|
1152
|
+
expect(last_response.status).to eq(200)
|
881
1153
|
end
|
882
1154
|
end
|
883
1155
|
|
@@ -1122,14 +1394,14 @@ describe Grape::Validations do
|
|
1122
1394
|
subject.params do
|
1123
1395
|
use :pagination
|
1124
1396
|
end
|
1125
|
-
expect(
|
1397
|
+
expect(declared_params).to eq %i[page per_page]
|
1126
1398
|
end
|
1127
1399
|
|
1128
1400
|
it 'by #use with multiple params' do
|
1129
1401
|
subject.params do
|
1130
1402
|
use :pagination, :period
|
1131
1403
|
end
|
1132
|
-
expect(
|
1404
|
+
expect(declared_params).to eq %i[page per_page start_date end_date]
|
1133
1405
|
end
|
1134
1406
|
end
|
1135
1407
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
4
|
+
require 'grape'
|
5
|
+
|
6
|
+
describe Grape do
|
7
|
+
it 'eager_load!' do
|
8
|
+
require 'grape/eager_load'
|
9
|
+
expect { Grape.eager_load! }.to_not raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'compile!' do
|
13
|
+
expect { Class.new(Grape::API).compile! }.to_not raise_error
|
14
|
+
end
|
15
|
+
end
|