]> cat aescling's git repositories - mastodon.git/blob - spec/models/user_spec.rb
Update Mastodon to Rails 6.1 (#15910)
[mastodon.git] / spec / models / user_spec.rb
1 require 'rails_helper'
2 require 'devise_two_factor/spec_helpers'
3
4 RSpec.describe User, type: :model do
5 it_behaves_like 'two_factor_backupable'
6
7 describe 'otp_secret' do
8 it 'is encrypted with OTP_SECRET environment variable' do
9 user = Fabricate(:user,
10 encrypted_otp_secret: "Fttsy7QAa0edaDfdfSz094rRLAxc8cJweDQ4BsWH/zozcdVA8o9GLqcKhn2b\nGi/V\n",
11 encrypted_otp_secret_iv: 'rys3THICkr60BoWC',
12 encrypted_otp_secret_salt: '_LMkAGvdg7a+sDIKjI3mR2Q==')
13
14 expect(user.otp_secret).to eq 'anotpsecretthatshouldbeencrypted'
15 end
16 end
17
18 describe 'validations' do
19 it 'is invalid without an account' do
20 user = Fabricate.build(:user, account: nil)
21 user.valid?
22 expect(user).to model_have_error_on_field(:account)
23 end
24
25 it 'is invalid without a valid locale' do
26 user = Fabricate.build(:user, locale: 'toto')
27 user.valid?
28 expect(user).to model_have_error_on_field(:locale)
29 end
30
31 it 'is invalid without a valid email' do
32 user = Fabricate.build(:user, email: 'john@')
33 user.valid?
34 expect(user).to model_have_error_on_field(:email)
35 end
36
37 it 'is valid with an invalid e-mail that has already been saved' do
38 user = Fabricate.build(:user, email: 'invalid-email')
39 user.save(validate: false)
40 expect(user.valid?).to be true
41 end
42
43 it 'cleans out empty string from languages' do
44 user = Fabricate.build(:user, chosen_languages: [''])
45 user.valid?
46 expect(user.chosen_languages).to eq nil
47 end
48 end
49
50 describe 'scopes' do
51 describe 'recent' do
52 it 'returns an array of recent users ordered by id' do
53 user_1 = Fabricate(:user)
54 user_2 = Fabricate(:user)
55 expect(User.recent).to eq [user_2, user_1]
56 end
57 end
58
59 describe 'admins' do
60 it 'returns an array of users who are admin' do
61 user_1 = Fabricate(:user, admin: false)
62 user_2 = Fabricate(:user, admin: true)
63 expect(User.admins).to match_array([user_2])
64 end
65 end
66
67 describe 'confirmed' do
68 it 'returns an array of users who are confirmed' do
69 user_1 = Fabricate(:user, confirmed_at: nil)
70 user_2 = Fabricate(:user, confirmed_at: Time.zone.now)
71 expect(User.confirmed).to match_array([user_2])
72 end
73 end
74
75 describe 'inactive' do
76 it 'returns a relation of inactive users' do
77 specified = Fabricate(:user, current_sign_in_at: 15.days.ago)
78 Fabricate(:user, current_sign_in_at: 6.days.ago)
79
80 expect(User.inactive).to match_array([specified])
81 end
82 end
83
84 describe 'matches_email' do
85 it 'returns a relation of users whose email starts with the given string' do
86 specified = Fabricate(:user, email: 'specified@spec')
87 Fabricate(:user, email: 'unspecified@spec')
88
89 expect(User.matches_email('specified')).to match_array([specified])
90 end
91 end
92 end
93
94 let(:account) { Fabricate(:account, username: 'alice') }
95 let(:password) { 'abcd1234' }
96
97 describe 'blacklist' do
98 around(:each) do |example|
99 old_blacklist = Rails.configuration.x.email_blacklist
100
101 Rails.configuration.x.email_domains_blacklist = 'mvrht.com'
102
103 example.run
104
105 Rails.configuration.x.email_domains_blacklist = old_blacklist
106 end
107
108 it 'should allow a non-blacklisted user to be created' do
109 user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
110
111 expect(user.valid?).to be_truthy
112 end
113
114 it 'should not allow a blacklisted user to be created' do
115 user = User.new(email: 'foo@mvrht.com', account: account, password: password, agreement: true)
116
117 expect(user.valid?).to be_falsey
118 end
119
120 it 'should not allow a subdomain blacklisted user to be created' do
121 user = User.new(email: 'foo@mvrht.com.topdomain.tld', account: account, password: password, agreement: true)
122
123 expect(user.valid?).to be_falsey
124 end
125 end
126
127 describe '#confirmed?' do
128 it 'returns true when a confirmed_at is set' do
129 user = Fabricate.build(:user, confirmed_at: Time.now.utc)
130 expect(user.confirmed?).to be true
131 end
132
133 it 'returns false if a confirmed_at is nil' do
134 user = Fabricate.build(:user, confirmed_at: nil)
135 expect(user.confirmed?).to be false
136 end
137 end
138
139 describe '#confirm' do
140 it 'sets email to unconfirmed_email' do
141 user = Fabricate.build(:user, confirmed_at: Time.now.utc, unconfirmed_email: 'new-email@example.com')
142 user.confirm
143 expect(user.email).to eq 'new-email@example.com'
144 end
145 end
146
147 describe '#disable_two_factor!' do
148 it 'saves false for otp_required_for_login' do
149 user = Fabricate.build(:user, otp_required_for_login: true)
150 user.disable_two_factor!
151 expect(user.reload.otp_required_for_login).to be false
152 end
153
154 it 'saves nil for otp_secret' do
155 user = Fabricate.build(:user, otp_secret: 'oldotpcode')
156 user.disable_two_factor!
157 expect(user.reload.otp_secret).to be nil
158 end
159
160 it 'saves cleared otp_backup_codes' do
161 user = Fabricate.build(:user, otp_backup_codes: %w(dummy dummy))
162 user.disable_two_factor!
163 expect(user.reload.otp_backup_codes.empty?).to be true
164 end
165 end
166
167 describe '#send_confirmation_instructions' do
168 around do |example|
169 queue_adapter = ActiveJob::Base.queue_adapter
170 example.run
171 ActiveJob::Base.queue_adapter = queue_adapter
172 end
173
174 it 'delivers confirmation instructions later' do
175 user = Fabricate(:user)
176 ActiveJob::Base.queue_adapter = :test
177
178 expect { user.send_confirmation_instructions }.to have_enqueued_job(ActionMailer::MailDeliveryJob)
179 end
180 end
181
182 describe 'settings' do
183 it 'is instance of Settings::ScopedSettings' do
184 user = Fabricate(:user)
185 expect(user.settings).to be_kind_of Settings::ScopedSettings
186 end
187 end
188
189 describe '#setting_default_privacy' do
190 it 'returns default privacy setting if user has configured' do
191 user = Fabricate(:user)
192 user.settings[:default_privacy] = 'unlisted'
193 expect(user.setting_default_privacy).to eq 'unlisted'
194 end
195
196 it "returns 'private' if user has not configured default privacy setting and account is locked" do
197 user = Fabricate(:user, account: Fabricate(:account, locked: true))
198 expect(user.setting_default_privacy).to eq 'private'
199 end
200
201 it "returns 'public' if user has not configured default privacy setting and account is not locked" do
202 user = Fabricate(:user, account: Fabricate(:account, locked: false))
203 expect(user.setting_default_privacy).to eq 'public'
204 end
205 end
206
207 describe 'whitelist' do
208 around(:each) do |example|
209 old_whitelist = Rails.configuration.x.email_domains_whitelist
210
211 Rails.configuration.x.email_domains_whitelist = 'mastodon.space'
212
213 example.run
214
215 Rails.configuration.x.email_domains_whitelist = old_whitelist
216 end
217
218 it 'should not allow a user to be created unless they are whitelisted' do
219 user = User.new(email: 'foo@example.com', account: account, password: password, agreement: true)
220 expect(user.valid?).to be_falsey
221 end
222
223 it 'should allow a user to be created if they are whitelisted' do
224 user = User.new(email: 'foo@mastodon.space', account: account, password: password, agreement: true)
225 expect(user.valid?).to be_truthy
226 end
227
228 it 'should not allow a user with a whitelisted top domain as subdomain in their email address to be created' do
229 user = User.new(email: 'foo@mastodon.space.userdomain.com', account: account, password: password, agreement: true)
230 expect(user.valid?).to be_falsey
231 end
232
233 context do
234 around do |example|
235 old_blacklist = Rails.configuration.x.email_blacklist
236 example.run
237 Rails.configuration.x.email_domains_blacklist = old_blacklist
238 end
239
240 it 'should not allow a user to be created with a specific blacklisted subdomain even if the top domain is whitelisted' do
241 Rails.configuration.x.email_domains_blacklist = 'blacklisted.mastodon.space'
242
243 user = User.new(email: 'foo@blacklisted.mastodon.space', account: account, password: password)
244 expect(user.valid?).to be_falsey
245 end
246 end
247 end
248
249 it_behaves_like 'Settings-extended' do
250 def create!
251 User.create!(account: Fabricate(:account), email: 'foo@mastodon.space', password: 'abcd1234', agreement: true)
252 end
253
254 def fabricate
255 Fabricate(:user)
256 end
257 end
258
259 describe 'token_for_app' do
260 let(:user) { Fabricate(:user) }
261 let(:app) { Fabricate(:application, owner: user) }
262
263 it 'returns a token' do
264 expect(user.token_for_app(app)).to be_a(Doorkeeper::AccessToken)
265 end
266
267 it 'persists a token' do
268 t = user.token_for_app(app)
269 expect(user.token_for_app(app)).to eql(t)
270 end
271
272 it 'is nil if user does not own app' do
273 app.update!(owner: nil)
274
275 expect(user.token_for_app(app)).to be_nil
276 end
277 end
278
279 describe '#role' do
280 it 'returns admin for admin' do
281 user = User.new(admin: true)
282 expect(user.role).to eq 'admin'
283 end
284
285 it 'returns moderator for moderator' do
286 user = User.new(moderator: true)
287 expect(user.role).to eq 'moderator'
288 end
289
290 it 'returns user otherwise' do
291 user = User.new
292 expect(user.role).to eq 'user'
293 end
294 end
295
296 describe '#role?' do
297 it 'returns false when invalid role requested' do
298 user = User.new(admin: true)
299 expect(user.role?('disabled')).to be false
300 end
301
302 it 'returns true when exact role match' do
303 user = User.new
304 mod = User.new(moderator: true)
305 admin = User.new(admin: true)
306
307 expect(user.role?('user')).to be true
308 expect(mod.role?('moderator')).to be true
309 expect(admin.role?('admin')).to be true
310 end
311
312 it 'returns true when role higher than needed' do
313 mod = User.new(moderator: true)
314 admin = User.new(admin: true)
315
316 expect(mod.role?('user')).to be true
317 expect(admin.role?('user')).to be true
318 expect(admin.role?('moderator')).to be true
319 end
320 end
321
322 describe '#disable!' do
323 subject(:user) { Fabricate(:user, disabled: false, current_sign_in_at: current_sign_in_at, last_sign_in_at: nil) }
324 let(:current_sign_in_at) { Time.zone.now }
325
326 before do
327 user.disable!
328 end
329
330 it 'disables user' do
331 expect(user).to have_attributes(disabled: true)
332 end
333 end
334
335 describe '#enable!' do
336 subject(:user) { Fabricate(:user, disabled: true) }
337
338 before do
339 user.enable!
340 end
341
342 it 'enables user' do
343 expect(user).to have_attributes(disabled: false)
344 end
345 end
346
347 describe '#confirm!' do
348 subject(:user) { Fabricate(:user, confirmed_at: confirmed_at) }
349
350 before do
351 ActionMailer::Base.deliveries.clear
352 user.confirm!
353 end
354
355 after { ActionMailer::Base.deliveries.clear }
356
357 context 'when user is new' do
358 let(:confirmed_at) { nil }
359
360 it 'confirms user' do
361 expect(user.confirmed_at).to be_present
362 end
363
364 it 'delivers mails' do
365 expect(ActionMailer::Base.deliveries.count).to eq 2
366 end
367 end
368
369 context 'when user is not new' do
370 let(:confirmed_at) { Time.zone.now }
371
372 it 'confirms user' do
373 expect(user.confirmed_at).to be_present
374 end
375
376 it 'does not deliver mail' do
377 expect(ActionMailer::Base.deliveries.count).to eq 0
378 end
379 end
380 end
381
382 describe '#promote!' do
383 subject(:user) { Fabricate(:user, admin: is_admin, moderator: is_moderator) }
384
385 before do
386 user.promote!
387 end
388
389 context 'when user is an admin' do
390 let(:is_admin) { true }
391
392 context 'when user is a moderator' do
393 let(:is_moderator) { true }
394
395 it 'changes moderator filed false' do
396 expect(user).to be_admin
397 expect(user).not_to be_moderator
398 end
399 end
400
401 context 'when user is not a moderator' do
402 let(:is_moderator) { false }
403
404 it 'does not change status' do
405 expect(user).to be_admin
406 expect(user).not_to be_moderator
407 end
408 end
409 end
410
411 context 'when user is not admin' do
412 let(:is_admin) { false }
413
414 context 'when user is a moderator' do
415 let(:is_moderator) { true }
416
417 it 'changes user into an admin' do
418 expect(user).to be_admin
419 expect(user).not_to be_moderator
420 end
421 end
422
423 context 'when user is not a moderator' do
424 let(:is_moderator) { false }
425
426 it 'changes user into a moderator' do
427 expect(user).not_to be_admin
428 expect(user).to be_moderator
429 end
430 end
431 end
432 end
433
434 describe '#demote!' do
435 subject(:user) { Fabricate(:user, admin: admin, moderator: moderator) }
436
437 before do
438 user.demote!
439 end
440
441 context 'when user is an admin' do
442 let(:admin) { true }
443
444 context 'when user is a moderator' do
445 let(:moderator) { true }
446
447 it 'changes user into a moderator' do
448 expect(user).not_to be_admin
449 expect(user).to be_moderator
450 end
451 end
452
453 context 'when user is not a moderator' do
454 let(:moderator) { false }
455
456 it 'changes user into a moderator' do
457 expect(user).not_to be_admin
458 expect(user).to be_moderator
459 end
460 end
461 end
462
463 context 'when user is not an admin' do
464 let(:admin) { false }
465
466 context 'when user is a moderator' do
467 let(:moderator) { true }
468
469 it 'changes user into a plain user' do
470 expect(user).not_to be_admin
471 expect(user).not_to be_moderator
472 end
473 end
474
475 context 'when user is not a moderator' do
476 let(:moderator) { false }
477
478 it 'does not change any fields' do
479 expect(user).not_to be_admin
480 expect(user).not_to be_moderator
481 end
482 end
483 end
484 end
485
486 describe '#active_for_authentication?' do
487 subject { user.active_for_authentication? }
488 let(:user) { Fabricate(:user, disabled: disabled, confirmed_at: confirmed_at) }
489
490 context 'when user is disabled' do
491 let(:disabled) { true }
492
493 context 'when user is confirmed' do
494 let(:confirmed_at) { Time.zone.now }
495
496 it { is_expected.to be true }
497 end
498
499 context 'when user is not confirmed' do
500 let(:confirmed_at) { nil }
501
502 it { is_expected.to be true }
503 end
504 end
505
506 context 'when user is not disabled' do
507 let(:disabled) { false }
508
509 context 'when user is confirmed' do
510 let(:confirmed_at) { Time.zone.now }
511
512 it { is_expected.to be true }
513 end
514
515 context 'when user is not confirmed' do
516 let(:confirmed_at) { nil }
517
518 it { is_expected.to be true }
519 end
520 end
521 end
522 end
This page took 0.184406 seconds and 4 git commands to generate.