diff --git a/lib/graphql_devise.rb b/lib/graphql_devise.rb index 3ec8627e..0ecf0de9 100644 --- a/lib/graphql_devise.rb +++ b/lib/graphql_devise.rb @@ -23,6 +23,7 @@ class InvalidMountOptionsError < GraphqlDevise::Error; end require 'graphql_devise/user_error' require 'graphql_devise/detailed_user_error' +require 'graphql_devise/mount_method/option_sanitizer' require 'graphql_devise/mount_method/options_validator' require 'graphql_devise/mount_method/queries_preparer' require 'graphql_devise/mount_method/mutations_preparer' diff --git a/lib/graphql_devise/mount_method/option_sanitizer.rb b/lib/graphql_devise/mount_method/option_sanitizer.rb new file mode 100644 index 00000000..7fbdbc29 --- /dev/null +++ b/lib/graphql_devise/mount_method/option_sanitizer.rb @@ -0,0 +1,18 @@ +require_relative 'supported_options' + +module GraphqlDevise + module MountMethod + class OptionSanitizer + def initialize(options = {}, supported_options = MountMethod::SUPPORTED_OPTIONS) + @options = options + @supported_options = supported_options + end + + def call! + @supported_options.each_with_object(Struct.new(*@supported_options.keys).new) do |(key, checker), result| + result[key] = checker.call!(@options[key], key) + end + end + end + end +end diff --git a/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb b/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb new file mode 100644 index 00000000..22355c66 --- /dev/null +++ b/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb @@ -0,0 +1,26 @@ +module GraphqlDevise + module MountMethod + module OptionSanitizers + class ArrayChecker + def initialize(element_type) + @element_type = element_type + @default_value = [] + end + + def call!(value, key) + return @default_value if value.blank? + + unless value.instance_of?(Array) + raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Array expected." + end + + unless value.all? { |element| element.instance_of?(@element_type) } + raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has invalid elements. #{@element_type} expected." + end + + value + end + end + end + end +end diff --git a/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb b/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb new file mode 100644 index 00000000..6cc8802e --- /dev/null +++ b/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb @@ -0,0 +1,26 @@ +module GraphqlDevise + module MountMethod + module OptionSanitizers + class ClassChecker + def initialize(klass) + @klass_array = Array(klass) + end + + def call!(value, key) + return if value.nil? + + unless value.instance_of?(Class) + raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Class expected." + end + + unless @klass_array.any? { |klass| value.ancestors.include?(klass) } + raise GraphqlDevise::InvalidMountOptionsError, + "`#{key}` option has an invalid value. #{@klass_array.join(', ')} or descendants expected. Got #{value}." + end + + value + end + end + end + end +end diff --git a/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb b/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb new file mode 100644 index 00000000..5d298932 --- /dev/null +++ b/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb @@ -0,0 +1,24 @@ +module GraphqlDevise + module MountMethod + module OptionSanitizers + class HashChecker + def initialize(element_type_array) + @element_type_array = Array(element_type_array) + @default_value = {} + end + + def call!(value, key) + return @default_value if value.blank? + + unless value.instance_of?(Hash) + raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Hash expected. Got #{value.class}." + end + + value.each { |internal_key, klass| ClassChecker.new(@element_type_array).call!(klass, "#{key} -> #{internal_key}") } + + value + end + end + end + end +end diff --git a/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb b/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb new file mode 100644 index 00000000..0934a282 --- /dev/null +++ b/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb @@ -0,0 +1,21 @@ +module GraphqlDevise + module MountMethod + module OptionSanitizers + class StringChecker + def initialize(default_string = nil) + @default_string = default_string + end + + def call!(value, key) + return @default_string if value.blank? + + unless value.instance_of?(String) + raise GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. String expected." + end + + value + end + end + end + end +end diff --git a/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb b/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb index f5ed7a17..33409796 100644 --- a/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb +++ b/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb @@ -4,40 +4,20 @@ module GraphqlDevise module MountMethod module OptionValidators class ProvidedOperationsValidator - def initialize(options: {}, supported_operations: {}) - @options = options || {} + def initialize(options:, supported_operations:) + @options = options @supported_operations = supported_operations end def validate! - skipped = @options.fetch(:skip, []) - only = @options.fetch(:only, []) - operations = @options.fetch(:operations, {}) supported_keys = @supported_operations.keys - raise_on_invalid_option_type!(:skip, skipped, Array) - raise_on_invalid_option_type!(:only, only, Array) - raise_on_invalid_option_type!(:operations, operations, Hash) - - custom = operations.keys - [ - SupportedOperationsValidator.new(provided_operations: skipped, key: :skip, supported_operations: supported_keys), - SupportedOperationsValidator.new(provided_operations: only, key: :only, supported_operations: supported_keys), - SupportedOperationsValidator.new(provided_operations: custom, key: :operations, supported_operations: supported_keys) + SupportedOperationsValidator.new(provided_operations: @options.skip, key: :skip, supported_operations: supported_keys), + SupportedOperationsValidator.new(provided_operations: @options.only, key: :only, supported_operations: supported_keys), + SupportedOperationsValidator.new(provided_operations: @options.operations.keys, key: :operations, supported_operations: supported_keys) ].each(&:validate!) end - - private - - def raise_on_invalid_option_type!(key, value, expected_class) - unless value.is_a?(expected_class) - raise( - GraphqlDevise::InvalidMountOptionsError, - "#{key} option contains value of invalid value. Value must be #{expected_class.name}." - ) - end - end end end end diff --git a/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb b/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb index d14ea306..efb559e5 100644 --- a/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb +++ b/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb @@ -2,12 +2,12 @@ module GraphqlDevise module MountMethod module OptionValidators class SkipOnlyValidator - def initialize(options: {}) - @options = options || {} + def initialize(options:) + @options = options end def validate! - if [@options[:skip], @options[:only]].all?(&:present?) + if [@options.skip, @options.only].all?(&:present?) raise( GraphqlDevise::InvalidMountOptionsError, "Can't specify both `skip` and `only` options when mounting the route." diff --git a/lib/graphql_devise/mount_method/supported_options.rb b/lib/graphql_devise/mount_method/supported_options.rb new file mode 100644 index 00000000..9c2641d8 --- /dev/null +++ b/lib/graphql_devise/mount_method/supported_options.rb @@ -0,0 +1,18 @@ +require_relative 'option_sanitizers/array_checker' +require_relative 'option_sanitizers/hash_checker' +require_relative 'option_sanitizers/string_checker' +require_relative 'option_sanitizers/class_checker' + +module GraphqlDevise + module MountMethod + SUPPORTED_OPTIONS = { + at: OptionSanitizers::StringChecker.new('/graphql_auth'), + operations: OptionSanitizers::HashChecker.new([GraphQL::Schema::Resolver, GraphQL::Schema::Mutation]), + only: OptionSanitizers::ArrayChecker.new(Symbol), + skip: OptionSanitizers::ArrayChecker.new(Symbol), + additional_queries: OptionSanitizers::HashChecker.new(GraphQL::Schema::Resolver), + additional_mutations: OptionSanitizers::HashChecker.new(GraphQL::Schema::Mutation), + authenticatable_type: OptionSanitizers::ClassChecker.new(GraphQL::Schema::Member) + }.freeze + end +end diff --git a/lib/graphql_devise/rails/routes.rb b/lib/graphql_devise/rails/routes.rb index 75f336ba..e4dccf8b 100644 --- a/lib/graphql_devise/rails/routes.rb +++ b/lib/graphql_devise/rails/routes.rb @@ -12,31 +12,25 @@ class Mapper def mount_graphql_devise_for(resource, options = {}) default_operations = GraphqlDevise::DefaultOperations::MUTATIONS.merge(GraphqlDevise::DefaultOperations::QUERIES) + clean_options = GraphqlDevise::MountMethod::OptionSanitizer.new(options).call! GraphqlDevise::MountMethod::OptionsValidator.new( [ - GraphqlDevise::MountMethod::OptionValidators::SkipOnlyValidator.new(options: options), + GraphqlDevise::MountMethod::OptionValidators::SkipOnlyValidator.new(options: clean_options), GraphqlDevise::MountMethod::OptionValidators::ProvidedOperationsValidator.new( - options: options, supported_operations: default_operations + options: clean_options, supported_operations: default_operations ) ] ).validate! - custom_operations = options.fetch(:operations, {}) - skipped_operations = options.fetch(:skip, []) - only_operations = options.fetch(:only, []) - additional_mutations = options.fetch(:additional_mutations, {}) - additional_queries = options.fetch(:additional_queries, {}) - path = options.fetch(:at, '/graphql_auth') - mapping_name = resource.underscore.tr('/', '_').to_sym - authenticatable_type = options[:authenticatable_type].presence || + authenticatable_type = clean_options.authenticatable_type.presence || "Types::#{resource}Type".safe_constantize || GraphqlDevise::Types::AuthenticatableType param_operations = { - custom: custom_operations, - only: only_operations, - skipped: skipped_operations + custom: clean_options.operations, + only: clean_options.only, + skipped: clean_options.skip } devise_for( @@ -62,28 +56,30 @@ def mount_graphql_devise_for(resource, options = {}) authenticatable_type: authenticatable_type ) - prepared_mutations.merge(additional_mutations).each do |action, mutation| + all_mutations = prepared_mutations.merge(clean_options.additional_mutations) + all_mutations.each do |action, mutation| GraphqlDevise::Types::MutationType.field(action, mutation: mutation) end - if (prepared_mutations.present? || additional_mutations.present?) && + if all_mutations.present? && (Gem::Version.new(GraphQL::VERSION) < Gem::Version.new('1.10.0') || GraphqlDevise::Schema.mutation.nil?) GraphqlDevise::Schema.mutation(GraphqlDevise::Types::MutationType) end - prepared_queries.merge(additional_queries).each do |action, resolver| + all_queries = prepared_queries.merge(clean_options.additional_queries) + all_queries.each do |action, resolver| GraphqlDevise::Types::QueryType.field(action, resolver: resolver) end - if (prepared_queries.blank? || additional_queries.present?) && GraphqlDevise::Types::QueryType.fields.blank? + if all_queries.present? && GraphqlDevise::Types::QueryType.fields.blank? GraphqlDevise::Types::QueryType.field(:dummy, resolver: GraphqlDevise::Resolvers::Dummy) end Devise.mailer.helper(GraphqlDevise::MailerHelper) - devise_scope mapping_name do - post path, to: 'graphql_devise/graphql#auth' - get path, to: 'graphql_devise/graphql#auth' + devise_scope resource.underscore.tr('/', '_').to_sym do + post clean_options.at, to: 'graphql_devise/graphql#auth' + get clean_options.at, to: 'graphql_devise/graphql#auth' end end end diff --git a/spec/services/mount_method/mutations_preparer_spec.rb b/spec/services/mount_method/mutations_preparer_spec.rb index a2c9e3e7..02c53df9 100644 --- a/spec/services/mount_method/mutations_preparer_spec.rb +++ b/spec/services/mount_method/mutations_preparer_spec.rb @@ -14,13 +14,13 @@ let(:class1) { Class.new(GraphQL::Schema::Mutation) } let(:class2) { GraphQL::Schema::Mutation } let(:auth_type) { GraphqlDevise::Types::AuthenticatableType } - let(:mutations) { { mutation_1: class1, mutation_2: class2 } } + let(:mutations) { { mutation1: class1, mutation2: class2 } } context 'when mutations is *NOT* empty' do it 'assign gql attibutes to mutations and changes keys using resource map' do result = subject - expect(result.keys).to contain_exactly(:user_mutation_1, :user_mutation_2) + expect(result.keys).to contain_exactly(:user_mutation1, :user_mutation2) expect(result.values.map(&:graphql_name)).to contain_exactly( 'UserMutation1', 'UserMutation2' ) diff --git a/spec/services/mount_method/option_sanitizer_spec.rb b/spec/services/mount_method/option_sanitizer_spec.rb new file mode 100644 index 00000000..6d67fcc9 --- /dev/null +++ b/spec/services/mount_method/option_sanitizer_spec.rb @@ -0,0 +1,85 @@ +require 'spec_helper' + +RSpec.describe GraphqlDevise::MountMethod::OptionSanitizer do + subject(:clean_options) { described_class.new(options, supported_options).call! } + + describe '#call!' do + let(:supported_options) do + { + my_string: GraphqlDevise::MountMethod::OptionSanitizers::StringChecker.new('default string'), + hash_multiple: GraphqlDevise::MountMethod::OptionSanitizers::HashChecker.new([String, Numeric]), + array: GraphqlDevise::MountMethod::OptionSanitizers::ArrayChecker.new(Symbol), + hash_single: GraphqlDevise::MountMethod::OptionSanitizers::HashChecker.new(Float), + my_class: GraphqlDevise::MountMethod::OptionSanitizers::ClassChecker.new(Numeric) + } + end + + context 'when all options are provided and correct' do + let(:options) do + { + my_string: 'non default', + hash_multiple: { first: String, second: Float, third: Float }, + array: [:one, :two, :three], + hash_single: { first: Float, second: Float }, + my_class: Float + } + end + + it 'returns a struct with clean options' do + expect( + my_string: clean_options.my_string, + hash_multiple: clean_options.hash_multiple, + array: clean_options.array, + hash_single: clean_options.hash_single, + my_class: clean_options.my_class + ).to match( + my_string: 'non default', + hash_multiple: { first: String, second: Float, third: Float }, + array: [:one, :two, :three], + hash_single: { first: Float, second: Float }, + my_class: Float + ) + end + end + + context 'when some options are provided but all correct' do + let(:options) do + { + hash_multiple: { first: String, second: Float, third: Float }, + array: [:one, :two, :three], + my_class: Float + } + end + + it 'returns a struct with clean options and default values' do + expect( + my_string: clean_options.my_string, + hash_multiple: clean_options.hash_multiple, + array: clean_options.array, + hash_single: clean_options.hash_single, + my_class: clean_options.my_class + ).to match( + my_string: 'default string', + hash_multiple: { first: String, second: Float, third: Float }, + array: [:one, :two, :three], + hash_single: {}, + my_class: Float + ) + end + end + + context 'when an option provided is invalid' do + let(:options) do + { + hash_multiple: { first: String, second: Float, third: Float }, + array: ['not symbol 1', 'not symbol 2'], + my_class: Float + } + end + + it 'raises an error' do + expect { clean_options }.to raise_error(GraphqlDevise::InvalidMountOptionsError, '`array` option has invalid elements. Symbol expected.') + end + end + end +end diff --git a/spec/services/mount_method/option_sanitizers/array_checker_spec.rb b/spec/services/mount_method/option_sanitizers/array_checker_spec.rb new file mode 100644 index 00000000..2096ac8b --- /dev/null +++ b/spec/services/mount_method/option_sanitizers/array_checker_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::ArrayChecker do + describe '#call!' do + subject(:clean_value) { described_class.new(element_type).call!(value, key) } + + let(:key) { :any_option } + let(:element_type) { Symbol } + + context 'when no value is provided' do + let(:value) { nil } + + it { is_expected.to eq([]) } + end + + context 'when provided value is not an array' do + let(:value) { 'not an array' } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Array expected.") + end + end + + context 'when provided array contains invalid elements' do + let(:value) { [:valid, 'invalid'] } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has invalid elements. #{element_type} expected.") + end + end + + context 'when provided array contains all valid elements' do + let(:value) { [:valid1, :valid2] } + + it { is_expected.to eq(value) } + end + end +end diff --git a/spec/services/mount_method/option_sanitizers/class_checker_spec.rb b/spec/services/mount_method/option_sanitizers/class_checker_spec.rb new file mode 100644 index 00000000..5ae9e07b --- /dev/null +++ b/spec/services/mount_method/option_sanitizers/class_checker_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::ClassChecker do + describe '#call!' do + subject(:clean_value) { described_class.new(expected_class).call!(value, key) } + + let(:key) { :any_option } + let(:expected_class) { Numeric } + + context 'when no value is provided' do + let(:value) { nil } + + it { is_expected.to eq(nil) } + end + + context 'when provided value is not a class' do + let(:value) { 'I\'m not a class' } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Class expected.") + end + end + + context 'when provided class is not of the expected type' do + let(:value) { String } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. #{expected_class} or descendants expected. Got String.") + end + end + + context 'when provided class is of the expected type' do + let(:value) { Numeric } + + it { is_expected.to eq(value) } + end + + context 'when provided class has the expected type as an acestor' do + let(:value) { Float } + + it { is_expected.to eq(value) } + end + end +end diff --git a/spec/services/mount_method/option_sanitizers/hash_checker_spec.rb b/spec/services/mount_method/option_sanitizers/hash_checker_spec.rb new file mode 100644 index 00000000..e0f24501 --- /dev/null +++ b/spec/services/mount_method/option_sanitizers/hash_checker_spec.rb @@ -0,0 +1,85 @@ +require 'spec_helper' + +RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::HashChecker do + describe '#call!' do + subject(:clean_value) { described_class.new(element_type).call!(value, key) } + + let(:key) { :any_option } + + context 'when a single valid type is provided' do + let(:element_type) { Numeric } + + context 'when no value is provided' do + let(:value) { nil } + + it { is_expected.to eq({}) } + end + + context 'when provided value is not a hash' do + let(:value) { 'not a hash' } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Hash expected. Got String.") + end + end + + context 'when provided hash contains invalid elements' do + let(:value) { { valid: Float, invalid: String } } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key} -> invalid` option has an invalid value. #{element_type} or descendants expected. Got #{String}.") + end + end + + context 'when provided array contains all valid elements' do + let(:value) { { valid1: Numeric, valid2: Numeric } } + + it { is_expected.to eq(value) } + end + + context 'when provided class has the expected type as an acestor' do + let(:value) { { valid: Float } } + + it { is_expected.to eq(value) } + end + end + + context 'when multiple value types are allowed' do + let(:element_type) { [String, Numeric] } + + context 'when no value is provided' do + let(:value) { nil } + + it { is_expected.to eq({}) } + end + + context 'when provided array contains all valid elements' do + let(:value) { { valid1: String, valid2: Numeric } } + + it { is_expected.to eq(value) } + end + + context 'when provided class has the expected type as an acestor' do + let(:value) { { valid: Float } } + + it { is_expected.to eq(value) } + end + + context 'when provided value is not a hash' do + let(:value) { 'not a hash' } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Hash expected. Got String.") + end + end + + context 'when provided hash contains invalid elements' do + let(:value) { { valid: String, invalid: StandardError } } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key} -> invalid` option has an invalid value. #{element_type.join(', ')} or descendants expected. Got #{StandardError}.") + end + end + end + end +end diff --git a/spec/services/mount_method/option_sanitizers/string_checker_spec.rb b/spec/services/mount_method/option_sanitizers/string_checker_spec.rb new file mode 100644 index 00000000..09869eac --- /dev/null +++ b/spec/services/mount_method/option_sanitizers/string_checker_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::StringChecker do + describe '#call!' do + subject(:clean_value) { described_class.new(default_string).call!(value, key) } + + let(:key) { :any_option } + let(:default_string) { 'default string' } + + context 'when no value is provided' do + let(:value) { nil } + + it { is_expected.to eq(default_string) } + end + + context 'when provided value is not a String' do + let(:value) { 1000 } + + it 'raises an error' do + expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. String expected.") + end + end + + context 'when provided array contains all valid elements' do + let(:value) { 'custom valid string' } + + it { is_expected.to eq(value) } + end + end +end diff --git a/spec/services/mount_method/option_validators/provided_operations_validator_spec.rb b/spec/services/mount_method/option_validators/provided_operations_validator_spec.rb index 35de00d0..304f0a2a 100644 --- a/spec/services/mount_method/option_validators/provided_operations_validator_spec.rb +++ b/spec/services/mount_method/option_validators/provided_operations_validator_spec.rb @@ -7,7 +7,7 @@ let(:supported_operations) { { operation1: 'irrelevant', operation2: 'irrelevant', operation3: 'irrelevant' } } context 'when skip option is provided' do - let(:provided_operations) { { skip: skipped } } + let(:provided_operations) { double(:clean_options, only: [], skip: skipped, operations: {}) } context 'when all skipped are supported' do let(:skipped) { [:operation2, :operation3] } @@ -20,16 +20,10 @@ it { is_expected.to raise_error(GraphqlDevise::InvalidMountOptionsError, 'skip option contains unsupported operations: "invalid". Check for typos.') } end - - context 'when provided skip value is not an array' do - let(:skipped) { 'Invalid value' } - - it { is_expected.to raise_error(GraphqlDevise::InvalidMountOptionsError, 'skip option contains value of invalid value. Value must be Array.') } - end end context 'when only option is provided' do - let(:provided_operations) { { only: only } } + let(:provided_operations) { double(:clean_options, skip: [], only: only, operations: {}) } context 'when all only are supported' do let(:only) { [:operation2, :operation3] } @@ -42,16 +36,10 @@ it { is_expected.to raise_error(GraphqlDevise::InvalidMountOptionsError, 'only option contains unsupported operations: "invalid". Check for typos.') } end - - context 'when provided only value is not an array' do - let(:only) { 'Invalid value' } - - it { is_expected.to raise_error(GraphqlDevise::InvalidMountOptionsError, 'only option contains value of invalid value. Value must be Array.') } - end end context 'when operations option is provided' do - let(:provided_operations) { { operations: operations } } + let(:provided_operations) { double(:clean_options, only: [], skip: [], operations: operations) } context 'when all operations are supported' do let(:operations) { { operation2: 'irrelevant', operation3: 'irrelevant' } } @@ -64,12 +52,6 @@ it { is_expected.to raise_error(GraphqlDevise::InvalidMountOptionsError, 'operations option contains unsupported operations: "invalid". Check for typos.') } end - - context 'when provided operations value is not a hash' do - let(:operations) { [:one, :two, :three] } - - it { is_expected.to raise_error(GraphqlDevise::InvalidMountOptionsError, 'operations option contains value of invalid value. Value must be Hash.') } - end end end end diff --git a/spec/services/mount_method/option_validators/skip_only_validator_spec.rb b/spec/services/mount_method/option_validators/skip_only_validator_spec.rb index 7d03f124..ba7b4842 100644 --- a/spec/services/mount_method/option_validators/skip_only_validator_spec.rb +++ b/spec/services/mount_method/option_validators/skip_only_validator_spec.rb @@ -5,25 +5,25 @@ subject { -> { described_class.new(options: options).validate! } } context 'when only `only` key is set' do - let(:options) { { only: 'Irrelevant value' } } + let(:options) { double(:clean_options, only: [:irrelevant], skip: []) } it { is_expected.not_to raise_error } end context 'when only `skip` key is set' do - let(:options) { { skip: 'Irrelevant value' } } + let(:options) { double(:clean_options, skip: [:irrelevant], only: []) } it { is_expected.not_to raise_error } end context 'when `skip` and `only` keys are set' do - let(:options) { { only: 'Irrelevant value', skip: 'irrelevant for specs' } } + let(:options) { double(:clean_options, only: [:irrelevant], skip: [:irrelevant]) } it { is_expected.to raise_error(GraphqlDevise::InvalidMountOptionsError, "Can't specify both `skip` and `only` options when mounting the route.") } end context 'when neither `skip` nor `only are set`' do - let(:options) { { irrelevant_option: 'Irrelevant value', another_option: 'irrelevant for specs' } } + let(:options) { double(:clean_options, skip: [], only: []) } it { is_expected.not_to raise_error } end