graphql_devise 0.18.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +7 -2
  3. data/.gitignore +3 -0
  4. data/.rubocop.yml +9 -10
  5. data/Appraisals +70 -18
  6. data/CHANGELOG.md +53 -0
  7. data/README.md +71 -142
  8. data/app/controllers/graphql_devise/graphql_controller.rb +3 -3
  9. data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +1 -5
  10. data/config/routes.rb +0 -2
  11. data/graphql_devise.gemspec +7 -5
  12. data/lib/graphql_devise/concerns/additional_controller_methods.rb +48 -0
  13. data/lib/graphql_devise/concerns/additional_model_methods.rb +17 -0
  14. data/lib/graphql_devise/concerns/authenticatable.rb +1 -1
  15. data/lib/graphql_devise/concerns/controller_methods.rb +70 -93
  16. data/lib/graphql_devise/concerns/field_authentication.rb +14 -0
  17. data/lib/graphql_devise/concerns/set_user_by_token.rb +1 -1
  18. data/lib/graphql_devise/default_operations.rb +16 -0
  19. data/lib/graphql_devise/engine.rb +0 -2
  20. data/lib/graphql_devise/model/with_email_updater.rb +5 -30
  21. data/lib/graphql_devise/mount_method/operation_preparer.rb +0 -7
  22. data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +1 -1
  23. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +1 -1
  24. data/lib/graphql_devise/mount_method/operation_sanitizer.rb +0 -12
  25. data/lib/graphql_devise/mount_method/option_sanitizer.rb +0 -2
  26. data/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb +2 -2
  27. data/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb +2 -2
  28. data/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb +1 -1
  29. data/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb +1 -1
  30. data/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb +0 -2
  31. data/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb +1 -1
  32. data/lib/graphql_devise/mount_method/option_validators/supported_operations_validator.rb +1 -1
  33. data/lib/graphql_devise/mount_method/options_validator.rb +0 -3
  34. data/lib/graphql_devise/mount_method/supported_options.rb +0 -5
  35. data/lib/graphql_devise/mutations/base.rb +1 -1
  36. data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +1 -1
  37. data/lib/graphql_devise/mutations/login.rb +1 -1
  38. data/lib/graphql_devise/mutations/register.rb +1 -1
  39. data/lib/graphql_devise/mutations/update_password_with_token.rb +1 -1
  40. data/lib/graphql_devise/resolvers/base.rb +1 -1
  41. data/lib/graphql_devise/resource_loader.rb +71 -39
  42. data/lib/graphql_devise/route_mounter.rb +13 -0
  43. data/lib/graphql_devise/schema_plugin.rb +7 -40
  44. data/lib/graphql_devise/types/authenticatable_type.rb +1 -1
  45. data/lib/graphql_devise/types/base_field.rb +9 -0
  46. data/lib/graphql_devise/types/base_type.rb +8 -0
  47. data/lib/graphql_devise/types/credential_type.rb +1 -1
  48. data/lib/graphql_devise/types/mutation_type.rb +1 -0
  49. data/lib/graphql_devise/types/query_type.rb +1 -0
  50. data/lib/graphql_devise/version.rb +1 -1
  51. data/lib/graphql_devise.rb +21 -29
  52. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +1 -16
  53. data/spec/dummy/app/graphql/dummy_schema.rb +1 -5
  54. data/spec/dummy/app/graphql/interpreter_schema.rb +6 -2
  55. data/spec/dummy/app/graphql/mutations/base_mutation.rb +6 -0
  56. data/spec/dummy/app/graphql/mutations/update_user.rb +2 -4
  57. data/spec/dummy/app/graphql/types/admin_type.rb +1 -1
  58. data/spec/dummy/app/graphql/types/custom_admin_type.rb +1 -1
  59. data/spec/dummy/app/graphql/types/mutation_type.rb +3 -1
  60. data/spec/dummy/app/graphql/types/query_type.rb +3 -1
  61. data/spec/dummy/app/graphql/types/user_type.rb +1 -1
  62. data/spec/dummy/config/environments/test.rb +1 -1
  63. data/spec/dummy/config/routes.rb +5 -9
  64. data/spec/graphql_devise/model/with_email_updater_spec.rb +17 -35
  65. data/spec/rails_helper.rb +5 -5
  66. data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +2 -3
  67. data/spec/requests/user_controller_spec.rb +1 -33
  68. data/spec/services/resource_loader_spec.rb +14 -3
  69. metadata +55 -48
  70. data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +0 -72
  71. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +0 -21
  72. data/app/helpers/graphql_devise/mailer_helper.rb +0 -37
  73. data/app/models/graphql_devise/concerns/additional_model_methods.rb +0 -21
  74. data/app/models/graphql_devise/concerns/model.rb +0 -25
  75. data/lib/graphql_devise/default_operations/mutations.rb +0 -32
  76. data/lib/graphql_devise/default_operations/resolvers.rb +0 -14
  77. data/lib/graphql_devise/mutations/resend_confirmation.rb +0 -45
  78. data/lib/graphql_devise/mutations/send_password_reset.rb +0 -38
  79. data/lib/graphql_devise/mutations/sign_up.rb +0 -61
  80. data/lib/graphql_devise/mutations/update_password.rb +0 -46
  81. data/lib/graphql_devise/rails/routes.rb +0 -15
  82. data/lib/graphql_devise/resolvers/check_password_token.rb +0 -43
  83. data/lib/graphql_devise/resolvers/confirm_account.rb +0 -42
  84. data/spec/dummy/app/graphql/mutations/sign_up.rb +0 -14
  85. data/spec/dummy/app/graphql/resolvers/confirm_admin_account.rb +0 -13
  86. data/spec/requests/mutations/resend_confirmation_spec.rb +0 -153
  87. data/spec/requests/mutations/send_password_reset_spec.rb +0 -103
  88. data/spec/requests/mutations/sign_up_spec.rb +0 -170
  89. data/spec/requests/mutations/update_password_spec.rb +0 -116
  90. data/spec/requests/queries/check_password_token_spec.rb +0 -149
  91. data/spec/requests/queries/confirm_account_spec.rb +0 -137
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActionDispatch::Routing
4
- class Mapper
5
- def mount_graphql_devise_for(resource, options = {})
6
- clean_options = GraphqlDevise::ResourceLoader.new(resource, options, true).call(
7
- GraphqlDevise::Types::QueryType,
8
- GraphqlDevise::Types::MutationType
9
- )
10
-
11
- post clean_options.at, to: 'graphql_devise/graphql#auth'
12
- get clean_options.at, to: 'graphql_devise/graphql#auth'
13
- end
14
- end
15
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphqlDevise
4
- module Resolvers
5
- class CheckPasswordToken < Base
6
- argument :reset_password_token, String, required: true
7
- argument :redirect_url, String, required: false
8
-
9
- def resolve(reset_password_token:, redirect_url: nil)
10
- resource = resource_class.with_reset_password_token(reset_password_token)
11
- raise_user_error(I18n.t('graphql_devise.passwords.reset_token_not_found')) if resource.blank?
12
-
13
- if resource.reset_password_period_valid?
14
- token_info = client_and_token(resource.create_token)
15
-
16
- resource.skip_confirmation! if confirmable_enabled? && !resource.confirmed_at
17
- resource.allow_password_change = true if recoverable_enabled?
18
-
19
- resource.save!
20
-
21
- yield resource if block_given?
22
-
23
- redirect_header_options = { reset_password: true }
24
- built_redirect_headers = redirect_headers(
25
- token_info,
26
- redirect_header_options
27
- )
28
-
29
- if redirect_url.present?
30
- check_redirect_url_whitelist!(redirect_url)
31
- controller.redirect_to(resource.build_auth_url(redirect_url, built_redirect_headers))
32
- else
33
- set_auth_headers(resource)
34
- end
35
-
36
- resource
37
- else
38
- raise_user_error(I18n.t('graphql_devise.passwords.reset_token_expired'))
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphqlDevise
4
- module Resolvers
5
- class ConfirmAccount < Base
6
- argument :confirmation_token, String, required: true
7
- argument :redirect_url, String, required: true
8
-
9
- def resolve(confirmation_token:, redirect_url:)
10
- check_redirect_url_whitelist!(redirect_url)
11
-
12
- resource = resource_class.confirm_by_token(confirmation_token)
13
-
14
- if resource.errors.empty?
15
- yield resource if block_given?
16
-
17
- redirect_header_options = { account_confirmation_success: true }
18
-
19
- redirect_to_link = if controller.signed_in?(resource_name)
20
- url = resource.build_auth_url(
21
- redirect_url,
22
- redirect_headers(
23
- client_and_token(resource.create_token),
24
- redirect_header_options
25
- )
26
- )
27
- resource.save!
28
-
29
- url
30
- else
31
- DeviseTokenAuth::Url.generate(redirect_url, redirect_header_options)
32
- end
33
-
34
- controller.redirect_to(redirect_to_link)
35
- resource
36
- else
37
- raise_user_error(I18n.t('graphql_devise.confirmations.invalid_token'))
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutations
4
- class SignUp < GraphqlDevise::Mutations::SignUp
5
- argument :name, String, required: false
6
-
7
- field :user, Types::UserType, null: true
8
-
9
- def resolve(email:, **attrs)
10
- original_payload = super
11
- original_payload.merge(user: original_payload[:authenticatable])
12
- end
13
- end
14
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Resolvers
4
- class ConfirmAdminAccount < GraphqlDevise::Resolvers::ConfirmAccount
5
- type Types::AdminType, null: false
6
-
7
- def resolve(confirmation_token:, redirect_url:)
8
- super do |admin|
9
- controller.sign_in(admin)
10
- end
11
- end
12
- end
13
- end
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Resend confirmation' do
6
- include_context 'with graphql query request'
7
-
8
- let(:confirmed_at) { nil }
9
- let!(:user) { create(:user, confirmed_at: nil, email: 'mwallace@wallaceinc.com') }
10
- let(:email) { user.email }
11
- let(:id) { user.id }
12
- let(:redirect) { 'https://google.com' }
13
- let(:query) do
14
- <<-GRAPHQL
15
- mutation {
16
- userResendConfirmation(
17
- email:"#{email}",
18
- redirectUrl:"#{redirect}"
19
- ) {
20
- message
21
- }
22
- }
23
- GRAPHQL
24
- end
25
-
26
- context 'when redirect_url is not whitelisted' do
27
- let(:redirect) { 'https://not-safe.com' }
28
-
29
- it 'returns a not whitelisted redirect url error' do
30
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
31
-
32
- expect(json_response[:errors]).to containing_exactly(
33
- hash_including(
34
- message: "Redirect to '#{redirect}' not allowed.",
35
- extensions: { code: 'USER_ERROR' }
36
- )
37
- )
38
- end
39
- end
40
-
41
- context 'when params are correct' do
42
- context 'when using the gem schema' do
43
- it 'sends an email to the user with confirmation url and returns a success message' do
44
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
45
- expect(json_response[:data][:userResendConfirmation]).to include(
46
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
47
- )
48
-
49
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
50
- link = email.css('a').first
51
- confirm_link_msg_text = email.css('p')[1].inner_html
52
- confirm_account_link_text = link.inner_html
53
-
54
- expect(link['href']).to include('/api/v1/graphql_auth?')
55
- expect(confirm_link_msg_text).to eq('You can confirm your account email through the link below:')
56
- expect(confirm_account_link_text).to eq('Confirm my account')
57
-
58
- expect do
59
- get link['href']
60
- user.reload
61
- end.to change(user, :confirmed_at).from(NilClass).to(ActiveSupport::TimeWithZone)
62
- end
63
- end
64
-
65
- context 'when using a custom schema' do
66
- let(:custom_path) { '/api/v1/graphql' }
67
-
68
- it 'sends an email to the user with confirmation url and returns a success message' do
69
- expect { post_request(custom_path) }.to change(ActionMailer::Base.deliveries, :count).by(1)
70
- expect(json_response[:data][:userResendConfirmation]).to include(
71
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
72
- )
73
-
74
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
75
- link = email.css('a').first
76
- confirm_link_msg_text = email.css('p')[1].inner_html
77
- confirm_account_link_text = link.inner_html
78
-
79
- expect(link['href']).to include("#{custom_path}?")
80
- expect(confirm_link_msg_text).to eq('You can confirm your account email through the link below:')
81
- expect(confirm_account_link_text).to eq('Confirm my account')
82
-
83
- expect do
84
- get link['href']
85
- user.reload
86
- end.to change(user, :confirmed_at).from(NilClass).to(ActiveSupport::TimeWithZone)
87
- end
88
- end
89
-
90
- context 'when email address uses different casing' do
91
- let(:email) { 'mWallace@wallaceinc.com' }
92
-
93
- it 'honors devise configuration for case insensitive fields' do
94
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
95
- expect(json_response[:data][:userResendConfirmation]).to include(
96
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
97
- )
98
- end
99
- end
100
-
101
- context 'when the user has already been confirmed' do
102
- before { user.confirm }
103
-
104
- it 'does *NOT* send an email and raises an error' do
105
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
106
- expect(json_response[:data][:userResendConfirmation]).to be_nil
107
- expect(json_response[:errors]).to contain_exactly(
108
- hash_including(
109
- message: 'Email was already confirmed, please try signing in',
110
- extensions: { code: 'USER_ERROR' }
111
- )
112
- )
113
- end
114
- end
115
- end
116
-
117
- context 'when the email was changed' do
118
- let(:confirmed_at) { 2.seconds.ago }
119
- let(:email) { 'new-email@wallaceinc.com' }
120
- let(:new_email) { email }
121
-
122
- before do
123
- user.update_with_email(
124
- email: new_email,
125
- schema_url: 'http://localhost/test',
126
- confirmation_success_url: 'https://google.com'
127
- )
128
- end
129
-
130
- it 'sends new confirmation email' do
131
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
132
- expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(new_email)
133
- expect(json_response[:data][:userResendConfirmation]).to include(
134
- message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
135
- )
136
- end
137
- end
138
-
139
- context "when the email isn't in the system" do
140
- let(:email) { 'nothere@gmail.com' }
141
-
142
- it 'does *NOT* send an email and raises an error' do
143
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
144
- expect(json_response[:data][:userResendConfirmation]).to be_nil
145
- expect(json_response[:errors]).to contain_exactly(
146
- hash_including(
147
- message: "Unable to find user with email '#{email}'.",
148
- extensions: { code: 'USER_ERROR' }
149
- )
150
- )
151
- end
152
- end
153
- end
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Send Password Reset Requests' do
6
- include_context 'with graphql query request'
7
-
8
- let!(:user) { create(:user, :confirmed, email: 'jwinnfield@wallaceinc.com') }
9
- let(:email) { user.email }
10
- let(:redirect_url) { 'https://google.com' }
11
- let(:query) do
12
- <<-GRAPHQL
13
- mutation {
14
- userSendPasswordReset(
15
- email: "#{email}",
16
- redirectUrl: "#{redirect_url}"
17
- ) {
18
- message
19
- }
20
- }
21
- GRAPHQL
22
- end
23
-
24
- context 'when redirect_url is not whitelisted' do
25
- let(:redirect_url) { 'https://not-safe.com' }
26
-
27
- it 'returns a not whitelisted redirect url error' do
28
- expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
29
-
30
- expect(json_response[:errors]).to containing_exactly(
31
- hash_including(
32
- message: "Redirect to '#{redirect_url}' not allowed.",
33
- extensions: { code: 'USER_ERROR' }
34
- )
35
- )
36
- end
37
- end
38
-
39
- context 'when params are correct' do
40
- context 'when using the gem schema' do
41
- it 'sends password reset email' do
42
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
43
-
44
- expect(json_response[:data][:userSendPasswordReset]).to include(
45
- message: 'You will receive an email with instructions on how to reset your password in a few minutes.'
46
- )
47
-
48
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
49
- link = email.css('a').first
50
- expect(link['href']).to include('/api/v1/graphql_auth?')
51
-
52
- expect do
53
- get link['href']
54
- user.reload
55
- end.to change(user, :allow_password_change).from(false).to(true)
56
- end
57
- end
58
-
59
- context 'when using a custom schema' do
60
- let(:custom_path) { '/api/v1/graphql' }
61
-
62
- it 'sends password reset email' do
63
- expect { post_request(custom_path) }.to change(ActionMailer::Base.deliveries, :count).by(1)
64
-
65
- expect(json_response[:data][:userSendPasswordReset]).to include(
66
- message: 'You will receive an email with instructions on how to reset your password in a few minutes.'
67
- )
68
-
69
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
70
- link = email.css('a').first
71
- expect(link['href']).to include("#{custom_path}?")
72
-
73
- expect do
74
- get link['href']
75
- user.reload
76
- end.to change(user, :allow_password_change).from(false).to(true)
77
- end
78
- end
79
- end
80
-
81
- context 'when email address uses different casing' do
82
- let(:email) { 'jWinnfield@wallaceinc.com' }
83
-
84
- it 'honors devise configuration for case insensitive fields' do
85
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
86
- expect(json_response[:data][:userSendPasswordReset]).to include(
87
- message: 'You will receive an email with instructions on how to reset your password in a few minutes.'
88
- )
89
- end
90
- end
91
-
92
- context 'when user email is not found' do
93
- let(:email) { 'nothere@gmail.com' }
94
-
95
- before { post_request }
96
-
97
- it 'returns an error' do
98
- expect(json_response[:errors]).to contain_exactly(
99
- hash_including(message: 'User was not found or was not logged in.', extensions: { code: 'USER_ERROR' })
100
- )
101
- end
102
- end
103
- end
@@ -1,170 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Sign Up process' do
6
- include_context 'with graphql query request'
7
-
8
- let(:name) { Faker::Name.name }
9
- let(:password) { Faker::Internet.password }
10
- let(:email) { Faker::Internet.email }
11
- let(:redirect) { 'https://google.com' }
12
-
13
- context 'when using the user model' do
14
- let(:query) do
15
- <<-GRAPHQL
16
- mutation {
17
- userSignUp(
18
- email: "#{email}"
19
- name: "#{name}"
20
- password: "#{password}"
21
- passwordConfirmation: "#{password}"
22
- confirmSuccessUrl: "#{redirect}"
23
- ) {
24
- credentials { accessToken }
25
- user {
26
- email
27
- name
28
- }
29
- }
30
- }
31
- GRAPHQL
32
- end
33
-
34
- context 'when redirect_url is not whitelisted' do
35
- let(:redirect) { 'https://not-safe.com' }
36
-
37
- it 'returns a not whitelisted redirect url error' do
38
- expect { post_request }.to(
39
- not_change(User, :count)
40
- .and(not_change(ActionMailer::Base.deliveries, :count))
41
- )
42
-
43
- expect(json_response[:errors]).to containing_exactly(
44
- hash_including(
45
- message: "Redirect to '#{redirect}' not allowed.",
46
- extensions: { code: 'USER_ERROR' }
47
- )
48
- )
49
- end
50
- end
51
-
52
- context 'when params are correct' do
53
- it 'creates a new resource that requires confirmation' do
54
- expect { post_request }.to(
55
- change(User, :count).by(1)
56
- .and(change(ActionMailer::Base.deliveries, :count).by(1))
57
- )
58
-
59
- user = User.last
60
-
61
- expect(user).not_to be_active_for_authentication
62
- expect(user.confirmed_at).to be_nil
63
- expect(user).to be_valid_password(password)
64
- expect(json_response[:data][:userSignUp]).to include(
65
- credentials: nil,
66
- user: {
67
- email: email,
68
- name: name
69
- }
70
- )
71
-
72
- email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
73
- link = email.css('a').first
74
-
75
- expect do
76
- get link['href']
77
- user.reload
78
- end.to change { user.active_for_authentication? }.to(true)
79
- end
80
-
81
- context 'when email address uses different casing' do
82
- let(:email) { 'miaWallace@wallaceinc.com' }
83
-
84
- it 'honors devise configuration for case insensitive fields' do
85
- expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
86
- expect(User.last.email).to eq('miawallace@wallaceinc.com')
87
- expect(json_response[:data][:userSignUp]).to include(user: { email: 'miawallace@wallaceinc.com', name: name })
88
- end
89
- end
90
- end
91
-
92
- context 'when required params are missing' do
93
- let(:email) { '' }
94
-
95
- it 'does *NOT* create resource a resource nor send an email' do
96
- expect { post_request }.to(
97
- not_change(User, :count)
98
- .and(not_change(ActionMailer::Base.deliveries, :count))
99
- )
100
-
101
- expect(json_response[:data][:userSignUp]).to be_nil
102
- expect(json_response[:errors]).to containing_exactly(
103
- hash_including(
104
- message: "User couldn't be registered",
105
- extensions: { code: 'USER_ERROR', detailed_errors: ["Email can't be blank"] }
106
- )
107
- )
108
- end
109
- end
110
- end
111
-
112
- context 'when using the admin model' do
113
- let(:query) do
114
- <<-GRAPHQL
115
- mutation {
116
- adminSignUp(
117
- email: "#{email}"
118
- password: "#{password}"
119
- passwordConfirmation: "#{password}"
120
- confirmSuccessUrl: "#{redirect}"
121
- ) {
122
- authenticatable {
123
- email
124
- }
125
- }
126
- }
127
- GRAPHQL
128
- end
129
-
130
- before { post_request }
131
-
132
- it 'skips the sign up mutation' do
133
- expect(json_response[:errors]).to contain_exactly(
134
- hash_including(message: "Field 'adminSignUp' doesn't exist on type 'Mutation'")
135
- )
136
- end
137
- end
138
-
139
- context 'when using the guest model' do
140
- let(:query) do
141
- <<-GRAPHQL
142
- mutation {
143
- guestSignUp(
144
- email: "#{email}"
145
- password: "#{password}"
146
- passwordConfirmation: "#{password}"
147
- confirmSuccessUrl: "#{redirect}"
148
- ) {
149
- credentials { accessToken client uid }
150
- authenticatable {
151
- email
152
- }
153
- }
154
- }
155
- GRAPHQL
156
- end
157
-
158
- it 'returns credentials as no confirmation is required' do
159
- expect { post_request }.to change(Guest, :count).from(0).to(1)
160
-
161
- expect(json_response[:data][:guestSignUp]).to include(
162
- authenticatable: { email: email },
163
- credentials: hash_including(
164
- uid: email,
165
- client: Guest.last.tokens.keys.first
166
- )
167
- )
168
- end
169
- end
170
- end
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Update Password Requests' do
6
- shared_examples 'successful password update' do
7
- it 'updates the password' do
8
- expect do
9
- post_request
10
- user.reload
11
- end.to change(user, :encrypted_password)
12
-
13
- expect(response).to include_auth_headers
14
- expect(json_response[:data][:userUpdatePassword]).to match(
15
- authenticatable: { email: user.email }
16
- )
17
- expect(json_response[:errors]).to be_nil
18
- expect(user).to be_valid_password(password)
19
- end
20
- end
21
-
22
- include_context 'with graphql query request'
23
-
24
- let(:password) { 'safePassw0rd!' }
25
- let(:password_confirmation) { 'safePassw0rd!' }
26
- let(:original_password) { 'current_password' }
27
- let(:current_password) { original_password }
28
- let(:allow_password_change) { false }
29
- let(:user) { create(:user, :confirmed, password: original_password, allow_password_change: allow_password_change) }
30
- let(:query) do
31
- <<-GRAPHQL
32
- mutation {
33
- userUpdatePassword(
34
- password: "#{password}",
35
- passwordConfirmation: "#{password_confirmation}",
36
- currentPassword: "#{current_password}"
37
- ) {
38
- authenticatable { email }
39
- }
40
- }
41
- GRAPHQL
42
- end
43
-
44
- context 'when user is logged in' do
45
- let(:headers) { user.create_new_auth_token }
46
-
47
- context 'when currentPassword is not provided' do
48
- let(:current_password) { nil }
49
-
50
- context 'when allow_password_change is true' do
51
- let(:allow_password_change) { true }
52
-
53
- it_behaves_like 'successful password update'
54
-
55
- it 'sets allow_password_change to false' do
56
- expect do
57
- post_request
58
- user.reload
59
- end.to change(user, :allow_password_change).from(true).to(false)
60
- end
61
- end
62
-
63
- context 'when allow_password_change is false' do
64
- it 'does not update the password' do
65
- expect do
66
- post_request
67
- user.reload
68
- end.not_to change(user, :encrypted_password)
69
-
70
- expect(response).to include_auth_headers
71
- expect(json_response[:data][:userUpdatePassword]).to be_nil
72
- expect(json_response[:errors]).to contain_exactly(
73
- hash_including(
74
- message: 'Unable to update user password',
75
- extensions: { code: 'USER_ERROR', detailed_errors: ["Current password can't be blank"] }
76
- )
77
- )
78
- end
79
- end
80
- end
81
-
82
- context 'when currentPassword is provided' do
83
- context 'when allow_password_change is true' do
84
- let(:allow_password_change) { true }
85
-
86
- it_behaves_like 'successful password update'
87
-
88
- it 'sets allow_password_change to false' do
89
- expect do
90
- post_request
91
- user.reload
92
- end.to change(user, :allow_password_change).from(true).to(false)
93
- end
94
- end
95
-
96
- context 'when allow_password_change is false' do
97
- it_behaves_like 'successful password update'
98
- end
99
- end
100
- end
101
-
102
- context 'when user is not logged in' do
103
- it 'does not update the password' do
104
- expect do
105
- post_request
106
- user.reload
107
- end.not_to change(user, :encrypted_password)
108
-
109
- expect(response).not_to include_auth_headers
110
- expect(json_response[:data][:userUpdatePassword]).to be_nil
111
- expect(json_response[:errors]).to contain_exactly(
112
- hash_including(message: 'User is not logged in.', extensions: { code: 'USER_ERROR' })
113
- )
114
- end
115
- end
116
- end