graphql_devise 0.14.1 → 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/.circleci/config.yml +118 -0
- data/Appraisals +26 -6
- data/CHANGELOG.md +72 -6
- data/README.md +184 -69
- data/Rakefile +2 -1
- data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +72 -0
- data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +5 -27
- data/app/controllers/graphql_devise/graphql_controller.rb +1 -1
- data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
- data/app/models/graphql_devise/concerns/additional_model_methods.rb +21 -0
- data/app/models/graphql_devise/concerns/model.rb +6 -9
- data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +7 -1
- data/graphql_devise.gemspec +1 -1
- data/lib/generators/graphql_devise/install_generator.rb +1 -1
- data/lib/graphql_devise.rb +20 -6
- data/lib/graphql_devise/concerns/controller_methods.rb +3 -3
- 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_preparer.rb +6 -6
- data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +6 -4
- data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +7 -5
- data/lib/graphql_devise/mount_method/operation_preparers/{resource_name_setter.rb → resource_klass_setter.rb} +4 -4
- 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/resolvers/confirm_account.rb +1 -1
- data/lib/graphql_devise/resource_loader.rb +26 -11
- data/lib/graphql_devise/schema_plugin.rb +31 -10
- data/lib/graphql_devise/version.rb +1 -1
- data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +13 -2
- data/spec/dummy/app/graphql/dummy_schema.rb +8 -6
- data/spec/dummy/app/graphql/mutations/register.rb +14 -0
- data/spec/dummy/app/graphql/types/query_type.rb +5 -0
- data/spec/dummy/config/routes.rb +7 -5
- data/spec/dummy/db/migrate/20200623003142_create_schema_users.rb +0 -1
- data/spec/dummy/db/migrate/20210516211417_add_vip_to_users.rb +5 -0
- data/spec/dummy/db/schema.rb +4 -4
- data/spec/generators/graphql_devise/install_generator_spec.rb +1 -1
- data/spec/graphql/user_queries_spec.rb +3 -1
- data/spec/graphql_devise/model/with_email_updater_spec.rb +97 -68
- data/spec/requests/graphql_controller_spec.rb +12 -11
- 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/requests/queries/introspection_query_spec.rb +149 -0
- data/spec/requests/user_controller_spec.rb +86 -25
- data/spec/services/mount_method/operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/{resource_name_setter_spec.rb → resource_klass_setter_spec.rb} +6 -6
- data/spec/services/mount_method/operation_sanitizer_spec.rb +3 -3
- data/spec/services/resource_loader_spec.rb +5 -5
- data/spec/support/contexts/graphql_request.rb +11 -3
- metadata +29 -12
- data/.travis.yml +0 -86
@@ -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
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Resend confirmation with token' 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(:confirm_url) { 'https://google.com' }
|
13
|
+
let(:query) do
|
14
|
+
<<-GRAPHQL
|
15
|
+
mutation {
|
16
|
+
userResendConfirmationWithToken(
|
17
|
+
email:"#{email}",
|
18
|
+
confirmUrl:"#{confirm_url}"
|
19
|
+
) {
|
20
|
+
message
|
21
|
+
}
|
22
|
+
}
|
23
|
+
GRAPHQL
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when confirm_url is not whitelisted' do
|
27
|
+
let(:confirm_url) { 'https://not-safe.com' }
|
28
|
+
|
29
|
+
it 'returns a not whitelisted confirm 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 '#{confirm_url}' 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][:userResendConfirmationWithToken]).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
|
+
confirm_link = email.css('a').first['href']
|
51
|
+
confirm_token = confirm_link.match(/\?confirmationToken\=(?<token>.+)\z/)[:token]
|
52
|
+
|
53
|
+
expect(User.confirm_by_token(confirm_token)).to eq(user)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when using a custom schema' do
|
58
|
+
let(:custom_path) { '/api/v1/graphql' }
|
59
|
+
|
60
|
+
it 'sends an email to the user with confirmation url and returns a success message' do
|
61
|
+
expect { post_request(custom_path) }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
62
|
+
expect(json_response[:data][:userResendConfirmationWithToken]).to include(
|
63
|
+
message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
|
64
|
+
)
|
65
|
+
|
66
|
+
email = Nokogiri::HTML(ActionMailer::Base.deliveries.last.body.encoded)
|
67
|
+
confirm_link = email.css('a').first['href']
|
68
|
+
confirm_token = confirm_link.match(/\?confirmationToken\=(?<token>.+)\z/)[:token]
|
69
|
+
|
70
|
+
expect(User.confirm_by_token(confirm_token)).to eq(user)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when email address uses different casing' do
|
75
|
+
let(:email) { 'mWallace@wallaceinc.com' }
|
76
|
+
|
77
|
+
it 'honors devise configuration for case insensitive fields' do
|
78
|
+
expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
79
|
+
expect(json_response[:data][:userResendConfirmationWithToken]).to include(
|
80
|
+
message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
|
81
|
+
)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when the user has already been confirmed' do
|
86
|
+
before { user.confirm }
|
87
|
+
|
88
|
+
it 'does *NOT* send an email and raises an error' do
|
89
|
+
expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
|
90
|
+
expect(json_response[:data][:userResendConfirmationWithToken]).to be_nil
|
91
|
+
expect(json_response[:errors]).to contain_exactly(
|
92
|
+
hash_including(
|
93
|
+
message: 'Email was already confirmed, please try signing in',
|
94
|
+
extensions: { code: 'USER_ERROR' }
|
95
|
+
)
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when the email was changed' do
|
102
|
+
let(:confirmed_at) { 2.seconds.ago }
|
103
|
+
let(:email) { 'new-email@wallaceinc.com' }
|
104
|
+
let(:new_email) { email }
|
105
|
+
|
106
|
+
before do
|
107
|
+
user.update_with_email(
|
108
|
+
email: new_email,
|
109
|
+
schema_url: 'http://localhost/test',
|
110
|
+
confirmation_success_url: 'https://google.com'
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'sends new confirmation email' do
|
115
|
+
expect { post_request }.to change(ActionMailer::Base.deliveries, :count).by(1)
|
116
|
+
expect(ActionMailer::Base.deliveries.first.to).to contain_exactly(new_email)
|
117
|
+
expect(json_response[:data][:userResendConfirmationWithToken]).to include(
|
118
|
+
message: 'You will receive an email with instructions for how to confirm your email address in a few minutes.'
|
119
|
+
)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when the email isn't in the system" do
|
124
|
+
let(:email) { 'notthere@gmail.com' }
|
125
|
+
|
126
|
+
it 'does *NOT* send an email and raises an error' do
|
127
|
+
expect { post_request }.to not_change(ActionMailer::Base.deliveries, :count)
|
128
|
+
expect(json_response[:data][:userResendConfirmationWithToken]).to be_nil
|
129
|
+
expect(json_response[:errors]).to contain_exactly(
|
130
|
+
hash_including(
|
131
|
+
message: "Unable to find user with email '#{email}'.",
|
132
|
+
extensions: { code: 'USER_ERROR' }
|
133
|
+
)
|
134
|
+
)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Login Requests' do
|
6
|
+
include_context 'with graphql query request'
|
7
|
+
|
8
|
+
let(:query) do
|
9
|
+
<<-GRAPHQL
|
10
|
+
query IntrospectionQuery {
|
11
|
+
__schema {
|
12
|
+
queryType { name }
|
13
|
+
mutationType { name }
|
14
|
+
subscriptionType { name }
|
15
|
+
types {
|
16
|
+
...FullType
|
17
|
+
}
|
18
|
+
directives {
|
19
|
+
name
|
20
|
+
description
|
21
|
+
args {
|
22
|
+
...InputValue
|
23
|
+
}
|
24
|
+
onOperation
|
25
|
+
onFragment
|
26
|
+
onField
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
fragment FullType on __Type {
|
32
|
+
kind
|
33
|
+
name
|
34
|
+
description
|
35
|
+
fields(includeDeprecated: true) {
|
36
|
+
name
|
37
|
+
description
|
38
|
+
args {
|
39
|
+
...InputValue
|
40
|
+
}
|
41
|
+
type {
|
42
|
+
...TypeRef
|
43
|
+
}
|
44
|
+
isDeprecated
|
45
|
+
deprecationReason
|
46
|
+
}
|
47
|
+
inputFields {
|
48
|
+
...InputValue
|
49
|
+
}
|
50
|
+
interfaces {
|
51
|
+
...TypeRef
|
52
|
+
}
|
53
|
+
enumValues(includeDeprecated: true) {
|
54
|
+
name
|
55
|
+
description
|
56
|
+
isDeprecated
|
57
|
+
deprecationReason
|
58
|
+
}
|
59
|
+
possibleTypes {
|
60
|
+
...TypeRef
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
fragment InputValue on __InputValue {
|
65
|
+
name
|
66
|
+
description
|
67
|
+
type { ...TypeRef }
|
68
|
+
defaultValue
|
69
|
+
}
|
70
|
+
|
71
|
+
fragment TypeRef on __Type {
|
72
|
+
kind
|
73
|
+
name
|
74
|
+
ofType {
|
75
|
+
kind
|
76
|
+
name
|
77
|
+
ofType {
|
78
|
+
kind
|
79
|
+
name
|
80
|
+
ofType {
|
81
|
+
kind
|
82
|
+
name
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
GRAPHQL
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when using a schema plugin to mount devise operations' do
|
92
|
+
context 'when schema plugin is set to authenticate by default' do
|
93
|
+
context 'when the resource is authenticated' do
|
94
|
+
let(:user) { create(:user, :confirmed) }
|
95
|
+
let(:headers) { user.create_new_auth_token }
|
96
|
+
|
97
|
+
it 'return the schema information' do
|
98
|
+
post_request('/api/v1/graphql')
|
99
|
+
|
100
|
+
expect(json_response[:data][:__schema].keys).to contain_exactly(
|
101
|
+
:queryType, :mutationType, :subscriptionType, :types, :directives
|
102
|
+
)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when the resource is *NOT* authenticated' do
|
107
|
+
context 'and instrospection is set to be public' do
|
108
|
+
it 'return the schema information' do
|
109
|
+
post_request('/api/v1/graphql')
|
110
|
+
|
111
|
+
expect(json_response[:data][:__schema].keys).to contain_exactly(
|
112
|
+
:queryType, :mutationType, :subscriptionType, :types, :directives
|
113
|
+
)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'and introspection is set to require auth' do
|
118
|
+
before do
|
119
|
+
allow_any_instance_of(GraphqlDevise::SchemaPlugin).to(
|
120
|
+
receive(:public_introspection).and_return(false)
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'return an error' do
|
125
|
+
post_request('/api/v1/graphql')
|
126
|
+
|
127
|
+
expect(json_response[:data]).to be_nil
|
128
|
+
expect(json_response[:errors]).to contain_exactly(
|
129
|
+
hash_including(
|
130
|
+
message: '__schema field requires authentication',
|
131
|
+
extensions: { code: 'AUTHENTICATION_ERROR' }
|
132
|
+
)
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when schema plugin is set *NOT* to authenticate by default' do
|
140
|
+
it 'return the schema information' do
|
141
|
+
post_request('/api/v1/interpreter')
|
142
|
+
|
143
|
+
expect(json_response[:data][:__schema].keys).to contain_exactly(
|
144
|
+
:queryType, :mutationType, :subscriptionType, :types, :directives
|
145
|
+
)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|