graphql_devise 0.10.1 → 0.11.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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/Appraisals +8 -0
  4. data/CHANGELOG.md +17 -0
  5. data/graphql_devise.gemspec +3 -3
  6. data/lib/graphql_devise.rb +20 -4
  7. data/lib/graphql_devise/default_operations/mutations.rb +20 -0
  8. data/lib/graphql_devise/default_operations/resolvers.rb +12 -0
  9. data/lib/graphql_devise/mount_method/operation_preparer.rb +41 -0
  10. data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +24 -0
  11. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +32 -0
  12. data/lib/graphql_devise/mount_method/operation_preparers/gql_name_setter.rb +23 -0
  13. data/lib/graphql_devise/mount_method/operation_preparers/mutation_field_setter.rb +17 -0
  14. data/lib/graphql_devise/mount_method/operation_preparers/resolver_type_setter.rb +17 -0
  15. data/lib/graphql_devise/mount_method/operation_preparers/resource_name_setter.rb +17 -0
  16. data/lib/graphql_devise/mount_method/operation_sanitizer.rb +29 -0
  17. data/lib/graphql_devise/mount_method/option_sanitizer.rb +18 -0
  18. data/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb +26 -0
  19. data/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb +26 -0
  20. data/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb +24 -0
  21. data/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb +21 -0
  22. data/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb +24 -0
  23. data/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb +20 -0
  24. data/lib/graphql_devise/mount_method/option_validators/supported_operations_validator.rb +24 -0
  25. data/lib/graphql_devise/mount_method/options_validator.rb +16 -0
  26. data/lib/graphql_devise/mount_method/supported_options.rb +18 -0
  27. data/{app/graphql → lib}/graphql_devise/mutations/base.rb +0 -0
  28. data/{app/graphql → lib}/graphql_devise/mutations/login.rb +0 -0
  29. data/{app/graphql → lib}/graphql_devise/mutations/logout.rb +0 -0
  30. data/{app/graphql → lib}/graphql_devise/mutations/resend_confirmation.rb +0 -0
  31. data/{app/graphql → lib}/graphql_devise/mutations/send_password_reset.rb +0 -0
  32. data/{app/graphql → lib}/graphql_devise/mutations/sign_up.rb +0 -0
  33. data/{app/graphql → lib}/graphql_devise/mutations/update_password.rb +0 -0
  34. data/lib/graphql_devise/rails/routes.rb +57 -85
  35. data/{app/graphql → lib}/graphql_devise/resolvers/base.rb +0 -0
  36. data/{app/graphql → lib}/graphql_devise/resolvers/check_password_token.rb +0 -0
  37. data/{app/graphql → lib}/graphql_devise/resolvers/confirm_account.rb +0 -0
  38. data/{app/graphql → lib}/graphql_devise/resolvers/dummy.rb +0 -0
  39. data/{app/graphql → lib}/graphql_devise/types/authenticatable_type.rb +0 -0
  40. data/{app/graphql → lib}/graphql_devise/types/credential_type.rb +0 -0
  41. data/{app/graphql → lib}/graphql_devise/types/mutation_type.rb +0 -0
  42. data/{app/graphql → lib}/graphql_devise/types/query_type.rb +0 -0
  43. data/lib/graphql_devise/version.rb +1 -1
  44. data/spec/services/mount_method/operation_preparer_spec.rb +30 -0
  45. data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +43 -0
  46. data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +60 -0
  47. data/spec/services/mount_method/operation_preparers/gql_name_setter_spec.rb +16 -0
  48. data/spec/services/mount_method/operation_preparers/mutation_field_setter_spec.rb +16 -0
  49. data/spec/services/mount_method/operation_preparers/resolver_type_setter_spec.rb +16 -0
  50. data/spec/services/mount_method/operation_preparers/resource_name_setter_spec.rb +14 -0
  51. data/spec/services/mount_method/operation_sanitizer_spec.rb +33 -0
  52. data/spec/services/mount_method/option_sanitizer_spec.rb +85 -0
  53. data/spec/services/mount_method/option_sanitizers/array_checker_spec.rb +38 -0
  54. data/spec/services/mount_method/option_sanitizers/class_checker_spec.rb +44 -0
  55. data/spec/services/mount_method/option_sanitizers/hash_checker_spec.rb +85 -0
  56. data/spec/services/mount_method/option_sanitizers/string_checker_spec.rb +30 -0
  57. data/spec/services/mount_method/option_validators/provided_operations_validator_spec.rb +57 -0
  58. data/spec/services/mount_method/option_validators/skip_only_validator_spec.rb +31 -0
  59. data/spec/services/mount_method/option_validators/supported_operations_validator_spec.rb +35 -0
  60. data/spec/services/mount_method/options_validator_spec.rb +36 -0
  61. metadata +79 -39
  62. data/gemfiles/.bundle/config +0 -2
  63. data/gemfiles/rails4.2_graphql1.8.gemfile +0 -10
  64. data/gemfiles/rails5.0_graphql1.8.gemfile +0 -11
  65. data/gemfiles/rails5.0_graphql1.9.gemfile +0 -9
  66. data/gemfiles/rails5.1_graphql1.8.gemfile +0 -11
  67. data/gemfiles/rails5.1_graphql1.9.gemfile +0 -9
  68. data/gemfiles/rails5.2_graphql1.10.gemfile +0 -9
  69. data/gemfiles/rails5.2_graphql1.8.gemfile +0 -11
  70. data/gemfiles/rails5.2_graphql1.9.gemfile +0 -9
  71. data/gemfiles/rails6.0_graphql1.10.gemfile +0 -10
  72. data/gemfiles/rails6.0_graphql1.8.gemfile +0 -10
  73. data/gemfiles/rails6.0_graphql1.9.gemfile +0 -10
  74. data/gemfiles/rails6.0_graphql_edge.gemfile +0 -11
  75. data/gemfiles/rails_edge_graphql_edge.gemfile +0 -11
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::DefaultOperationPreparer do
4
+ describe '#call' do
5
+ subject(:prepared) { default_preparer.call }
6
+
7
+ let(:default_preparer) { described_class.new(selected_operations: operations, custom_keys: custom_keys, mapping_name: mapping_name, preparer: preparer) }
8
+ let(:confirm_operation) { double(:confirm_operation, graphql_name: nil) }
9
+ let(:sign_up_operation) { double(:sign_up_operation, graphql_name: nil) }
10
+ let(:login_operation) { double(:confirm_operation, graphql_name: nil) }
11
+ let(:logout_operation) { double(:sign_up_operation, graphql_name: nil) }
12
+ let(:mapping_name) { 'user' }
13
+ let(:preparer) { double(:preparer) }
14
+ let(:operations) { { login: login_operation, logout: logout_operation, sign_up: sign_up_operation, confirm: confirm_operation } }
15
+ let(:custom_keys) { [:login, :logout] }
16
+
17
+ before do
18
+ allow(default_preparer).to receive(:child_class).with(confirm_operation).and_return(confirm_operation)
19
+ allow(default_preparer).to receive(:child_class).with(sign_up_operation).and_return(sign_up_operation)
20
+ allow(default_preparer).to receive(:child_class).with(login_operation).and_return(login_operation)
21
+ allow(default_preparer).to receive(:child_class).with(logout_operation).and_return(logout_operation)
22
+ allow(preparer).to receive(:call).with(confirm_operation).and_return(confirm_operation)
23
+ allow(preparer).to receive(:call).with(sign_up_operation).and_return(sign_up_operation)
24
+ allow(preparer).to receive(:call).with(login_operation).and_return(login_operation)
25
+ allow(preparer).to receive(:call).with(logout_operation).and_return(logout_operation)
26
+ end
27
+
28
+ it 'returns only those operations with no custom operation provided' do
29
+ expect(prepared.keys).to contain_exactly(:user_sign_up, :user_confirm)
30
+ end
31
+
32
+ it 'prepares default operations' do
33
+ expect(confirm_operation).to receive(:graphql_name).with('UserConfirm')
34
+ expect(sign_up_operation).to receive(:graphql_name).with('UserSignUp')
35
+ expect(preparer).to receive(:call).with(confirm_operation)
36
+ expect(preparer).to receive(:call).with(sign_up_operation)
37
+
38
+ prepared
39
+
40
+ expect(confirm_operation.instance_variable_get(:@resource_name)).to eq(:user)
41
+ expect(sign_up_operation.instance_variable_get(:@resource_name)).to eq(:user)
42
+ end
43
+
44
+ context 'when no custom keys are provided' do
45
+ let(:custom_keys) { [] }
46
+
47
+ it 'returns all selected operations' do
48
+ expect(prepared.keys).to contain_exactly(:user_sign_up, :user_confirm, :user_login, :user_logout)
49
+ end
50
+ end
51
+
52
+ context 'when no selected operations are provided' do
53
+ let(:operations) { {} }
54
+
55
+ it 'returns all selected operations' do
56
+ expect(prepared.keys).to eq([])
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::GqlNameSetter do
4
+ describe '#call' do
5
+ subject(:prepared_operation) { described_class.new(mapping_name).call(operation) }
6
+
7
+ let(:operation) { double(:operation) }
8
+ let(:mapping_name) { 'user_login' }
9
+
10
+ it 'sets a gql name to the operation' do
11
+ expect(operation).to receive(:graphql_name).with('UserLogin')
12
+
13
+ prepared_operation
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::MutationFieldSetter do
4
+ describe '#call' do
5
+ subject(:prepared_operation) { described_class.new(field_type).call(operation) }
6
+
7
+ let(:operation) { double(:operation) }
8
+ let(:field_type) { double(:type) }
9
+
10
+ it 'sets a field for the mutation' do
11
+ expect(operation).to receive(:field).with(:authenticatable, field_type, null: false)
12
+
13
+ prepared_operation
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::ResolverTypeSetter do
4
+ describe '#call' do
5
+ subject(:prepared_operation) { described_class.new(field_type).call(operation) }
6
+
7
+ let(:operation) { double(:operation) }
8
+ let(:field_type) { double(:type) }
9
+
10
+ it 'sets a field for the mutation' do
11
+ expect(operation).to receive(:type).with(field_type, null: false)
12
+
13
+ prepared_operation
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OperationPreparers::ResourceNameSetter do
4
+ describe '#call' do
5
+ subject(:prepared_operation) { described_class.new(mapping_name).call(operation) }
6
+
7
+ let(:operation) { double(:operation) }
8
+ let(:mapping_name) { 'user' }
9
+
10
+ it 'sets a gql name to the operation' do
11
+ expect(prepared_operation.instance_variable_get(:@resource_name)).to eq(:user)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ require 'rails_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OperationSanitizer do
4
+ describe '.call' do
5
+ subject { described_class.call(default: default, only: only, skipped: skipped) }
6
+
7
+ let(:op_class1) { Class.new }
8
+ let(:op_class2) { Class.new }
9
+ let(:op_class3) { Class.new }
10
+
11
+ context 'when the operations passed are mutations' do
12
+ let(:skipped) { [] }
13
+ let(:only) { [] }
14
+ let(:default) { { operation1: op_class1, operation2: op_class2 } }
15
+
16
+ context 'when no other option besides default is passed' do
17
+ it { is_expected.to eq(default) }
18
+ end
19
+
20
+ context 'when there are only operations' do
21
+ let(:only) { [:operation1] }
22
+
23
+ it { is_expected.to eq(operation1: op_class1) }
24
+ end
25
+
26
+ context 'when there are skipped operations' do
27
+ let(:skipped) { [:operation2] }
28
+
29
+ it { is_expected.to eq(operation1: op_class1) }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OptionSanitizer do
4
+ subject(:clean_options) { described_class.new(options, supported_options).call! }
5
+
6
+ describe '#call!' do
7
+ let(:supported_options) do
8
+ {
9
+ my_string: GraphqlDevise::MountMethod::OptionSanitizers::StringChecker.new('default string'),
10
+ hash_multiple: GraphqlDevise::MountMethod::OptionSanitizers::HashChecker.new([String, Numeric]),
11
+ array: GraphqlDevise::MountMethod::OptionSanitizers::ArrayChecker.new(Symbol),
12
+ hash_single: GraphqlDevise::MountMethod::OptionSanitizers::HashChecker.new(Float),
13
+ my_class: GraphqlDevise::MountMethod::OptionSanitizers::ClassChecker.new(Numeric)
14
+ }
15
+ end
16
+
17
+ context 'when all options are provided and correct' do
18
+ let(:options) do
19
+ {
20
+ my_string: 'non default',
21
+ hash_multiple: { first: String, second: Float, third: Float },
22
+ array: [:one, :two, :three],
23
+ hash_single: { first: Float, second: Float },
24
+ my_class: Float
25
+ }
26
+ end
27
+
28
+ it 'returns a struct with clean options' do
29
+ expect(
30
+ my_string: clean_options.my_string,
31
+ hash_multiple: clean_options.hash_multiple,
32
+ array: clean_options.array,
33
+ hash_single: clean_options.hash_single,
34
+ my_class: clean_options.my_class
35
+ ).to match(
36
+ my_string: 'non default',
37
+ hash_multiple: { first: String, second: Float, third: Float },
38
+ array: [:one, :two, :three],
39
+ hash_single: { first: Float, second: Float },
40
+ my_class: Float
41
+ )
42
+ end
43
+ end
44
+
45
+ context 'when some options are provided but all correct' do
46
+ let(:options) do
47
+ {
48
+ hash_multiple: { first: String, second: Float, third: Float },
49
+ array: [:one, :two, :three],
50
+ my_class: Float
51
+ }
52
+ end
53
+
54
+ it 'returns a struct with clean options and default values' do
55
+ expect(
56
+ my_string: clean_options.my_string,
57
+ hash_multiple: clean_options.hash_multiple,
58
+ array: clean_options.array,
59
+ hash_single: clean_options.hash_single,
60
+ my_class: clean_options.my_class
61
+ ).to match(
62
+ my_string: 'default string',
63
+ hash_multiple: { first: String, second: Float, third: Float },
64
+ array: [:one, :two, :three],
65
+ hash_single: {},
66
+ my_class: Float
67
+ )
68
+ end
69
+ end
70
+
71
+ context 'when an option provided is invalid' do
72
+ let(:options) do
73
+ {
74
+ hash_multiple: { first: String, second: Float, third: Float },
75
+ array: ['not symbol 1', 'not symbol 2'],
76
+ my_class: Float
77
+ }
78
+ end
79
+
80
+ it 'raises an error' do
81
+ expect { clean_options }.to raise_error(GraphqlDevise::InvalidMountOptionsError, '`array` option has invalid elements. Symbol expected.')
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::ArrayChecker do
4
+ describe '#call!' do
5
+ subject(:clean_value) { described_class.new(element_type).call!(value, key) }
6
+
7
+ let(:key) { :any_option }
8
+ let(:element_type) { Symbol }
9
+
10
+ context 'when no value is provided' do
11
+ let(:value) { nil }
12
+
13
+ it { is_expected.to eq([]) }
14
+ end
15
+
16
+ context 'when provided value is not an array' do
17
+ let(:value) { 'not an array' }
18
+
19
+ it 'raises an error' do
20
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Array expected.")
21
+ end
22
+ end
23
+
24
+ context 'when provided array contains invalid elements' do
25
+ let(:value) { [:valid, 'invalid'] }
26
+
27
+ it 'raises an error' do
28
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has invalid elements. #{element_type} expected.")
29
+ end
30
+ end
31
+
32
+ context 'when provided array contains all valid elements' do
33
+ let(:value) { [:valid1, :valid2] }
34
+
35
+ it { is_expected.to eq(value) }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::ClassChecker do
4
+ describe '#call!' do
5
+ subject(:clean_value) { described_class.new(expected_class).call!(value, key) }
6
+
7
+ let(:key) { :any_option }
8
+ let(:expected_class) { Numeric }
9
+
10
+ context 'when no value is provided' do
11
+ let(:value) { nil }
12
+
13
+ it { is_expected.to eq(nil) }
14
+ end
15
+
16
+ context 'when provided value is not a class' do
17
+ let(:value) { 'I\'m not a class' }
18
+
19
+ it 'raises an error' do
20
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Class expected.")
21
+ end
22
+ end
23
+
24
+ context 'when provided class is not of the expected type' do
25
+ let(:value) { String }
26
+
27
+ it 'raises an error' do
28
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. #{expected_class} or descendants expected. Got String.")
29
+ end
30
+ end
31
+
32
+ context 'when provided class is of the expected type' do
33
+ let(:value) { Numeric }
34
+
35
+ it { is_expected.to eq(value) }
36
+ end
37
+
38
+ context 'when provided class has the expected type as an acestor' do
39
+ let(:value) { Float }
40
+
41
+ it { is_expected.to eq(value) }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::HashChecker do
4
+ describe '#call!' do
5
+ subject(:clean_value) { described_class.new(element_type).call!(value, key) }
6
+
7
+ let(:key) { :any_option }
8
+
9
+ context 'when a single valid type is provided' do
10
+ let(:element_type) { Numeric }
11
+
12
+ context 'when no value is provided' do
13
+ let(:value) { nil }
14
+
15
+ it { is_expected.to eq({}) }
16
+ end
17
+
18
+ context 'when provided value is not a hash' do
19
+ let(:value) { 'not a hash' }
20
+
21
+ it 'raises an error' do
22
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Hash expected. Got String.")
23
+ end
24
+ end
25
+
26
+ context 'when provided hash contains invalid elements' do
27
+ let(:value) { { valid: Float, invalid: String } }
28
+
29
+ it 'raises an error' do
30
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key} -> invalid` option has an invalid value. #{element_type} or descendants expected. Got #{String}.")
31
+ end
32
+ end
33
+
34
+ context 'when provided array contains all valid elements' do
35
+ let(:value) { { valid1: Numeric, valid2: Numeric } }
36
+
37
+ it { is_expected.to eq(value) }
38
+ end
39
+
40
+ context 'when provided class has the expected type as an acestor' do
41
+ let(:value) { { valid: Float } }
42
+
43
+ it { is_expected.to eq(value) }
44
+ end
45
+ end
46
+
47
+ context 'when multiple value types are allowed' do
48
+ let(:element_type) { [String, Numeric] }
49
+
50
+ context 'when no value is provided' do
51
+ let(:value) { nil }
52
+
53
+ it { is_expected.to eq({}) }
54
+ end
55
+
56
+ context 'when provided array contains all valid elements' do
57
+ let(:value) { { valid1: String, valid2: Numeric } }
58
+
59
+ it { is_expected.to eq(value) }
60
+ end
61
+
62
+ context 'when provided class has the expected type as an acestor' do
63
+ let(:value) { { valid: Float } }
64
+
65
+ it { is_expected.to eq(value) }
66
+ end
67
+
68
+ context 'when provided value is not a hash' do
69
+ let(:value) { 'not a hash' }
70
+
71
+ it 'raises an error' do
72
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. Hash expected. Got String.")
73
+ end
74
+ end
75
+
76
+ context 'when provided hash contains invalid elements' do
77
+ let(:value) { { valid: String, invalid: StandardError } }
78
+
79
+ it 'raises an error' do
80
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key} -> invalid` option has an invalid value. #{element_type.join(', ')} or descendants expected. Got #{StandardError}.")
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GraphqlDevise::MountMethod::OptionSanitizers::StringChecker do
4
+ describe '#call!' do
5
+ subject(:clean_value) { described_class.new(default_string).call!(value, key) }
6
+
7
+ let(:key) { :any_option }
8
+ let(:default_string) { 'default string' }
9
+
10
+ context 'when no value is provided' do
11
+ let(:value) { nil }
12
+
13
+ it { is_expected.to eq(default_string) }
14
+ end
15
+
16
+ context 'when provided value is not a String' do
17
+ let(:value) { 1000 }
18
+
19
+ it 'raises an error' do
20
+ expect { clean_value }.to raise_error(GraphqlDevise::InvalidMountOptionsError, "`#{key}` option has an invalid value. String expected.")
21
+ end
22
+ end
23
+
24
+ context 'when provided array contains all valid elements' do
25
+ let(:value) { 'custom valid string' }
26
+
27
+ it { is_expected.to eq(value) }
28
+ end
29
+ end
30
+ end