Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* [#2656](https://github.com/ruby-grape/grape/pull/2656): Remove useless instance_variable_defined? checks - [@ericproulx](https://github.com/ericproulx).
* [#2619](https://github.com/ruby-grape/grape/pull/2619): Remove TOC from README.md and danger-toc check - [@alexanderadam](https://github.com/alexanderadam).
* [#2663](https://github.com/ruby-grape/grape/pull/2663): Refactor `ParamsScope` and `Parameters` DSL to use named kwargs - [@ericproulx](https://github.com/ericproulx).
* [#2664](https://github.com/ruby-grape/grape/pull/2664): Drop `test-prof` dependency - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

#### Fixes
Expand Down
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ group :test do
gem 'rspec', '~> 3.13'
gem 'simplecov', '~> 0.21', require: false
gem 'simplecov-lcov', '~> 0.8', require: false
gem 'test-prof', require: false
end

platforms :jruby do
Expand Down
9 changes: 0 additions & 9 deletions spec/config/spec_test_prof.rb

This file was deleted.

198 changes: 120 additions & 78 deletions spec/grape/validations/validators/all_or_none_validator_spec.rb
Original file line number Diff line number Diff line change
@@ -1,101 +1,100 @@
# frozen_string_literal: true

describe Grape::Validations::Validators::AllOrNoneOfValidator do
let_it_be(:app) do
Class.new(Grape::API) do
rescue_from Grape::Exceptions::ValidationErrors do |e|
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
end
describe '#validate!' do
subject(:validate) { post path, params }

params do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine
end
post do
end
describe '/' do
let(:app) do
Class.new(Grape::API) do
rescue_from Grape::Exceptions::ValidationErrors do |e|
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
end

params do
optional :beer, :wine, :other, type: Grape::API::Boolean
all_or_none_of :beer, :wine
end
post 'mixed-params' do
params do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine
end
post do
end
end
end

params do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine, message: 'choose all or none'
end
post '/custom-message' do
end
context 'when all restricted params are present' do
let(:path) { '/' }
let(:params) { { beer: true, wine: true } }

params do
requires :item, type: Hash do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine
it 'does not return a validation error' do
validate
expect(last_response.status).to eq 201
end
end
post '/nested-hash' do
end

params do
requires :items, type: Array do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine
context 'when a subset of restricted params are present' do
let(:path) { '/' }
let(:params) { { beer: true } }

it 'returns a validation error' do
validate
expect(last_response.status).to eq 400
expect(JSON.parse(last_response.body)).to eq(
'beer,wine' => ['provide all or none of parameters']
)
end
end
post '/nested-array' do

context 'when no restricted params are present' do
let(:path) { '/' }
let(:params) { { somethingelse: true } }

it 'does not return a validation error' do
validate
expect(last_response.status).to eq 201
end
end
end

params do
requires :items, type: Array do
requires :nested_items, type: Array do
optional :beer, :wine, type: Grape::API::Boolean
describe '/mixed-params' do
let(:app) do
Class.new(Grape::API) do
rescue_from Grape::Exceptions::ValidationErrors do |e|
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
end

params do
optional :beer, :wine, :other, type: Grape::API::Boolean
all_or_none_of :beer, :wine
end
post 'mixed-params' do
end
end
end
post '/deeply-nested-array' do
end
end
end

describe '#validate!' do
subject(:validate) { post path, params }

context 'when all restricted params are present' do
let(:path) { '/' }
let(:params) { { beer: true, wine: true } }
let(:path) { '/mixed-params' }
let(:params) { { beer: true, wine: true, other: true } }

it 'does not return a validation error' do
validate
expect(last_response.status).to eq 201
end

context 'mixed with other params' do
let(:path) { '/mixed-params' }
let(:params) { { beer: true, wine: true, other: true } }

it 'does not return a validation error' do
validate
expect(last_response.status).to eq 201
end
end
end

context 'when a subset of restricted params are present' do
let(:path) { '/' }
let(:params) { { beer: true } }
describe '/custom-message' do
let(:app) do
Class.new(Grape::API) do
rescue_from Grape::Exceptions::ValidationErrors do |e|
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
end

it 'returns a validation error' do
validate
expect(last_response.status).to eq 400
expect(JSON.parse(last_response.body)).to eq(
'beer,wine' => ['provide all or none of parameters']
)
params do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine, message: 'choose all or none'
end
post '/custom-message' do
end
end
end
end

context 'when custom message is specified' do
let(:path) { '/custom-message' }
let(:params) { { beer: true } }

Expand All @@ -108,17 +107,24 @@
end
end

context 'when no restricted params are present' do
let(:path) { '/' }
let(:params) { { somethingelse: true } }
describe '/nested-hash' do
let(:app) do
Class.new(Grape::API) do
rescue_from Grape::Exceptions::ValidationErrors do |e|
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
end

it 'does not return a validation error' do
validate
expect(last_response.status).to eq 201
params do
requires :item, type: Hash do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine
end
end
post '/nested-hash' do
end
end
end
end

context 'when restricted params are nested inside required hash' do
let(:path) { '/nested-hash' }
let(:params) { { item: { beer: true } } }

Expand All @@ -131,7 +137,24 @@
end
end

context 'when mutually exclusive params are nested inside array' do
describe '/nested-array' do
let(:app) do
Class.new(Grape::API) do
rescue_from Grape::Exceptions::ValidationErrors do |e|
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
end

params do
requires :items, type: Array do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine
end
end
post '/nested-array' do
end
end
end

let(:path) { '/nested-array' }
let(:params) { { items: [{ beer: true, wine: true }, { wine: true }] } }

Expand All @@ -144,7 +167,26 @@
end
end

context 'when mutually exclusive params are deeply nested' do
describe '/deeply-nested-array' do
let(:app) do
Class.new(Grape::API) do
rescue_from Grape::Exceptions::ValidationErrors do |e|
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
end

params do
requires :items, type: Array do
requires :nested_items, type: Array do
optional :beer, :wine, type: Grape::API::Boolean
all_or_none_of :beer, :wine
end
end
end
post '/deeply-nested-array' do
end
end
end

let(:path) { '/deeply-nested-array' }
let(:params) { { items: [{ nested_items: [{ beer: true }] }] } }

Expand Down
Loading