graphql_devise 0.16.0 → 0.17.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +49 -23
- data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +7 -1
- data/lib/graphql_devise/default_operations/mutations.rb +14 -8
- data/lib/graphql_devise/default_operations/resolvers.rb +2 -2
- data/lib/graphql_devise/model/with_email_updater.rb +34 -8
- data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +1 -1
- data/lib/graphql_devise/mount_method/operation_sanitizer.rb +13 -1
- data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +30 -0
- data/lib/graphql_devise/mutations/register.rb +60 -0
- data/lib/graphql_devise/mutations/resend_confirmation_with_token.rb +44 -0
- data/lib/graphql_devise/mutations/sign_up.rb +1 -1
- data/lib/graphql_devise/version.rb +1 -1
- data/spec/dummy/app/graphql/dummy_schema.rb +4 -3
- data/spec/dummy/app/graphql/mutations/register.rb +14 -0
- data/spec/dummy/config/routes.rb +5 -4
- data/spec/graphql_devise/model/with_email_updater_spec.rb +97 -68
- data/spec/requests/mutations/confirm_registration_with_token_spec.rb +117 -0
- data/spec/requests/mutations/register_spec.rb +166 -0
- data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +137 -0
- data/spec/services/mount_method/operation_sanitizer_spec.rb +3 -3
- metadata +14 -3
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphqlDevise
|
4
|
+
module Mutations
|
5
|
+
class ResendConfirmationWithToken < Base
|
6
|
+
argument :email, String, required: true
|
7
|
+
argument :confirm_url, String, required: true
|
8
|
+
|
9
|
+
field :message, String, null: false
|
10
|
+
|
11
|
+
def resolve(email:, confirm_url:)
|
12
|
+
check_redirect_url_whitelist!(confirm_url)
|
13
|
+
|
14
|
+
resource = find_confirmable_resource(email)
|
15
|
+
|
16
|
+
if resource
|
17
|
+
yield resource if block_given?
|
18
|
+
|
19
|
+
if resource.confirmed? && !resource.pending_reconfirmation?
|
20
|
+
raise_user_error(I18n.t('graphql_devise.confirmations.already_confirmed'))
|
21
|
+
end
|
22
|
+
|
23
|
+
resource.send_confirmation_instructions(
|
24
|
+
redirect_url: confirm_url,
|
25
|
+
template_path: ['graphql_devise/mailer']
|
26
|
+
)
|
27
|
+
|
28
|
+
{ message: I18n.t('graphql_devise.confirmations.send_instructions', email: email) }
|
29
|
+
else
|
30
|
+
raise_user_error(I18n.t('graphql_devise.confirmations.user_not_found', email: email))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def find_confirmable_resource(email)
|
37
|
+
email_insensitive = get_case_insensitive_field(:email, email)
|
38
|
+
resource = find_resource(:unconfirmed_email, email_insensitive) if resource_class.reconfirmable
|
39
|
+
resource ||= find_resource(:email, email_insensitive)
|
40
|
+
resource
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -31,7 +31,7 @@ module GraphqlDevise
|
|
31
31
|
|
32
32
|
unless resource.confirmed?
|
33
33
|
resource.send_confirmation_instructions(
|
34
|
-
redirect_url:
|
34
|
+
redirect_url: redirect_url,
|
35
35
|
template_path: ['graphql_devise/mailer'],
|
36
36
|
schema_url: controller.full_url_without_params
|
37
37
|
)
|
@@ -7,17 +7,18 @@ class DummySchema < GraphQL::Schema
|
|
7
7
|
public_introspection: true,
|
8
8
|
resource_loaders: [
|
9
9
|
GraphqlDevise::ResourceLoader.new(
|
10
|
-
|
10
|
+
User,
|
11
11
|
only: [
|
12
12
|
:login,
|
13
13
|
:confirm_account,
|
14
14
|
:send_password_reset,
|
15
15
|
:resend_confirmation,
|
16
|
+
:resend_confirmation_with_token,
|
16
17
|
:check_password_token
|
17
18
|
]
|
18
19
|
),
|
19
|
-
GraphqlDevise::ResourceLoader.new(
|
20
|
-
GraphqlDevise::ResourceLoader.new(
|
20
|
+
GraphqlDevise::ResourceLoader.new(Guest, only: [:logout]),
|
21
|
+
GraphqlDevise::ResourceLoader.new(SchemaUser)
|
21
22
|
]
|
22
23
|
)
|
23
24
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutations
|
4
|
+
class Register < GraphqlDevise::Mutations::Register
|
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
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
Rails.application.routes.draw do
|
4
4
|
mount_graphql_devise_for 'User', at: '/api/v1/graphql_auth', operations: {
|
5
|
-
login:
|
6
|
-
sign_up:
|
5
|
+
login: Mutations::Login,
|
6
|
+
sign_up: Mutations::SignUp,
|
7
|
+
register: Mutations::Register
|
7
8
|
}, additional_mutations: {
|
8
9
|
register_confirmed_user: Mutations::RegisterConfirmedUser
|
9
10
|
}, additional_queries: {
|
@@ -13,7 +14,7 @@ Rails.application.routes.draw do
|
|
13
14
|
mount_graphql_devise_for(
|
14
15
|
Admin,
|
15
16
|
authenticatable_type: Types::CustomAdminType,
|
16
|
-
skip: [:sign_up, :check_password_token],
|
17
|
+
skip: [:sign_up, :register, :check_password_token],
|
17
18
|
operations: {
|
18
19
|
confirm_account: Resolvers::ConfirmAdminAccount,
|
19
20
|
update_password_with_token: Mutations::ResetAdminPasswordWithToken
|
@@ -23,7 +24,7 @@ Rails.application.routes.draw do
|
|
23
24
|
|
24
25
|
mount_graphql_devise_for(
|
25
26
|
'Guest',
|
26
|
-
only: [:login, :logout, :sign_up],
|
27
|
+
only: [:login, :logout, :sign_up, :register],
|
27
28
|
at: '/api/v1/guest/graphql_auth'
|
28
29
|
)
|
29
30
|
|
@@ -4,6 +4,57 @@ require 'rails_helper'
|
|
4
4
|
|
5
5
|
RSpec.describe GraphqlDevise::Model::WithEmailUpdater do
|
6
6
|
describe '#call' do
|
7
|
+
shared_examples 'all required arguments are provided' do |base_attributes|
|
8
|
+
let(:attributes) { base_attributes.merge(email: 'new@gmail.com', name: 'Updated Name') }
|
9
|
+
|
10
|
+
it 'postpones email update' do
|
11
|
+
expect do
|
12
|
+
updater
|
13
|
+
resource.reload
|
14
|
+
end.to not_change(resource, :email).from(resource.email).and(
|
15
|
+
not_change(resource, :uid).from(resource.uid)
|
16
|
+
).and(
|
17
|
+
change(resource, :unconfirmed_email).from(nil).to('new@gmail.com')
|
18
|
+
).and(
|
19
|
+
change(resource, :name).from(resource.name).to('Updated Name')
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'sends out a confirmation email to the unconfirmed_email' do
|
24
|
+
expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
25
|
+
|
26
|
+
email = ActionMailer::Base.deliveries.first
|
27
|
+
expect(email.to).to contain_exactly('new@gmail.com')
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when email value is the same on the DB' do
|
31
|
+
let(:attributes) { base_attributes.merge(email: resource.email, name: 'changed') }
|
32
|
+
|
33
|
+
it 'updates attributes and does not send confirmation email' do
|
34
|
+
expect do
|
35
|
+
updater
|
36
|
+
resource.reload
|
37
|
+
end.to change(resource, :name).from(resource.name).to('changed').and(
|
38
|
+
not_change(resource, :email).from(resource.email)
|
39
|
+
).and(
|
40
|
+
not_change(ActionMailer::Base.deliveries, :count).from(0)
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when provided params are invalid' do
|
46
|
+
let(:attributes) { base_attributes.merge(email: 'newgmail.com', name: '') }
|
47
|
+
|
48
|
+
it 'returns false and adds errors to the model' do
|
49
|
+
expect(updater).to be_falsey
|
50
|
+
expect(resource.errors.full_messages).to contain_exactly(
|
51
|
+
'Email is not an email',
|
52
|
+
"Name can't be blank"
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
7
58
|
subject(:updater) { described_class.new(resource, attributes).call }
|
8
59
|
|
9
60
|
context 'when the model does not have an unconfirmed_email column' do
|
@@ -38,90 +89,68 @@ RSpec.describe GraphqlDevise::Model::WithEmailUpdater do
|
|
38
89
|
end
|
39
90
|
|
40
91
|
context 'when attributes contain email' do
|
41
|
-
context 'when
|
42
|
-
|
43
|
-
|
44
|
-
it 'raises an error' do
|
45
|
-
expect { updater }.to raise_error(
|
46
|
-
GraphqlDevise::Error,
|
47
|
-
'Method `update_with_email` requires attributes `confirmation_success_url` and `schema_url` for email reconfirmation to work'
|
48
|
-
)
|
49
|
-
end
|
92
|
+
context 'when confirmation_success_url is used' do
|
93
|
+
it_behaves_like 'all required arguments are provided', schema_url: 'http://localhost/test', confirmation_success_url: 'https://google.com'
|
50
94
|
|
51
|
-
context 'when
|
52
|
-
let(:attributes) { { email:
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
).and(
|
61
|
-
not_change(ActionMailer::Base.deliveries, :count).from(0)
|
95
|
+
context 'when confirmation_success_url is missing and no default is set' do
|
96
|
+
let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name', schema_url: 'http://localhost/test' } }
|
97
|
+
|
98
|
+
before { allow(DeviseTokenAuth).to receive(:default_confirm_success_url).and_return(nil) }
|
99
|
+
|
100
|
+
it 'raises an error' do
|
101
|
+
expect { updater }.to raise_error(
|
102
|
+
GraphqlDevise::Error,
|
103
|
+
'Method `update_with_email` requires attribute `confirmation_url` for email reconfirmation to work'
|
62
104
|
)
|
63
105
|
end
|
106
|
+
|
107
|
+
context 'when email will not change' do
|
108
|
+
let(:attributes) { { email: resource.email, name: 'changed', confirmation_success_url: 'https://google.com' } }
|
109
|
+
|
110
|
+
it 'updates name and does not raise an error' do
|
111
|
+
expect do
|
112
|
+
updater
|
113
|
+
resource.reload
|
114
|
+
end.to change(resource, :name).from(resource.name).to('changed').and(
|
115
|
+
not_change(resource, :email).from(resource.email)
|
116
|
+
).and(
|
117
|
+
not_change(ActionMailer::Base.deliveries, :count).from(0)
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
64
121
|
end
|
65
122
|
end
|
66
123
|
|
67
|
-
context 'when
|
68
|
-
|
124
|
+
context 'when confirm_url is used' do
|
125
|
+
it_behaves_like 'all required arguments are provided', confirmation_url: 'https://google.com'
|
69
126
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
email = ActionMailer::Base.deliveries.first
|
74
|
-
expect(email.body.decoded).to include(CGI.escape('https://google.com'))
|
127
|
+
context 'when arguments hash has strings as keys' do
|
128
|
+
it_behaves_like 'all required arguments are provided', 'confirmation_url' => 'https://google.com'
|
75
129
|
end
|
76
130
|
end
|
77
131
|
|
78
|
-
context 'when
|
79
|
-
|
80
|
-
|
81
|
-
it 'postpones email update' do
|
82
|
-
expect do
|
83
|
-
updater
|
84
|
-
resource.reload
|
85
|
-
end.to not_change(resource, :email).from(resource.email).and(
|
86
|
-
not_change(resource, :uid).from(resource.uid)
|
87
|
-
).and(
|
88
|
-
change(resource, :unconfirmed_email).from(nil).to('new@gmail.com')
|
89
|
-
).and(
|
90
|
-
change(resource, :name).from(resource.name).to('Updated Name')
|
91
|
-
)
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'sends out a confirmation email to the unconfirmed_email' do
|
95
|
-
expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
132
|
+
context 'when no confirmation url is provided is provided' do
|
133
|
+
context 'when schema_url is provided' do
|
134
|
+
let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name', schema_url: 'http://localhost/test' } }
|
96
135
|
|
97
|
-
email
|
98
|
-
|
99
|
-
end
|
136
|
+
it 'uses DTA default_confirm_success_url on the email with redirect flow' do
|
137
|
+
expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
100
138
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
it 'updates attributes and does not send confirmation email' do
|
105
|
-
expect do
|
106
|
-
updater
|
107
|
-
resource.reload
|
108
|
-
end.to change(resource, :name).from(resource.name).to('changed').and(
|
109
|
-
not_change(resource, :email).from(resource.email)
|
110
|
-
).and(
|
111
|
-
not_change(ActionMailer::Base.deliveries, :count).from(0)
|
112
|
-
)
|
139
|
+
email = ActionMailer::Base.deliveries.first
|
140
|
+
expect(email.body.decoded).to include(CGI.escape('https://google.com'))
|
141
|
+
expect(email.body.decoded).to include(CGI.escape('ConfirmAccount('))
|
113
142
|
end
|
114
143
|
end
|
115
144
|
|
116
|
-
context 'when
|
117
|
-
let(:attributes) { { email: '
|
145
|
+
context 'when schema_url is not provided' do
|
146
|
+
let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name' } }
|
118
147
|
|
119
|
-
it '
|
120
|
-
expect
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
)
|
148
|
+
it 'uses DTA default_confirm_success_url on the email and new confirmation flow' do
|
149
|
+
expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
150
|
+
|
151
|
+
email = ActionMailer::Base.deliveries.first
|
152
|
+
expect(email.body.decoded).to include(CGI.escape('https://google.com'))
|
153
|
+
expect(email.body.decoded).to include('?confirmationToken=')
|
125
154
|
end
|
126
155
|
end
|
127
156
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Registration confirmation with token' do
|
6
|
+
include_context 'with graphql query request'
|
7
|
+
|
8
|
+
context 'when using the user model' do
|
9
|
+
let(:user) { create(:user, confirmed_at: nil) }
|
10
|
+
let(:query) do
|
11
|
+
<<-GRAPHQL
|
12
|
+
mutation {
|
13
|
+
userConfirmRegistrationWithToken(
|
14
|
+
confirmationToken: "#{token}"
|
15
|
+
) {
|
16
|
+
authenticatable {
|
17
|
+
email
|
18
|
+
name
|
19
|
+
}
|
20
|
+
credentials { client }
|
21
|
+
}
|
22
|
+
}
|
23
|
+
GRAPHQL
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when confirmation token is correct' do
|
27
|
+
let(:token) { user.confirmation_token }
|
28
|
+
|
29
|
+
before do
|
30
|
+
user.send_confirmation_instructions(
|
31
|
+
template_path: ['graphql_devise/mailer']
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'confirms the resource and returns credentials' do
|
36
|
+
expect do
|
37
|
+
post_request
|
38
|
+
user.reload
|
39
|
+
end.to(change(user, :confirmed_at).from(nil))
|
40
|
+
|
41
|
+
expect(json_response[:data][:userConfirmRegistrationWithToken]).to include(
|
42
|
+
authenticatable: { email: user.email, name: user.name },
|
43
|
+
credentials: { client: user.tokens.keys.first }
|
44
|
+
)
|
45
|
+
|
46
|
+
expect(user).to be_active_for_authentication
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when unconfirmed_email is present' do
|
50
|
+
let(:user) { create(:user, :confirmed, unconfirmed_email: 'vvega@wallaceinc.com') }
|
51
|
+
|
52
|
+
it 'confirms the unconfirmed email' do
|
53
|
+
expect do
|
54
|
+
post_request
|
55
|
+
user.reload
|
56
|
+
end.to change(user, :email).from(user.email).to('vvega@wallaceinc.com').and(
|
57
|
+
change(user, :unconfirmed_email).from('vvega@wallaceinc.com').to(nil)
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when reset password token is not found' do
|
64
|
+
let(:token) { "#{user.confirmation_token}-invalid" }
|
65
|
+
|
66
|
+
it 'does *NOT* confirm the user' do
|
67
|
+
expect do
|
68
|
+
post_request
|
69
|
+
user.reload
|
70
|
+
end.not_to change(user, :confirmed_at).from(nil)
|
71
|
+
|
72
|
+
expect(json_response[:errors]).to contain_exactly(
|
73
|
+
hash_including(
|
74
|
+
message: 'Invalid confirmation token. Please try again',
|
75
|
+
extensions: { code: 'USER_ERROR' }
|
76
|
+
)
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when using the admin model' do
|
83
|
+
let(:admin) { create(:admin, confirmed_at: nil) }
|
84
|
+
let(:query) do
|
85
|
+
<<-GRAPHQL
|
86
|
+
mutation {
|
87
|
+
adminConfirmRegistrationWithToken(
|
88
|
+
confirmationToken: "#{token}"
|
89
|
+
) {
|
90
|
+
authenticatable { email }
|
91
|
+
}
|
92
|
+
}
|
93
|
+
GRAPHQL
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when confirmation token is correct' do
|
97
|
+
let(:token) { admin.confirmation_token }
|
98
|
+
|
99
|
+
before do
|
100
|
+
admin.send_confirmation_instructions(
|
101
|
+
template_path: ['graphql_devise/mailer']
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'confirms the resource and persists credentials on the DB' do
|
106
|
+
expect do
|
107
|
+
get_request
|
108
|
+
admin.reload
|
109
|
+
end.to change(admin, :confirmed_at).from(nil).and(
|
110
|
+
change { admin.tokens.keys.count }.from(0).to(1)
|
111
|
+
)
|
112
|
+
|
113
|
+
expect(admin).to be_active_for_authentication
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Registration 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
|
+
userRegister(
|
18
|
+
email: "#{email}"
|
19
|
+
name: "#{name}"
|
20
|
+
password: "#{password}"
|
21
|
+
passwordConfirmation: "#{password}"
|
22
|
+
confirmUrl: "#{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][:userRegister]).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
|
+
confirm_link = email.css('a').first['href']
|
74
|
+
confirm_token = confirm_link.match(/\?confirmationToken\=(?<token>.+)\z/)[:token]
|
75
|
+
|
76
|
+
expect(User.confirm_by_token(confirm_token)).to eq(user)
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when email address uses different casing' do
|
80
|
+
let(:email) { 'miaWallace@wallaceinc.com' }
|
81
|
+
|
82
|
+
it 'honors devise configuration for case insensitive fields' do
|
83
|
+
expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
84
|
+
expect(User.last.email).to eq('miawallace@wallaceinc.com')
|
85
|
+
expect(json_response[:data][:userRegister]).to include(user: { email: 'miawallace@wallaceinc.com', name: name })
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when required params are missing' do
|
91
|
+
let(:email) { '' }
|
92
|
+
|
93
|
+
it 'does *NOT* create resource a resource nor send an email' do
|
94
|
+
expect { post_request }.to(
|
95
|
+
not_change(User, :count)
|
96
|
+
.and(not_change(ActionMailer::Base.deliveries, :count))
|
97
|
+
)
|
98
|
+
|
99
|
+
expect(json_response[:data][:userRegister]).to be_nil
|
100
|
+
expect(json_response[:errors]).to containing_exactly(
|
101
|
+
hash_including(
|
102
|
+
message: "User couldn't be registered",
|
103
|
+
extensions: { code: 'USER_ERROR', detailed_errors: ["Email can't be blank"] }
|
104
|
+
)
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when using the admin model' do
|
111
|
+
let(:query) do
|
112
|
+
<<-GRAPHQL
|
113
|
+
mutation {
|
114
|
+
adminRegister(
|
115
|
+
email: "#{email}"
|
116
|
+
password: "#{password}"
|
117
|
+
passwordConfirmation: "#{password}"
|
118
|
+
) {
|
119
|
+
authenticatable {
|
120
|
+
email
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
GRAPHQL
|
125
|
+
end
|
126
|
+
|
127
|
+
before { post_request }
|
128
|
+
|
129
|
+
it 'skips the register mutation' do
|
130
|
+
expect(json_response[:errors]).to contain_exactly(
|
131
|
+
hash_including(message: "Field 'adminRegister' doesn't exist on type 'Mutation'")
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'when using the guest model' do
|
137
|
+
let(:query) do
|
138
|
+
<<-GRAPHQL
|
139
|
+
mutation {
|
140
|
+
guestRegister(
|
141
|
+
email: "#{email}"
|
142
|
+
password: "#{password}"
|
143
|
+
passwordConfirmation: "#{password}"
|
144
|
+
) {
|
145
|
+
credentials { accessToken client uid }
|
146
|
+
authenticatable {
|
147
|
+
email
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
GRAPHQL
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'returns credentials as no confirmation is required' do
|
155
|
+
expect { post_request }.to change(Guest, :count).from(0).to(1)
|
156
|
+
|
157
|
+
expect(json_response[:data][:guestRegister]).to include(
|
158
|
+
authenticatable: { email: email },
|
159
|
+
credentials: hash_including(
|
160
|
+
uid: email,
|
161
|
+
client: Guest.last.tokens.keys.first
|
162
|
+
)
|
163
|
+
)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|