graphql_devise 0.18.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +25 -2
  3. data/.gitignore +4 -0
  4. data/.rubocop.yml +9 -10
  5. data/Appraisals +72 -35
  6. data/CHANGELOG.md +63 -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 +8 -6
  12. data/lib/generators/graphql_devise/install_generator.rb +1 -1
  13. data/lib/graphql_devise/concerns/additional_controller_methods.rb +48 -0
  14. data/lib/graphql_devise/concerns/additional_model_methods.rb +17 -0
  15. data/lib/graphql_devise/concerns/authenticatable.rb +1 -1
  16. data/lib/graphql_devise/concerns/controller_methods.rb +79 -91
  17. data/lib/graphql_devise/concerns/field_authentication.rb +14 -0
  18. data/lib/graphql_devise/concerns/set_user_by_token.rb +1 -1
  19. data/lib/graphql_devise/default_operations.rb +16 -0
  20. data/lib/graphql_devise/engine.rb +0 -2
  21. data/lib/graphql_devise/model/with_email_updater.rb +5 -30
  22. data/lib/graphql_devise/mount_method/operation_preparer.rb +0 -7
  23. data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +1 -1
  24. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +1 -1
  25. data/lib/graphql_devise/mount_method/operation_sanitizer.rb +0 -12
  26. data/lib/graphql_devise/mount_method/option_sanitizer.rb +0 -2
  27. data/lib/graphql_devise/mount_method/option_sanitizers/array_checker.rb +2 -2
  28. data/lib/graphql_devise/mount_method/option_sanitizers/class_checker.rb +2 -2
  29. data/lib/graphql_devise/mount_method/option_sanitizers/hash_checker.rb +1 -1
  30. data/lib/graphql_devise/mount_method/option_sanitizers/string_checker.rb +1 -1
  31. data/lib/graphql_devise/mount_method/option_validators/provided_operations_validator.rb +0 -2
  32. data/lib/graphql_devise/mount_method/option_validators/skip_only_validator.rb +1 -1
  33. data/lib/graphql_devise/mount_method/option_validators/supported_operations_validator.rb +1 -1
  34. data/lib/graphql_devise/mount_method/options_validator.rb +0 -3
  35. data/lib/graphql_devise/mount_method/supported_options.rb +0 -5
  36. data/lib/graphql_devise/mutations/base.rb +1 -1
  37. data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +2 -2
  38. data/lib/graphql_devise/mutations/login.rb +2 -2
  39. data/lib/graphql_devise/mutations/register.rb +2 -2
  40. data/lib/graphql_devise/mutations/update_password_with_token.rb +2 -2
  41. data/lib/graphql_devise/resolvers/base.rb +1 -1
  42. data/lib/graphql_devise/resource_loader.rb +71 -39
  43. data/lib/graphql_devise/route_mounter.rb +13 -0
  44. data/lib/graphql_devise/schema_plugin.rb +11 -40
  45. data/lib/graphql_devise/types/authenticatable_type.rb +1 -1
  46. data/lib/graphql_devise/types/base_field.rb +9 -0
  47. data/lib/graphql_devise/types/base_type.rb +8 -0
  48. data/lib/graphql_devise/types/credential_type.rb +1 -1
  49. data/lib/graphql_devise/types/mutation_type.rb +1 -0
  50. data/lib/graphql_devise/types/query_type.rb +1 -0
  51. data/lib/graphql_devise/version.rb +1 -1
  52. data/lib/graphql_devise.rb +21 -29
  53. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +2 -16
  54. data/spec/dummy/app/graphql/dummy_schema.rb +1 -5
  55. data/spec/dummy/app/graphql/interpreter_schema.rb +6 -2
  56. data/spec/dummy/app/graphql/mutations/base_mutation.rb +6 -0
  57. data/spec/dummy/app/graphql/mutations/update_user.rb +2 -4
  58. data/spec/dummy/app/graphql/types/admin_type.rb +1 -1
  59. data/spec/dummy/app/graphql/types/custom_admin_type.rb +1 -1
  60. data/spec/dummy/app/graphql/types/mutation_type.rb +3 -1
  61. data/spec/dummy/app/graphql/types/query_type.rb +3 -1
  62. data/spec/dummy/app/graphql/types/user_type.rb +1 -1
  63. data/spec/dummy/config/environments/test.rb +1 -1
  64. data/spec/dummy/config/routes.rb +5 -9
  65. data/spec/generators/graphql_devise/install_generator_spec.rb +2 -2
  66. data/spec/graphql_devise/model/with_email_updater_spec.rb +17 -35
  67. data/spec/rails_helper.rb +5 -5
  68. data/spec/requests/mutations/login_spec.rb +34 -0
  69. data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +2 -3
  70. data/spec/requests/user_controller_spec.rb +1 -33
  71. data/spec/services/resource_loader_spec.rb +53 -3
  72. data/spec/spec_helper.rb +1 -1
  73. metadata +62 -55
  74. data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +0 -72
  75. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +0 -21
  76. data/app/helpers/graphql_devise/mailer_helper.rb +0 -37
  77. data/app/models/graphql_devise/concerns/additional_model_methods.rb +0 -21
  78. data/app/models/graphql_devise/concerns/model.rb +0 -25
  79. data/lib/graphql_devise/default_operations/mutations.rb +0 -32
  80. data/lib/graphql_devise/default_operations/resolvers.rb +0 -14
  81. data/lib/graphql_devise/mutations/resend_confirmation.rb +0 -45
  82. data/lib/graphql_devise/mutations/send_password_reset.rb +0 -38
  83. data/lib/graphql_devise/mutations/sign_up.rb +0 -61
  84. data/lib/graphql_devise/mutations/update_password.rb +0 -46
  85. data/lib/graphql_devise/rails/routes.rb +0 -15
  86. data/lib/graphql_devise/resolvers/check_password_token.rb +0 -43
  87. data/lib/graphql_devise/resolvers/confirm_account.rb +0 -42
  88. data/spec/dummy/app/graphql/mutations/sign_up.rb +0 -14
  89. data/spec/dummy/app/graphql/resolvers/confirm_admin_account.rb +0 -13
  90. data/spec/requests/mutations/resend_confirmation_spec.rb +0 -153
  91. data/spec/requests/mutations/send_password_reset_spec.rb +0 -103
  92. data/spec/requests/mutations/sign_up_spec.rb +0 -170
  93. data/spec/requests/mutations/update_password_spec.rb +0 -116
  94. data/spec/requests/queries/check_password_token_spec.rb +0 -149
  95. data/spec/requests/queries/confirm_account_spec.rb +0 -137
@@ -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
@@ -1,149 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rails_helper'
4
-
5
- RSpec.describe 'Check Password Token Requests' do
6
- include_context 'with graphql query request'
7
-
8
- let(:user) { create(:user, :confirmed) }
9
- let(:redirect_url) { 'https://google.com' }
10
-
11
- context 'when using the user model' do
12
- let(:query) do
13
- <<-GRAPHQL
14
- query {
15
- userCheckPasswordToken(
16
- resetPasswordToken: "#{token}",
17
- redirectUrl: "#{redirect_url}"
18
- ) {
19
- email
20
- }
21
- }
22
- GRAPHQL
23
- end
24
-
25
- context 'when reset password token is valid' do
26
- let(:token) { user.send(:set_reset_password_token) }
27
-
28
- context 'when redirect_url is not provided' do
29
- let(:redirect_url) { nil }
30
-
31
- it 'returns authenticatable and credentials in the headers' do
32
- get_request
33
-
34
- expect(response).to include_auth_headers
35
- expect(json_response[:data][:userCheckPasswordToken]).to match(
36
- email: user.email
37
- )
38
- end
39
- end
40
-
41
- context 'when redirect url is provided' do
42
- it 'redirects to redirect url' do
43
- expect do
44
- get_request
45
-
46
- user.reload
47
- end.to change { user.tokens.keys.count }.from(0).to(1).and(
48
- change(user, :allow_password_change).from(false).to(true)
49
- )
50
-
51
- expect(response).to redirect_to %r{\Ahttps://google.com}
52
- expect(response.body).to include("client=#{user.reload.tokens.keys.first}")
53
- expect(response.body).to include('access-token=')
54
- expect(response.body).to include('uid=')
55
- expect(response.body).to include('expiry=')
56
- end
57
-
58
- context 'when redirect_url is not whitelisted' do
59
- let(:redirect_url) { 'https://not-safe.com' }
60
-
61
- before { post_request }
62
-
63
- it 'returns a not whitelisted redirect url error' do
64
- expect(json_response[:errors]).to containing_exactly(
65
- hash_including(
66
- message: "Redirect to '#{redirect_url}' not allowed.",
67
- extensions: { code: 'USER_ERROR' }
68
- )
69
- )
70
- end
71
- end
72
- end
73
-
74
- context 'when token has expired' do
75
- it 'returns an expired token error' do
76
- travel_to 10.hours.ago do
77
- token
78
- end
79
-
80
- get_request
81
-
82
- expect(json_response[:errors]).to contain_exactly(
83
- hash_including(message: 'Reset password token is no longer valid.', extensions: { code: 'USER_ERROR' })
84
- )
85
- end
86
- end
87
- end
88
-
89
- context 'when reset password token is not found' do
90
- let(:token) { user.send(:set_reset_password_token) + 'invalid' }
91
-
92
- it 'returns an error message' do
93
- get_request
94
-
95
- expect(json_response[:errors]).to contain_exactly(
96
- hash_including(message: 'No user found for the specified reset token.', extensions: { code: 'USER_ERROR' })
97
- )
98
- end
99
- end
100
- end
101
-
102
- context 'when using the admin model' do
103
- let(:token) { 'not_important' }
104
- let(:query) do
105
- <<-GRAPHQL
106
- query {
107
- adminCheckPasswordToken(
108
- resetPasswordToken: "#{token}",
109
- redirectUrl: "#{redirect_url}"
110
- ) {
111
- email
112
- }
113
- }
114
- GRAPHQL
115
- end
116
-
117
- before { post_request }
118
-
119
- it 'skips the sign up mutation' do
120
- expect(json_response[:errors]).to contain_exactly(
121
- hash_including(message: "Field 'adminCheckPasswordToken' doesn't exist on type 'Query'")
122
- )
123
- end
124
- end
125
-
126
- context 'when using the guest model' do
127
- let(:token) { 'not_important' }
128
- let(:query) do
129
- <<-GRAPHQL
130
- query {
131
- guestCheckPasswordToken(
132
- resetPasswordToken: "#{token}",
133
- redirectUrl: "#{redirect_url}"
134
- ) {
135
- email
136
- }
137
- }
138
- GRAPHQL
139
- end
140
-
141
- before { post_request }
142
-
143
- it 'skips the sign up mutation' do
144
- expect(json_response[:errors]).to contain_exactly(
145
- hash_including(message: "Field 'guestCheckPasswordToken' doesn't exist on type 'Query'")
146
- )
147
- end
148
- end
149
- end