spec/grape/validations_spec.rb in grape-0.7.0 vs spec/grape/validations_spec.rb in grape-0.8.0
- old
+ new
@@ -17,16 +17,16 @@
subject.get '/optional' do
'optional works!'
end
get '/optional', a_number: 'string'
- last_response.status.should == 400
- last_response.body.should == 'a_number is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('a_number is invalid')
get '/optional', a_number: 45
- last_response.status.should == 200
- last_response.body.should == 'optional works!'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('optional works!')
end
it "doesn't validate when param not present" do
subject.params do
optional :a_number, regexp: /^[0-9]+$/
@@ -34,19 +34,19 @@
subject.get '/optional' do
'optional works!'
end
get '/optional'
- last_response.status.should == 200
- last_response.body.should == 'optional works!'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('optional works!')
end
it 'adds to declared parameters' do
subject.params do
optional :some_param
end
- subject.settings[:declared_params].should == [:some_param]
+ expect(subject.settings[:declared_params]).to eq([:some_param])
end
end
context 'required' do
before do
@@ -58,33 +58,33 @@
end
end
it 'errors when param not present' do
get '/required'
- last_response.status.should == 400
- last_response.body.should == 'key is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('key is missing')
end
it "doesn't throw a missing param when param is present" do
get '/required', key: 'cool'
- last_response.status.should == 200
- last_response.body.should == 'required works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required works')
end
it 'adds to declared parameters' do
subject.params do
requires :some_param
end
- subject.settings[:declared_params].should == [:some_param]
+ expect(subject.settings[:declared_params]).to eq([:some_param])
end
end
context 'requires :all using Grape::Entity documentation' do
def define_requires_all
documentation = {
- required_field: { type: String },
- optional_field: { type: String }
+ required_field: { type: String },
+ optional_field: { type: String }
}
subject.params do
requires :all, except: :optional_field, using: documentation
end
end
@@ -95,31 +95,31 @@
end
end
it 'adds entity documentation to declared params' do
define_requires_all
- subject.settings[:declared_params].should == [:required_field, :optional_field]
+ expect(subject.settings[:declared_params]).to eq([:required_field, :optional_field])
end
it 'errors when required_field is not present' do
get '/required'
- last_response.status.should == 400
- last_response.body.should == 'required_field is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('required_field is missing')
end
it 'works when required_field is present' do
get '/required', required_field: 'woof'
- last_response.status.should == 200
- last_response.body.should == 'required works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required works')
end
end
context 'requires :none using Grape::Entity documentation' do
def define_requires_none
documentation = {
- required_field: { type: String },
- optional_field: { type: String }
+ required_field: { type: String },
+ optional_field: { type: String }
}
subject.params do
requires :none, except: :required_field, using: documentation
end
end
@@ -130,26 +130,61 @@
end
end
it 'adds entity documentation to declared params' do
define_requires_none
- subject.settings[:declared_params].should == [:required_field, :optional_field]
+ expect(subject.settings[:declared_params]).to eq([:required_field, :optional_field])
end
it 'errors when required_field is not present' do
get '/required'
- last_response.status.should == 400
- last_response.body.should == 'required_field is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('required_field is missing')
end
it 'works when required_field is present' do
get '/required', required_field: 'woof'
- last_response.status.should == 200
- last_response.body.should == 'required works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required works')
end
end
+ context 'requires :all or :none but except a non-existent field using Grape::Entity documentation' do
+ context 'requires :all' do
+ def define_requires_all
+ documentation = {
+ required_field: { type: String },
+ optional_field: { type: String }
+ }
+ subject.params do
+ requires :all, except: :non_existent_field, using: documentation
+ end
+ end
+
+ it 'adds only the entity documentation to declared params, nothing more' do
+ define_requires_all
+ expect(subject.settings[:declared_params]).to eq([:required_field, :optional_field])
+ end
+ end
+
+ context 'requires :none' do
+ def define_requires_none
+ documentation = {
+ required_field: { type: String },
+ optional_field: { type: String }
+ }
+ subject.params do
+ requires :none, except: :non_existent_field, using: documentation
+ end
+ end
+
+ it 'adds only the entity documentation to declared params, nothing more' do
+ expect { define_requires_none }.to raise_error(ArgumentError)
+ end
+ end
+ end
+
context 'required with an Array block' do
before do
subject.params do
requires :items, type: Array do
requires :key
@@ -160,28 +195,28 @@
end
end
it 'errors when param not present' do
get '/required'
- last_response.status.should == 400
- last_response.body.should == 'items is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is missing')
end
it "errors when param is not an Array" do
get '/required', items: "hello"
- last_response.status.should == 400
- last_response.body.should == 'items is invalid, items[key] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid, items[key] is missing')
get '/required', items: { key: 'foo' }
- last_response.status.should == 400
- last_response.body.should == 'items is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid')
end
it "doesn't throw a missing param when param is present" do
get '/required', items: [{ key: 'hello' }, { key: 'world' }]
- last_response.status.should == 200
- last_response.body.should == 'required works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required works')
end
it "doesn't allow any key in the options hash other than type" do
expect {
subject.params do
@@ -196,11 +231,11 @@
subject.params do
requires :items do
requires :key
end
end
- subject.settings[:declared_params].should == [items: [:key]]
+ expect(subject.settings[:declared_params]).to eq([items: [:key]])
end
end
context 'required with a Hash block' do
before do
@@ -214,28 +249,28 @@
end
end
it 'errors when param not present' do
get '/required'
- last_response.status.should == 400
- last_response.body.should == 'items is missing, items[key] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is missing, items[key] is missing')
end
it "errors when param is not a Hash" do
get '/required', items: "hello"
- last_response.status.should == 400
- last_response.body.should == 'items is invalid, items[key] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid, items[key] is missing')
get '/required', items: [{ key: 'foo' }]
- last_response.status.should == 400
- last_response.body.should == 'items is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid')
end
it "doesn't throw a missing param when param is present" do
get '/required', items: { key: 'hello' }
- last_response.status.should == 200
- last_response.body.should == 'required works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required works')
end
it "doesn't allow any key in the options hash other than type" do
expect {
subject.params do
@@ -250,11 +285,11 @@
subject.params do
requires :items do
requires :key
end
end
- subject.settings[:declared_params].should == [items: [:key]]
+ expect(subject.settings[:declared_params]).to eq([items: [:key]])
end
end
context 'group' do
before do
@@ -268,27 +303,27 @@
end
end
it 'errors when param not present' do
get '/required'
- last_response.status.should == 400
- last_response.body.should == 'items is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is missing')
end
it "doesn't throw a missing param when param is present" do
get '/required', items: [key: 'hello', key: 'world']
- last_response.status.should == 200
- last_response.body.should == 'required works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required works')
end
it 'adds to declared parameters' do
subject.params do
group :items do
requires :key
end
end
- subject.settings[:declared_params].should == [items: [:key]]
+ expect(subject.settings[:declared_params]).to eq([items: [:key]])
end
end
context 'validation within arrays' do
before do
@@ -308,49 +343,49 @@
it 'can handle new scopes within child elements' do
get '/within_array', children: [
{ name: 'John', parents: [{ name: 'Jane' }, { name: 'Bob' }] },
{ name: 'Joe', parents: [{ name: 'Josie' }] }
]
- last_response.status.should == 200
- last_response.body.should == 'within array works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('within array works')
end
it 'errors when a parameter is not present' do
get '/within_array', children: [
{ name: 'Jim', parents: [{}] },
{ name: 'Job', parents: [{ name: 'Joy' }] }
]
# NOTE: with body parameters in json or XML or similar this
# should actually fail with: children[parents][name] is missing.
- last_response.status.should == 400
- last_response.body.should == 'children[parents] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children[parents] is missing')
end
it 'safely handles empty arrays and blank parameters' do
# NOTE: with body parameters in json or XML or similar this
# should actually return 200, since an empty array is valid.
get '/within_array', children: []
- last_response.status.should == 400
- last_response.body.should == 'children is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children is missing')
get '/within_array', children: [name: 'Jay']
- last_response.status.should == 400
- last_response.body.should == 'children[parents] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children[parents] is missing')
end
it "errors when param is not an Array" do
# NOTE: would be nicer if these just returned 'children is invalid'
get '/within_array', children: "hello"
- last_response.status.should == 400
- last_response.body.should == 'children is invalid, children[name] is missing, children[parents] is missing, children[parents] is invalid, children[parents][name] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children is invalid, children[name] is missing, children[parents] is missing, children[parents] is invalid, children[parents][name] is missing')
get '/within_array', children: { name: 'foo' }
- last_response.status.should == 400
- last_response.body.should == 'children is invalid, children[parents] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children is invalid, children[parents] is missing')
get '/within_array', children: [name: 'Jay', parents: { name: 'Fred' }]
- last_response.status.should == 400
- last_response.body.should == 'children[parents] is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children[parents] is invalid')
end
end
context 'with block param' do
before do
@@ -392,57 +427,57 @@
end
end
it 'requires defaults to Array type' do
get '/req', planets: "Jupiter, Saturn"
- last_response.status.should == 400
- last_response.body.should == 'planets is invalid, planets[name] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('planets is invalid, planets[name] is missing')
get '/req', planets: { name: 'Jupiter' }
- last_response.status.should == 400
- last_response.body.should == 'planets is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('planets is invalid')
get '/req', planets: [{ name: 'Venus' }, { name: 'Mars' }]
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
put_with_json '/req', planets: []
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
end
it 'optional defaults to Array type' do
get '/opt', name: "Jupiter", moons: "Europa, Ganymede"
- last_response.status.should == 400
- last_response.body.should == 'moons is invalid, moons[name] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('moons is invalid, moons[name] is missing')
get '/opt', name: "Jupiter", moons: { name: 'Ganymede' }
- last_response.status.should == 400
- last_response.body.should == 'moons is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('moons is invalid')
get '/opt', name: "Jupiter", moons: [{ name: 'Io' }, { name: 'Callisto' }]
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
put_with_json '/opt', name: "Venus"
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
put_with_json '/opt', name: "Mercury", moons: []
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
end
it 'group defaults to Array type' do
get '/grp', stars: "Sun"
- last_response.status.should == 400
- last_response.body.should == 'stars is invalid, stars[name] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('stars is invalid, stars[name] is missing')
get '/grp', stars: { name: 'Sun' }
- last_response.status.should == 400
- last_response.body.should == 'stars is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('stars is invalid')
get '/grp', stars: [{ name: 'Sun' }]
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
put_with_json '/grp', stars: []
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
end
end
context 'validation within arrays with JSON' do
before do
@@ -462,29 +497,29 @@
it 'can handle new scopes within child elements' do
put_with_json '/within_array', children: [
{ name: 'John', parents: [{ name: 'Jane' }, { name: 'Bob' }] },
{ name: 'Joe', parents: [{ name: 'Josie' }] }
]
- last_response.status.should == 200
- last_response.body.should == 'within array works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('within array works')
end
it 'errors when a parameter is not present' do
put_with_json '/within_array', children: [
{ name: 'Jim', parents: [{}] },
{ name: 'Job', parents: [{ name: 'Joy' }] }
]
- last_response.status.should == 400
- last_response.body.should == 'children[parents][name] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children[parents][name] is missing')
end
it 'safely handles empty arrays and blank parameters' do
put_with_json '/within_array', children: []
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
put_with_json '/within_array', children: [name: 'Jay']
- last_response.status.should == 400
- last_response.body.should == 'children[parents] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('children[parents] is missing')
end
end
context 'optional with an Array block' do
before do
@@ -498,43 +533,43 @@
end
end
it "doesn't throw a missing param when the group isn't present" do
get '/optional_group'
- last_response.status.should == 200
- last_response.body.should == 'optional group works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('optional group works')
end
it "doesn't throw a missing param when both group and param are given" do
get '/optional_group', items: [{ key: 'foo' }]
- last_response.status.should == 200
- last_response.body.should == 'optional group works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('optional group works')
end
it "errors when group is present, but required param is not" do
get '/optional_group', items: [{ not_key: 'foo' }]
- last_response.status.should == 400
- last_response.body.should == 'items[key] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items[key] is missing')
end
it "errors when param is present but isn't an Array" do
get '/optional_group', items: "hello"
- last_response.status.should == 400
- last_response.body.should == 'items is invalid, items[key] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid, items[key] is missing')
get '/optional_group', items: { key: 'foo' }
- last_response.status.should == 400
- last_response.body.should == 'items is invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items is invalid')
end
it 'adds to declared parameters' do
subject.params do
optional :items do
requires :key
end
end
- subject.settings[:declared_params].should == [items: [:key]]
+ expect(subject.settings[:declared_params]).to eq([items: [:key]])
end
end
context 'nested optional Array blocks' do
before do
@@ -548,57 +583,57 @@
subject.get('/nested_optional_group') { 'nested optional group works' }
end
it 'does no internal validations if the outer group is blank' do
get '/nested_optional_group'
- last_response.status.should == 200
- last_response.body.should == 'nested optional group works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('nested optional group works')
end
it 'does internal validations if the outer group is present' do
get '/nested_optional_group', items: [{ key: 'foo' }]
- last_response.status.should == 400
- last_response.body.should == 'items[required_subitems] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items[required_subitems] is missing')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }]
- last_response.status.should == 200
- last_response.body.should == 'nested optional group works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('nested optional group works')
end
it 'handles deep nesting' do
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ not_value: 'baz' }] }]
- last_response.status.should == 400
- last_response.body.should == 'items[optional_subitems][value] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items[optional_subitems][value] is missing')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ value: 'baz' }] }]
- last_response.status.should == 200
- last_response.body.should == 'nested optional group works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('nested optional group works')
end
it 'handles validation within arrays' do
get '/nested_optional_group', items: [{ key: 'foo' }]
- last_response.status.should == 400
- last_response.body.should == 'items[required_subitems] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items[required_subitems] is missing')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }] }]
- last_response.status.should == 200
- last_response.body.should == 'nested optional group works'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('nested optional group works')
get '/nested_optional_group', items: [{ key: 'foo', required_subitems: [{ value: 'bar' }], optional_subitems: [{ not_value: 'baz' }] }]
- last_response.status.should == 400
- last_response.body.should == 'items[optional_subitems][value] is missing'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('items[optional_subitems][value] is missing')
end
it 'adds to declared parameters' do
subject.params do
optional :items do
requires :key
optional(:optional_subitems) { requires :value }
requires(:required_subitems) { requires :value }
end
end
- subject.settings[:declared_params].should == [items: [:key, { optional_subitems: [:value] }, { required_subitems: [:value] }]]
+ expect(subject.settings[:declared_params]).to eq([items: [:key, { optional_subitems: [:value] }, { required_subitems: [:value] }]])
end
end
context 'multiple validation errors' do
before do
@@ -611,13 +646,13 @@
end
end
it 'throws the validation errors' do
get '/two_required'
- last_response.status.should == 400
- last_response.body.should =~ /yolo is missing/
- last_response.body.should =~ /swag is missing/
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to match(/yolo is missing/)
+ expect(last_response.body).to match(/swag is missing/)
end
end
context 'custom validation' do
module CustomValidations
@@ -640,32 +675,32 @@
end
end
it 'validates when param is present' do
get '/optional_custom', custom: 'im custom'
- last_response.status.should == 200
- last_response.body.should == 'optional with custom works!'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('optional with custom works!')
get '/optional_custom', custom: 'im wrong'
- last_response.status.should == 400
- last_response.body.should == 'custom is not custom!'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('custom is not custom!')
end
it "skips validation when parameter isn't present" do
get '/optional_custom'
- last_response.status.should == 200
- last_response.body.should == 'optional with custom works!'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('optional with custom works!')
end
it 'validates with custom validator when param present and incorrect type' do
subject.params do
optional :custom, type: String, customvalidator: true
end
get '/optional_custom', custom: 123
- last_response.status.should == 400
- last_response.body.should == 'custom is not custom!'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('custom is not custom!')
end
end
context 'when using requires with a custom validator' do
before do
@@ -677,22 +712,22 @@
end
end
it 'validates when param is present' do
get '/required_custom', custom: 'im wrong, validate me'
- last_response.status.should == 400
- last_response.body.should == 'custom is not custom!'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('custom is not custom!')
get '/required_custom', custom: 'im custom'
- last_response.status.should == 200
- last_response.body.should == 'required with custom works!'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('required with custom works!')
end
it 'validates when param is not present' do
get '/required_custom'
- last_response.status.should == 400
- last_response.body.should == 'custom is missing, custom is not custom!'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('custom is missing, custom is not custom!')
end
context 'nested namespaces' do
before do
subject.params do
@@ -735,37 +770,37 @@
end
end
specify 'the parent namespace uses the validator' do
get '/nested/one', custom: 'im wrong, validate me'
- last_response.status.should == 400
- last_response.body.should == 'custom is not custom!'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('custom is not custom!')
end
specify 'the nested namesapce inherits the custom validator' do
get '/nested/nested/two', custom: 'im wrong, validate me'
- last_response.status.should == 400
- last_response.body.should == 'custom is not custom!'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('custom is not custom!')
end
specify 'peer namesapces does not have the validator' do
get '/peer/one', custom: 'im not validated'
- last_response.status.should == 200
- last_response.body.should == 'no validation required'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('no validation required')
end
specify 'namespaces nested in peers should also not have the validator' do
get '/peer/nested/two', custom: 'im not validated'
- last_response.status.should == 200
- last_response.body.should == 'no validation required'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq('no validation required')
end
specify 'when nested, specifying a route should clear out the validations for deeper nested params' do
get '/unrelated/one'
- last_response.status.should == 400
+ expect(last_response.status).to eq(400)
get '/unrelated/double/two'
- last_response.status.should == 200
+ expect(last_response.status).to eq(200)
end
end
end
end # end custom validation
@@ -809,21 +844,62 @@
it 'by #use' do
subject.params do
use :pagination
end
- subject.settings[:declared_params].should eq [:page, :per_page]
+ expect(subject.settings[:declared_params]).to eq [:page, :per_page]
end
it 'by #use with multiple params' do
subject.params do
use :pagination, :period
end
- subject.settings[:declared_params].should eq [:page, :per_page, :start_date, :end_date]
+ expect(subject.settings[:declared_params]).to eq [:page, :per_page, :start_date, :end_date]
end
end
+
+ context 'with block' do
+ before do
+ subject.helpers do
+ params :order do |options|
+ optional :order, type: Symbol, values: [:asc, :desc], default: options[:default_order]
+ optional :order_by, type: Symbol, values: options[:order_by], default: options[:default_order_by]
+ end
+ end
+ subject.format :json
+ subject.params do
+ use :order, default_order: :asc, order_by: [:name, :created_at], default_order_by: :created_at
+ end
+ subject.get '/order' do
+ {
+ order: params[:order],
+ order_by: params[:order_by]
+ }
+ end
+ end
+ it 'returns defaults' do
+ get '/order'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq({ order: :asc, order_by: :created_at }.to_json)
+ end
+ it 'overrides default value for order' do
+ get '/order?order=desc'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq({ order: :desc, order_by: :created_at }.to_json)
+ end
+ it 'overrides default value for order_by' do
+ get '/order?order_by=name'
+ expect(last_response.status).to eq(200)
+ expect(last_response.body).to eq({ order: :asc, order_by: :name }.to_json)
+ end
+ it 'fails with invalid value' do
+ get '/order?order=invalid'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq('{"error":"order does not have a valid value"}')
+ end
+ end
end
context 'documentation' do
it 'can be included with a hash' do
documentation = { example: 'Joe' }
@@ -832,10 +908,87 @@
requires 'first_name', documentation: documentation
end
subject.get '/' do
end
- subject.routes.first.route_params['first_name'][:documentation].should eq(documentation)
+ expect(subject.routes.first.route_params['first_name'][:documentation]).to eq(documentation)
+ end
+ end
+
+ context 'mutually exclusive' do
+ context 'optional params' do
+ it 'errors when two or more are present' do
+ subject.params do
+ optional :beer
+ optional :wine
+ optional :juice
+ mutually_exclusive :beer, :wine, :juice
+ end
+ subject.get '/mutually_exclusive' do
+ 'mutually_exclusive works!'
+ end
+
+ get '/mutually_exclusive', beer: 'string', wine: 'anotherstring'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq("[:beer, :wine] are mutually exclusive")
+ end
+ end
+
+ context 'more than one set of mutually exclusive params' do
+ it 'errors for all sets' do
+ subject.params do
+ optional :beer
+ optional :wine
+ mutually_exclusive :beer, :wine
+ optional :scotch
+ optional :aquavit
+ mutually_exclusive :scotch, :aquavit
+ end
+ subject.get '/mutually_exclusive' do
+ 'mutually_exclusive works!'
+ end
+
+ get '/mutually_exclusive', beer: 'true', wine: 'true', scotch: 'true', aquavit: 'true'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to match(/\[:beer, :wine\] are mutually exclusive/)
+ expect(last_response.body).to match(/\[:scotch, :aquavit\] are mutually exclusive/)
+ end
+ end
+ end
+
+ context 'exactly one of' do
+ context 'params' do
+ it 'errors when two or more are present' do
+ subject.params do
+ optional :beer
+ optional :wine
+ optional :juice
+ exactly_one_of :beer, :wine, :juice
+ end
+ subject.get '/exactly_one_of' do
+ 'exactly_one_of works!'
+ end
+
+ get '/exactly_one_of', beer: 'string', wine: 'anotherstring'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq("[:beer, :wine] are mutually exclusive")
+ end
+
+ it 'errors when none is selected' do
+ subject.params do
+ optional :beer
+ optional :wine
+ optional :juice
+ exactly_one_of :beer, :wine, :juice
+ end
+ subject.get '/exactly_one_of' do
+ 'exactly_one_of works!'
+ end
+
+ get '/exactly_one_of'
+ expect(last_response.status).to eq(400)
+ expect(last_response.body).to eq("[:beer, :wine, :juice] - exactly one parameter must be provided")
+ end
end
end
end
end