1# frozen_string_literal: true
2
3require 'spec_helper'
4
5RSpec.describe User do
6  include ProjectForksHelper
7  include TermsHelper
8  include ExclusiveLeaseHelpers
9  include LdapHelpers
10
11  it_behaves_like 'having unique enum values'
12
13  describe 'modules' do
14    subject { described_class }
15
16    it { is_expected.to include_module(Gitlab::ConfigHelper) }
17    it { is_expected.to include_module(Referable) }
18    it { is_expected.to include_module(Sortable) }
19    it { is_expected.to include_module(TokenAuthenticatable) }
20    it { is_expected.to include_module(BlocksJsonSerialization) }
21    it { is_expected.to include_module(AsyncDeviseEmail) }
22  end
23
24  describe 'constants' do
25    it { expect(described_class::COUNT_CACHE_VALIDITY_PERIOD).to be_a(Integer) }
26    it { expect(described_class::MAX_USERNAME_LENGTH).to be_a(Integer) }
27    it { expect(described_class::MIN_USERNAME_LENGTH).to be_a(Integer) }
28  end
29
30  describe 'delegations' do
31    it { is_expected.to delegate_method(:path).to(:namespace).with_prefix }
32
33    it { is_expected.to delegate_method(:notes_filter_for).to(:user_preference) }
34    it { is_expected.to delegate_method(:set_notes_filter).to(:user_preference) }
35
36    it { is_expected.to delegate_method(:first_day_of_week).to(:user_preference) }
37    it { is_expected.to delegate_method(:first_day_of_week=).to(:user_preference).with_arguments(:args) }
38
39    it { is_expected.to delegate_method(:timezone).to(:user_preference) }
40    it { is_expected.to delegate_method(:timezone=).to(:user_preference).with_arguments(:args) }
41
42    it { is_expected.to delegate_method(:time_display_relative).to(:user_preference) }
43    it { is_expected.to delegate_method(:time_display_relative=).to(:user_preference).with_arguments(:args) }
44
45    it { is_expected.to delegate_method(:time_format_in_24h).to(:user_preference) }
46    it { is_expected.to delegate_method(:time_format_in_24h=).to(:user_preference).with_arguments(:args) }
47
48    it { is_expected.to delegate_method(:show_whitespace_in_diffs).to(:user_preference) }
49    it { is_expected.to delegate_method(:show_whitespace_in_diffs=).to(:user_preference).with_arguments(:args) }
50
51    it { is_expected.to delegate_method(:view_diffs_file_by_file).to(:user_preference) }
52    it { is_expected.to delegate_method(:view_diffs_file_by_file=).to(:user_preference).with_arguments(:args) }
53
54    it { is_expected.to delegate_method(:tab_width).to(:user_preference) }
55    it { is_expected.to delegate_method(:tab_width=).to(:user_preference).with_arguments(:args) }
56
57    it { is_expected.to delegate_method(:sourcegraph_enabled).to(:user_preference) }
58    it { is_expected.to delegate_method(:sourcegraph_enabled=).to(:user_preference).with_arguments(:args) }
59
60    it { is_expected.to delegate_method(:gitpod_enabled).to(:user_preference) }
61    it { is_expected.to delegate_method(:gitpod_enabled=).to(:user_preference).with_arguments(:args) }
62
63    it { is_expected.to delegate_method(:setup_for_company).to(:user_preference) }
64    it { is_expected.to delegate_method(:setup_for_company=).to(:user_preference).with_arguments(:args) }
65
66    it { is_expected.to delegate_method(:render_whitespace_in_code).to(:user_preference) }
67    it { is_expected.to delegate_method(:render_whitespace_in_code=).to(:user_preference).with_arguments(:args) }
68
69    it { is_expected.to delegate_method(:markdown_surround_selection).to(:user_preference) }
70    it { is_expected.to delegate_method(:markdown_surround_selection=).to(:user_preference).with_arguments(:args) }
71
72    it { is_expected.to delegate_method(:job_title).to(:user_detail).allow_nil }
73    it { is_expected.to delegate_method(:job_title=).to(:user_detail).with_arguments(:args).allow_nil }
74
75    it { is_expected.to delegate_method(:pronouns).to(:user_detail).allow_nil }
76    it { is_expected.to delegate_method(:pronouns=).to(:user_detail).with_arguments(:args).allow_nil }
77
78    it { is_expected.to delegate_method(:pronunciation).to(:user_detail).allow_nil }
79    it { is_expected.to delegate_method(:pronunciation=).to(:user_detail).with_arguments(:args).allow_nil }
80
81    it { is_expected.to delegate_method(:bio).to(:user_detail).allow_nil }
82    it { is_expected.to delegate_method(:bio=).to(:user_detail).with_arguments(:args).allow_nil }
83
84    it { is_expected.to delegate_method(:registration_objective).to(:user_detail).allow_nil }
85    it { is_expected.to delegate_method(:registration_objective=).to(:user_detail).with_arguments(:args).allow_nil }
86  end
87
88  describe 'associations' do
89    it { is_expected.to have_one(:namespace) }
90    it { is_expected.to have_one(:status) }
91    it { is_expected.to have_one(:user_detail) }
92    it { is_expected.to have_one(:atlassian_identity) }
93    it { is_expected.to have_one(:user_highest_role) }
94    it { is_expected.to have_one(:credit_card_validation) }
95    it { is_expected.to have_one(:banned_user) }
96    it { is_expected.to have_many(:snippets).dependent(:destroy) }
97    it { is_expected.to have_many(:members) }
98    it { is_expected.to have_many(:project_members) }
99    it { is_expected.to have_many(:group_members) }
100    it { is_expected.to have_many(:groups) }
101    it { is_expected.to have_many(:keys).dependent(:destroy) }
102    it { is_expected.to have_many(:expired_today_and_unnotified_keys) }
103    it { is_expected.to have_many(:deploy_keys).dependent(:nullify) }
104    it { is_expected.to have_many(:group_deploy_keys) }
105    it { is_expected.to have_many(:events).dependent(:delete_all) }
106    it { is_expected.to have_many(:issues).dependent(:destroy) }
107    it { is_expected.to have_many(:notes).dependent(:destroy) }
108    it { is_expected.to have_many(:merge_requests).dependent(:destroy) }
109    it { is_expected.to have_many(:identities).dependent(:destroy) }
110    it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
111    it { is_expected.to have_many(:todos) }
112    it { is_expected.to have_many(:award_emoji).dependent(:destroy) }
113    it { is_expected.to have_many(:builds) }
114    it { is_expected.to have_many(:pipelines) }
115    it { is_expected.to have_many(:chat_names).dependent(:destroy) }
116    it { is_expected.to have_many(:uploads) }
117    it { is_expected.to have_many(:reported_abuse_reports).dependent(:destroy).class_name('AbuseReport') }
118    it { is_expected.to have_many(:custom_attributes).class_name('UserCustomAttribute') }
119    it { is_expected.to have_many(:releases).dependent(:nullify) }
120    it { is_expected.to have_many(:metrics_users_starred_dashboards).inverse_of(:user) }
121    it { is_expected.to have_many(:reviews).inverse_of(:author) }
122    it { is_expected.to have_many(:merge_request_assignees).inverse_of(:assignee) }
123    it { is_expected.to have_many(:merge_request_reviewers).inverse_of(:reviewer) }
124    it { is_expected.to have_many(:created_custom_emoji).inverse_of(:creator) }
125    it { is_expected.to have_many(:in_product_marketing_emails) }
126    it { is_expected.to have_many(:timelogs) }
127    it { is_expected.to have_many(:callouts).class_name('Users::Callout') }
128    it { is_expected.to have_many(:group_callouts).class_name('Users::GroupCallout') }
129
130    describe '#user_detail' do
131      it 'does not persist `user_detail` by default' do
132        expect(create(:user).user_detail).not_to be_persisted
133      end
134
135      it 'creates `user_detail` when `bio` is given' do
136        user = create(:user, bio: 'my bio')
137
138        expect(user.user_detail).to be_persisted
139        expect(user.user_detail.bio).to eq('my bio')
140      end
141
142      it 'delegates `bio` to `user_detail`' do
143        user = create(:user, bio: 'my bio')
144
145        expect(user.bio).to eq(user.user_detail.bio)
146      end
147
148      it 'delegates `pronouns` to `user_detail`' do
149        user = create(:user, pronouns: 'they/them')
150
151        expect(user.pronouns).to eq(user.user_detail.pronouns)
152      end
153
154      it 'delegates `pronunciation` to `user_detail`' do
155        user = create(:user, name: 'Example', pronunciation: 'uhg-zaam-pl')
156
157        expect(user.pronunciation).to eq(user.user_detail.pronunciation)
158      end
159
160      it 'creates `user_detail` when `bio` is first updated' do
161        user = create(:user)
162
163        expect { user.update!(bio: 'my bio') }.to change { user.user_detail.persisted? }.from(false).to(true)
164      end
165    end
166
167    describe '#abuse_report' do
168      let(:current_user) { create(:user) }
169      let(:other_user) { create(:user) }
170
171      it { is_expected.to have_one(:abuse_report) }
172
173      it 'refers to the abuse report whose user_id is the current user' do
174        abuse_report = create(:abuse_report, reporter: other_user, user: current_user)
175
176        expect(current_user.abuse_report).to eq(abuse_report)
177      end
178
179      it 'does not refer to the abuse report whose reporter_id is the current user' do
180        create(:abuse_report, reporter: current_user, user: other_user)
181
182        expect(current_user.abuse_report).to be_nil
183      end
184
185      it 'does not update the user_id of an abuse report when the user is updated' do
186        abuse_report = create(:abuse_report, reporter: current_user, user: other_user)
187
188        current_user.block
189
190        expect(abuse_report.reload.user).to eq(other_user)
191      end
192    end
193
194    describe '#group_members' do
195      it 'does not include group memberships for which user is a requester' do
196        user = create(:user)
197        group = create(:group, :public)
198        group.request_access(user)
199
200        expect(user.group_members).to be_empty
201      end
202    end
203
204    describe '#project_members' do
205      it 'does not include project memberships for which user is a requester' do
206        user = create(:user)
207        project = create(:project, :public)
208        project.request_access(user)
209
210        expect(user.project_members).to be_empty
211      end
212    end
213  end
214
215  describe 'Devise emails' do
216    let!(:user) { create(:user) }
217
218    describe 'behaviour' do
219      it 'sends emails asynchronously' do
220        expect do
221          user.update!(email: 'hello@hello.com')
222        end.to have_enqueued_job.on_queue('mailers').exactly(:twice)
223      end
224    end
225
226    context 'emails sent on changing password' do
227      context 'when password is updated' do
228        context 'default behaviour' do
229          it 'enqueues the `password changed` email' do
230            user.password = User.random_password
231
232            expect { user.save! }.to have_enqueued_mail(DeviseMailer, :password_change)
233          end
234
235          it 'does not enqueue the `admin changed your password` email' do
236            user.password = User.random_password
237
238            expect { user.save! }.not_to have_enqueued_mail(DeviseMailer, :password_change_by_admin)
239          end
240        end
241
242        context '`admin changed your password` email' do
243          it 'is enqueued only when explicitly allowed' do
244            user.password = User.random_password
245            user.send_only_admin_changed_your_password_notification!
246
247            expect { user.save! }.to have_enqueued_mail(DeviseMailer, :password_change_by_admin)
248          end
249
250          it '`password changed` email is not enqueued if it is explicitly allowed' do
251            user.password = User.random_password
252            user.send_only_admin_changed_your_password_notification!
253
254            expect { user.save! }.not_to have_enqueued_mail(DeviseMailer, :password_changed)
255          end
256
257          it 'is not enqueued if sending notifications on password updates is turned off as per Devise config' do
258            user.password = User.random_password
259            user.send_only_admin_changed_your_password_notification!
260
261            allow(Devise).to receive(:send_password_change_notification).and_return(false)
262
263            expect { user.save! }.not_to have_enqueued_mail(DeviseMailer, :password_change_by_admin)
264          end
265        end
266      end
267
268      context 'when password is not updated' do
269        it 'does not enqueue the `admin changed your password` email even if explicitly allowed' do
270          user.name = 'John'
271          user.send_only_admin_changed_your_password_notification!
272
273          expect { user.save! }.not_to have_enqueued_mail(DeviseMailer, :password_change_by_admin)
274        end
275      end
276    end
277  end
278
279  describe 'validations' do
280    describe 'password' do
281      let!(:user) { build_stubbed(:user) }
282
283      before do
284        allow(Devise).to receive(:password_length).and_return(8..128)
285        allow(described_class).to receive(:password_length).and_return(10..130)
286      end
287
288      context 'length' do
289        it { is_expected.to validate_length_of(:password).is_at_least(10).is_at_most(130) }
290      end
291
292      context 'length validator' do
293        context 'for a short password' do
294          before do
295            user.password = user.password_confirmation = 'abc'
296          end
297
298          it 'does not run the default Devise password length validation' do
299            expect(user).to be_invalid
300            expect(user.errors.full_messages.join).not_to include('is too short (minimum is 8 characters)')
301          end
302
303          it 'runs the custom password length validator' do
304            expect(user).to be_invalid
305            expect(user.errors.full_messages.join).to include('is too short (minimum is 10 characters)')
306          end
307        end
308
309        context 'for a long password' do
310          before do
311            user.password = user.password_confirmation = 'a' * 140
312          end
313
314          it 'does not run the default Devise password length validation' do
315            expect(user).to be_invalid
316            expect(user.errors.full_messages.join).not_to include('is too long (maximum is 128 characters)')
317          end
318
319          it 'runs the custom password length validator' do
320            expect(user).to be_invalid
321            expect(user.errors.full_messages.join).to include('is too long (maximum is 130 characters)')
322          end
323        end
324      end
325    end
326
327    describe 'name' do
328      it { is_expected.to validate_presence_of(:name) }
329      it { is_expected.to validate_length_of(:name).is_at_most(255) }
330    end
331
332    describe 'first name' do
333      it { is_expected.to validate_length_of(:first_name).is_at_most(127) }
334    end
335
336    describe 'last name' do
337      it { is_expected.to validate_length_of(:last_name).is_at_most(127) }
338    end
339
340    describe 'preferred_language' do
341      context 'when its value is nil in the database' do
342        let(:user) { build(:user, preferred_language: nil) }
343
344        it 'falls back to I18n.default_locale when empty in the database' do
345          expect(user.preferred_language).to eq I18n.default_locale.to_s
346        end
347
348        it 'falls back to english when I18n.default_locale is not an available language' do
349          I18n.default_locale = :kl
350          default_preferred_language = user.send(:default_preferred_language)
351
352          expect(user.preferred_language).to eq default_preferred_language
353        end
354      end
355    end
356
357    describe 'username' do
358      it 'validates presence' do
359        expect(subject).to validate_presence_of(:username)
360      end
361
362      it 'rejects denied names' do
363        user = build(:user, username: 'dashboard')
364
365        expect(user).not_to be_valid
366        expect(user.errors.messages[:username]).to eq ['dashboard is a reserved name']
367      end
368
369      it 'allows child names' do
370        user = build(:user, username: 'avatar')
371
372        expect(user).to be_valid
373      end
374
375      it 'allows wildcard names' do
376        user = build(:user, username: 'blob')
377
378        expect(user).to be_valid
379      end
380
381      context 'when username is changed' do
382        let(:user) { build_stubbed(:user, username: 'old_path', namespace: build_stubbed(:user_namespace)) }
383
384        it 'validates move_dir is allowed for the namespace' do
385          expect(user.namespace).to receive(:any_project_has_container_registry_tags?).and_return(true)
386          user.username = 'new_path'
387          expect(user).to be_invalid
388          expect(user.errors.messages[:username].first).to eq(_('cannot be changed if a personal project has container registry tags.'))
389        end
390      end
391
392      context 'when the username is in use by another user' do
393        let(:username) { 'foo' }
394        let!(:other_user) { create(:user, username: username) }
395
396        it 'is invalid' do
397          user = build(:user, username: username)
398
399          expect(user).not_to be_valid
400          expect(user.errors.full_messages).to eq(['Username has already been taken'])
401        end
402      end
403
404      it 'validates format' do
405        Mime::EXTENSION_LOOKUP.keys.each do |type|
406          user = build(:user, username: "test.#{type}")
407
408          expect(user).not_to be_valid
409          expect(user.errors.full_messages).to include('Username ending with a reserved file extension is not allowed.')
410          expect(build(:user, username: "test#{type}")).to be_valid
411        end
412      end
413
414      it 'validates format on updated record' do
415        expect(create(:user).update(username: 'profile.html')).to be_falsey
416      end
417    end
418
419    it 'has a DB-level NOT NULL constraint on projects_limit' do
420      user = create(:user)
421
422      expect(user.persisted?).to eq(true)
423
424      expect do
425        user.update_columns(projects_limit: nil)
426      end.to raise_error(ActiveRecord::StatementInvalid)
427    end
428
429    it { is_expected.to validate_presence_of(:projects_limit) }
430    it { is_expected.to validate_numericality_of(:projects_limit) }
431    it { is_expected.to allow_value(0).for(:projects_limit) }
432    it { is_expected.not_to allow_value(-1).for(:projects_limit) }
433    it { is_expected.not_to allow_value(Gitlab::Database::MAX_INT_VALUE + 1).for(:projects_limit) }
434
435    it_behaves_like 'an object with email-formatted attributes', :email do
436      subject { build(:user) }
437    end
438
439    it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :public_email, :notification_email do
440      subject { create(:user).tap { |user| user.emails << build(:email, email: email_value, confirmed_at: Time.current) } }
441    end
442
443    describe '#commit_email_or_default' do
444      subject(:user) { create(:user) }
445
446      it 'defaults to the primary email' do
447        expect(user.email).to be_present
448        expect(user.commit_email_or_default).to eq(user.email)
449      end
450
451      it 'defaults to the primary email when the column in the database is null' do
452        user.update_column(:commit_email, nil)
453
454        found_user = described_class.find_by(id: user.id)
455
456        expect(found_user.commit_email_or_default).to eq(user.email)
457      end
458
459      it 'returns the private commit email when commit_email has _private' do
460        user.update_column(:commit_email, Gitlab::PrivateCommitEmail::TOKEN)
461
462        expect(user.commit_email_or_default).to eq(user.private_commit_email)
463      end
464    end
465
466    describe '#commit_email=' do
467      subject(:user) { create(:user) }
468
469      it 'can be set to a confirmed email' do
470        confirmed = create(:email, :confirmed, user: user)
471        user.commit_email = confirmed.email
472
473        expect(user).to be_valid
474      end
475
476      it 'can not be set to an unconfirmed email' do
477        unconfirmed = create(:email, user: user)
478        user.commit_email = unconfirmed.email
479
480        expect(user).not_to be_valid
481      end
482
483      it 'can not be set to a non-existent email' do
484        user.commit_email = 'non-existent-email@nonexistent.nonexistent'
485
486        expect(user).not_to be_valid
487      end
488
489      it 'can not be set to an invalid email, even if confirmed' do
490        confirmed = create(:email, :confirmed, :skip_validate, user: user, email: 'invalid')
491        user.commit_email = confirmed.email
492
493        expect(user).not_to be_valid
494      end
495    end
496
497    describe 'email' do
498      let(:expected_error) { _('is not allowed for sign-up. Check with your administrator.') }
499
500      context 'when no signup domains allowed' do
501        before do
502          stub_application_setting(domain_allowlist: [])
503        end
504
505        it 'accepts any email' do
506          user = build(:user, email: "info@example.com")
507          expect(user).to be_valid
508        end
509      end
510
511      context 'bad regex' do
512        before do
513          stub_application_setting(domain_allowlist: ['([a-zA-Z0-9]+)+\.com'])
514        end
515
516        it 'does not hang on evil input' do
517          user = build(:user, email: 'user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!.com')
518
519          expect do
520            Timeout.timeout(2.seconds) { user.valid? }
521          end.not_to raise_error
522        end
523      end
524
525      context 'when a signup domain is allowed and subdomains are allowed' do
526        before do
527          stub_application_setting(domain_allowlist: ['example.com', '*.example.com'])
528        end
529
530        it 'accepts info@example.com' do
531          user = build(:user, email: "info@example.com")
532          expect(user).to be_valid
533        end
534
535        it 'accepts info@test.example.com' do
536          user = build(:user, email: "info@test.example.com")
537          expect(user).to be_valid
538        end
539
540        it 'rejects example@test.com' do
541          user = build(:user, email: "example@test.com")
542          expect(user).to be_invalid
543          expect(user.errors.messages[:email].first).to eq(expected_error)
544        end
545      end
546
547      context 'when a signup domain is allowed and subdomains are not allowed' do
548        before do
549          stub_application_setting(domain_allowlist: ['example.com'])
550        end
551
552        it 'accepts info@example.com' do
553          user = build(:user, email: "info@example.com")
554          expect(user).to be_valid
555        end
556
557        it 'rejects info@test.example.com' do
558          user = build(:user, email: "info@test.example.com")
559          expect(user).to be_invalid
560          expect(user.errors.messages[:email].first).to eq(expected_error)
561        end
562
563        it 'rejects example@test.com' do
564          user = build(:user, email: "example@test.com")
565          expect(user).to be_invalid
566          expect(user.errors.messages[:email].first).to eq(expected_error)
567        end
568
569        it 'accepts example@test.com when added by another user' do
570          user = build(:user, email: "example@test.com", created_by_id: 1)
571          expect(user).to be_valid
572        end
573      end
574
575      context 'domain denylist' do
576        before do
577          stub_application_setting(domain_denylist_enabled: true)
578          stub_application_setting(domain_denylist: ['example.com'])
579        end
580
581        context 'bad regex' do
582          before do
583            stub_application_setting(domain_denylist: ['([a-zA-Z0-9]+)+\.com'])
584          end
585
586          it 'does not hang on evil input' do
587            user = build(:user, email: 'user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!.com')
588
589            expect do
590              Timeout.timeout(2.seconds) { user.valid? }
591            end.not_to raise_error
592          end
593        end
594
595        context 'when a signup domain is denied' do
596          it 'accepts info@test.com' do
597            user = build(:user, email: 'info@test.com')
598            expect(user).to be_valid
599          end
600
601          it 'rejects info@example.com' do
602            user = build(:user, email: 'info@example.com')
603            expect(user).not_to be_valid
604            expect(user.errors.messages[:email].first).to eq(expected_error)
605          end
606
607          it 'accepts info@example.com when added by another user' do
608            user = build(:user, email: 'info@example.com', created_by_id: 1)
609            expect(user).to be_valid
610          end
611        end
612
613        context 'when a signup domain is denied but a wildcard subdomain is allowed' do
614          before do
615            stub_application_setting(domain_denylist: ['test.example.com'])
616            stub_application_setting(domain_allowlist: ['*.example.com'])
617          end
618
619          it 'gives priority to allowlist and allow info@test.example.com' do
620            user = build(:user, email: 'info@test.example.com')
621            expect(user).to be_valid
622          end
623        end
624
625        context 'with both lists containing a domain' do
626          before do
627            stub_application_setting(domain_allowlist: ['test.com'])
628          end
629
630          it 'accepts info@test.com' do
631            user = build(:user, email: 'info@test.com')
632            expect(user).to be_valid
633          end
634
635          it 'rejects info@example.com' do
636            user = build(:user, email: 'info@example.com')
637            expect(user).not_to be_valid
638            expect(user.errors.messages[:email].first).to eq(expected_error)
639          end
640        end
641      end
642
643      context 'email restrictions' do
644        context 'when email restriction is disabled' do
645          before do
646            stub_application_setting(email_restrictions_enabled: false)
647            stub_application_setting(email_restrictions: '\+')
648          end
649
650          it 'does accept email address' do
651            user = build(:user, email: 'info+1@test.com')
652
653            expect(user).to be_valid
654          end
655        end
656
657        context 'when email restrictions is enabled' do
658          before do
659            stub_application_setting(email_restrictions_enabled: true)
660            stub_application_setting(email_restrictions: '([\+]|\b(\w*gitlab.com\w*)\b)')
661          end
662
663          it 'does not accept email address with + characters' do
664            user = build(:user, email: 'info+1@test.com')
665
666            expect(user).not_to be_valid
667          end
668
669          it 'does not accept email with a gitlab domain' do
670            user = build(:user, email: 'info@gitlab.com')
671
672            expect(user).not_to be_valid
673          end
674
675          it 'adds an error message when email is not accepted' do
676            user = build(:user, email: 'info@gitlab.com')
677
678            expect(user).not_to be_valid
679            expect(user.errors.messages[:email].first).to eq(expected_error)
680          end
681
682          it 'does accept a valid email address' do
683            user = build(:user, email: 'info@test.com')
684
685            expect(user).to be_valid
686          end
687
688          context 'when created_by_id is set' do
689            it 'does accept the email address' do
690              user = build(:user, email: 'info+1@test.com', created_by_id: 1)
691
692              expect(user).to be_valid
693            end
694          end
695        end
696      end
697
698      context 'when secondary email is same as primary' do
699        let(:user) { create(:user, email: 'user@example.com') }
700
701        it 'lets user change primary email without failing validations' do
702          user.commit_email = user.email
703          user.notification_email = user.email
704          user.public_email = user.email
705          user.save!
706
707          user.email = 'newemail@example.com'
708          user.confirm
709
710          expect(user).to be_valid
711        end
712      end
713
714      context 'when commit_email is changed to _private' do
715        it 'passes user validations' do
716          user = create(:user)
717          user.commit_email = '_private'
718
719          expect(user).to be_valid
720        end
721      end
722    end
723  end
724
725  describe 'scopes' do
726    context 'blocked users' do
727      let_it_be(:active_user) { create(:user) }
728      let_it_be(:blocked_user) { create(:user, :blocked) }
729      let_it_be(:ldap_blocked_user) { create(:omniauth_user, :ldap_blocked) }
730      let_it_be(:blocked_pending_approval_user) { create(:user, :blocked_pending_approval) }
731      let_it_be(:banned_user) { create(:user, :banned) }
732
733      describe '.blocked' do
734        subject { described_class.blocked }
735
736        it 'returns only blocked users' do
737          expect(subject).to include(
738            blocked_user,
739            ldap_blocked_user
740          )
741
742          expect(subject).not_to include(active_user, blocked_pending_approval_user, banned_user)
743        end
744      end
745
746      describe '.blocked_pending_approval' do
747        subject { described_class.blocked_pending_approval }
748
749        it 'returns only pending approval users' do
750          expect(subject).to contain_exactly(blocked_pending_approval_user)
751        end
752      end
753
754      describe '.banned' do
755        subject { described_class.banned }
756
757        it 'returns only banned users' do
758          expect(subject).to contain_exactly(banned_user)
759        end
760      end
761    end
762
763    describe '.with_two_factor' do
764      it 'returns users with 2fa enabled via OTP' do
765        user_with_2fa = create(:user, :two_factor_via_otp)
766        user_without_2fa = create(:user)
767        users_with_two_factor = described_class.with_two_factor.pluck(:id)
768
769        expect(users_with_two_factor).to include(user_with_2fa.id)
770        expect(users_with_two_factor).not_to include(user_without_2fa.id)
771      end
772
773      shared_examples 'returns the right users' do |trait|
774        it 'returns users with 2fa enabled via hardware token' do
775          user_with_2fa = create(:user, trait)
776          user_without_2fa = create(:user)
777          users_with_two_factor = described_class.with_two_factor.pluck(:id)
778
779          expect(users_with_two_factor).to include(user_with_2fa.id)
780          expect(users_with_two_factor).not_to include(user_without_2fa.id)
781        end
782
783        it 'returns users with 2fa enabled via OTP and hardware token' do
784          user_with_2fa = create(:user, :two_factor_via_otp, trait)
785          user_without_2fa = create(:user)
786          users_with_two_factor = described_class.with_two_factor.pluck(:id)
787
788          expect(users_with_two_factor).to eq([user_with_2fa.id])
789          expect(users_with_two_factor).not_to include(user_without_2fa.id)
790        end
791
792        it 'works with ORDER BY' do
793          user_with_2fa = create(:user, :two_factor_via_otp, trait)
794
795          expect(described_class
796                     .with_two_factor
797                     .reorder_by_name).to eq([user_with_2fa])
798        end
799      end
800
801      describe 'and U2F' do
802        it_behaves_like "returns the right users", :two_factor_via_u2f
803      end
804
805      describe 'and WebAuthn' do
806        it_behaves_like "returns the right users", :two_factor_via_webauthn
807      end
808    end
809
810    describe '.without_two_factor' do
811      it 'excludes users with 2fa enabled via OTP' do
812        user_with_2fa = create(:user, :two_factor_via_otp)
813        user_without_2fa = create(:user)
814        users_without_two_factor = described_class.without_two_factor.pluck(:id)
815
816        expect(users_without_two_factor).to include(user_without_2fa.id)
817        expect(users_without_two_factor).not_to include(user_with_2fa.id)
818      end
819
820      describe 'and u2f' do
821        it 'excludes users with 2fa enabled via U2F' do
822          user_with_2fa = create(:user, :two_factor_via_u2f)
823          user_without_2fa = create(:user)
824          users_without_two_factor = described_class.without_two_factor.pluck(:id)
825
826          expect(users_without_two_factor).to include(user_without_2fa.id)
827          expect(users_without_two_factor).not_to include(user_with_2fa.id)
828        end
829
830        it 'excludes users with 2fa enabled via OTP and U2F' do
831          user_with_2fa = create(:user, :two_factor_via_otp, :two_factor_via_u2f)
832          user_without_2fa = create(:user)
833          users_without_two_factor = described_class.without_two_factor.pluck(:id)
834
835          expect(users_without_two_factor).to include(user_without_2fa.id)
836          expect(users_without_two_factor).not_to include(user_with_2fa.id)
837        end
838      end
839
840      describe 'and webauthn' do
841        it 'excludes users with 2fa enabled via WebAuthn' do
842          user_with_2fa = create(:user, :two_factor_via_webauthn)
843          user_without_2fa = create(:user)
844          users_without_two_factor = described_class.without_two_factor.pluck(:id)
845
846          expect(users_without_two_factor).to include(user_without_2fa.id)
847          expect(users_without_two_factor).not_to include(user_with_2fa.id)
848        end
849
850        it 'excludes users with 2fa enabled via OTP and WebAuthn' do
851          user_with_2fa = create(:user, :two_factor_via_otp, :two_factor_via_webauthn)
852          user_without_2fa = create(:user)
853          users_without_two_factor = described_class.without_two_factor.pluck(:id)
854
855          expect(users_without_two_factor).to include(user_without_2fa.id)
856          expect(users_without_two_factor).not_to include(user_with_2fa.id)
857        end
858      end
859    end
860
861    describe '.random_password' do
862      let(:random_password) { described_class.random_password }
863
864      before do
865        expect(User).to receive(:password_length).and_return(88..128)
866      end
867
868      context 'length' do
869        it 'conforms to the current password length settings' do
870          expect(random_password.length).to eq(128)
871        end
872      end
873    end
874
875    describe '.password_length' do
876      let(:password_length) { described_class.password_length }
877
878      it 'is expected to be a Range' do
879        expect(password_length).to be_a(Range)
880      end
881
882      context 'minimum value' do
883        before do
884          stub_application_setting(minimum_password_length: 101)
885        end
886
887        it 'is determined by the current value of `minimum_password_length` attribute of application_setting' do
888          expect(password_length.min).to eq(101)
889        end
890      end
891
892      context 'maximum value' do
893        it 'is determined by the current value of `Devise.password_length.max`' do
894          expect(password_length.max).to eq(Devise.password_length.max)
895        end
896      end
897    end
898
899    describe '.limit_to_todo_authors' do
900      context 'when filtering by todo authors' do
901        let(:user1) { create(:user) }
902        let(:user2) { create(:user) }
903
904        before do
905          create(:todo, user: user1, author: user1, state: :done)
906          create(:todo, user: user2, author: user2, state: :pending)
907        end
908
909        it 'only returns users that have authored todos' do
910          users = described_class.limit_to_todo_authors(
911            user: user2,
912            with_todos: true,
913            todo_state: :pending
914          )
915
916          expect(users).to eq([user2])
917        end
918
919        it 'ignores users that do not have a todo in the matching state' do
920          users = described_class.limit_to_todo_authors(
921            user: user1,
922            with_todos: true,
923            todo_state: :pending
924          )
925
926          expect(users).to be_empty
927        end
928      end
929
930      context 'when not filtering by todo authors' do
931        it 'returns the input relation' do
932          user1 = create(:user)
933          user2 = create(:user)
934          rel = described_class.limit_to_todo_authors(user: user1)
935
936          expect(rel).to include(user1, user2)
937        end
938      end
939
940      context 'when no user is provided' do
941        it 'returns the input relation' do
942          user1 = create(:user)
943          user2 = create(:user)
944          rel = described_class.limit_to_todo_authors
945
946          expect(rel).to include(user1, user2)
947        end
948      end
949    end
950
951    describe '.by_username' do
952      it 'finds users regardless of the case passed' do
953        user = create(:user, username: 'CaMeLcAsEd')
954        user2 = create(:user, username: 'UPPERCASE')
955
956        expect(described_class.by_username(%w(CAMELCASED uppercase)))
957          .to contain_exactly(user, user2)
958      end
959
960      it 'finds a single user regardless of the case passed' do
961        user = create(:user, username: 'CaMeLcAsEd')
962
963        expect(described_class.by_username('CAMELCASED'))
964          .to contain_exactly(user)
965      end
966    end
967
968    describe '.with_expiring_and_not_notified_personal_access_tokens' do
969      let_it_be(:user1) { create(:user) }
970      let_it_be(:user2) { create(:user) }
971      let_it_be(:user3) { create(:user) }
972
973      let_it_be(:expired_token) { create(:personal_access_token, user: user1, expires_at: 2.days.ago) }
974      let_it_be(:revoked_token) { create(:personal_access_token, user: user1, revoked: true) }
975      let_it_be(:impersonation_token) { create(:personal_access_token, :impersonation, user: user1, expires_at: 2.days.from_now) }
976      let_it_be(:valid_token_and_notified) { create(:personal_access_token, user: user2, expires_at: 2.days.from_now, expire_notification_delivered: true) }
977      let_it_be(:valid_token1) { create(:personal_access_token, user: user2, expires_at: 2.days.from_now) }
978      let_it_be(:valid_token2) { create(:personal_access_token, user: user2, expires_at: 2.days.from_now) }
979
980      let(:users) { described_class.with_expiring_and_not_notified_personal_access_tokens(from) }
981
982      context 'in one day' do
983        let(:from) { 1.day.from_now }
984
985        it "doesn't include an user" do
986          expect(users).to be_empty
987        end
988      end
989
990      context 'in three days' do
991        let(:from) { 3.days.from_now }
992
993        it 'only includes user2' do
994          expect(users).to contain_exactly(user2)
995        end
996      end
997    end
998
999    describe '.with_personal_access_tokens_expired_today' do
1000      let_it_be(:user1) { create(:user) }
1001      let_it_be(:expired_today) { create(:personal_access_token, user: user1, expires_at: Date.current) }
1002
1003      let_it_be(:user2) { create(:user) }
1004      let_it_be(:revoked_token) { create(:personal_access_token, user: user2, expires_at: Date.current, revoked: true) }
1005
1006      let_it_be(:user3) { create(:user) }
1007      let_it_be(:impersonated_token) { create(:personal_access_token, user: user3, expires_at: Date.current, impersonation: true) }
1008
1009      let_it_be(:user4) { create(:user) }
1010      let_it_be(:already_notified) { create(:personal_access_token, user: user4, expires_at: Date.current, after_expiry_notification_delivered: true) }
1011
1012      it 'returns users whose token has expired today' do
1013        expect(described_class.with_personal_access_tokens_expired_today).to contain_exactly(user1)
1014      end
1015    end
1016
1017    context 'SSH key expiration scopes' do
1018      let_it_be(:user1) { create(:user) }
1019      let_it_be(:user2) { create(:user) }
1020      let_it_be(:expired_today_not_notified) { create(:key, expires_at: Time.current, user: user1) }
1021      let_it_be(:expired_today_already_notified) { create(:key, expires_at: Time.current, user: user2, expiry_notification_delivered_at: Time.current) }
1022      let_it_be(:expiring_soon_not_notified) { create(:key, expires_at: 2.days.from_now, user: user2) }
1023      let_it_be(:expiring_soon_notified) { create(:key, expires_at: 2.days.from_now, user: user1, before_expiry_notification_delivered_at: Time.current) }
1024
1025      describe '.with_ssh_key_expiring_soon' do
1026        it 'returns users whose keys will expire soon' do
1027          expect(described_class.with_ssh_key_expiring_soon).to contain_exactly(user2)
1028        end
1029      end
1030    end
1031
1032    describe '.active_without_ghosts' do
1033      let_it_be(:user1) { create(:user, :external) }
1034      let_it_be(:user2) { create(:user, state: 'blocked') }
1035      let_it_be(:user3) { create(:user, :ghost) }
1036      let_it_be(:user4) { create(:user) }
1037
1038      it 'returns all active users but ghost users' do
1039        expect(described_class.active_without_ghosts).to match_array([user1, user4])
1040      end
1041    end
1042
1043    describe '.without_ghosts' do
1044      let_it_be(:user1) { create(:user, :external) }
1045      let_it_be(:user2) { create(:user, state: 'blocked') }
1046      let_it_be(:user3) { create(:user, :ghost) }
1047
1048      it 'returns users without ghosts users' do
1049        expect(described_class.without_ghosts).to match_array([user1, user2])
1050      end
1051    end
1052
1053    describe '.by_id_and_login' do
1054      let_it_be(:user) { create(:user) }
1055
1056      it 'finds a user regardless of case' do
1057        expect(described_class.by_id_and_login(user.id, user.username.upcase))
1058          .to contain_exactly(user)
1059      end
1060
1061      it 'finds a user when login is an email address regardless of case' do
1062        expect(described_class.by_id_and_login(user.id, user.email.upcase))
1063          .to contain_exactly(user)
1064      end
1065    end
1066
1067    describe '.for_todos' do
1068      let_it_be(:user1) { create(:user) }
1069      let_it_be(:user2) { create(:user) }
1070      let_it_be(:issue) { create(:issue) }
1071
1072      let_it_be(:todo1) { create(:todo, target: issue, author: user1, user: user1) }
1073      let_it_be(:todo2) { create(:todo, target: issue, author: user1, user: user1) }
1074      let_it_be(:todo3) { create(:todo, target: issue, author: user2, user: user2) }
1075
1076      it 'returns users for the given todos' do
1077        expect(described_class.for_todos(issue.todos))
1078          .to contain_exactly(user1, user2)
1079      end
1080    end
1081  end
1082
1083  context 'strip attributes' do
1084    context 'name' do
1085      let(:user) { User.new(name: ' John Smith ') }
1086
1087      it 'strips whitespaces on validation' do
1088        expect { user.valid? }.to change { user.name }.to('John Smith')
1089      end
1090    end
1091  end
1092
1093  describe 'Respond to' do
1094    it { is_expected.to respond_to(:admin?) }
1095    it { is_expected.to respond_to(:name) }
1096    it { is_expected.to respond_to(:external?) }
1097  end
1098
1099  describe 'before save hook' do
1100    describe '#default_private_profile_to_false' do
1101      let(:user) { create(:user, private_profile: true) }
1102
1103      it 'converts nil to false' do
1104        user.private_profile = nil
1105        user.save!
1106
1107        expect(user.private_profile).to eq false
1108      end
1109    end
1110
1111    context 'when saving an external user' do
1112      let(:user)          { create(:user) }
1113      let(:external_user) { create(:user, external: true) }
1114
1115      it 'sets other properties as well' do
1116        expect(external_user.can_create_team).to be_falsey
1117        expect(external_user.can_create_group).to be_falsey
1118        expect(external_user.projects_limit).to be 0
1119      end
1120    end
1121
1122    describe '#check_for_verified_email' do
1123      let(:user)      { create(:user) }
1124      let(:secondary) { create(:email, :confirmed, email: 'secondary@example.com', user: user) }
1125
1126      it 'allows a verified secondary email to be used as the primary without needing reconfirmation' do
1127        user.update!(email: secondary.email)
1128        user.reload
1129        expect(user.email).to eq secondary.email
1130        expect(user.unconfirmed_email).to eq nil
1131        expect(user.confirmed?).to be_truthy
1132      end
1133    end
1134  end
1135
1136  describe 'after commit hook' do
1137    describe 'when the primary email is updated' do
1138      before do
1139        @user = create(:user, email: 'primary@example.com').tap do |user|
1140          user.skip_reconfirmation!
1141        end
1142        @secondary = create :email, email: 'secondary@example.com', user: @user
1143        @user.reload
1144      end
1145
1146      it 'keeps old primary to secondary emails when secondary is a new email' do
1147        @user.update!(email: 'new_primary@example.com')
1148        @user.reload
1149
1150        expect(@user.emails.count).to eq 2
1151        expect(@user.emails.pluck(:email)).to match_array([@secondary.email, 'primary@example.com'])
1152      end
1153
1154      context 'when the first email was unconfirmed and the second email gets confirmed' do
1155        let(:user) { create(:user, :unconfirmed, email: 'should-be-unconfirmed@test.com') }
1156
1157        before do
1158          user.update!(email: 'should-be-confirmed@test.com')
1159          user.confirm
1160        end
1161
1162        it 'updates user.email' do
1163          expect(user.email).to eq('should-be-confirmed@test.com')
1164        end
1165
1166        it 'confirms user.email' do
1167          expect(user).to be_confirmed
1168        end
1169
1170        it 'does not add unconfirmed email to secondary' do
1171          expect(user.emails.map(&:email)).not_to include('should-be-unconfirmed@test.com')
1172        end
1173
1174        it 'has only one email association' do
1175          expect(user.emails.size).to eq(1)
1176        end
1177      end
1178    end
1179
1180    context 'when an existing email record is set as primary' do
1181      let(:user) { create(:user, email: 'confirmed@test.com') }
1182
1183      context 'when it is unconfirmed' do
1184        let(:originally_unconfirmed_email) { 'should-stay-unconfirmed@test.com' }
1185
1186        before do
1187          user.emails << create(:email, email: originally_unconfirmed_email, confirmed_at: nil)
1188
1189          user.update!(email: originally_unconfirmed_email)
1190        end
1191
1192        it 'keeps the user confirmed' do
1193          expect(user).to be_confirmed
1194        end
1195
1196        it 'keeps the original email' do
1197          expect(user.email).to eq('confirmed@test.com')
1198        end
1199
1200        context 'when the email gets confirmed' do
1201          before do
1202            user.confirm
1203          end
1204
1205          it 'keeps the user confirmed' do
1206            expect(user).to be_confirmed
1207          end
1208
1209          it 'updates the email' do
1210            expect(user.email).to eq(originally_unconfirmed_email)
1211          end
1212        end
1213      end
1214
1215      context 'when it is confirmed' do
1216        let!(:old_confirmed_email) { user.email }
1217        let(:confirmed_email) { 'already-confirmed@test.com' }
1218
1219        before do
1220          user.emails << create(:email, :confirmed, email: confirmed_email)
1221
1222          user.update!(email: confirmed_email)
1223        end
1224
1225        it 'keeps the user confirmed' do
1226          expect(user).to be_confirmed
1227        end
1228
1229        it 'updates the email' do
1230          expect(user.email).to eq(confirmed_email)
1231        end
1232
1233        it 'keeps the old email' do
1234          email = user.reload.emails.first
1235
1236          expect(email.email).to eq(old_confirmed_email)
1237          expect(email).to be_confirmed
1238        end
1239      end
1240    end
1241
1242    context 'when unconfirmed user deletes a confirmed additional email' do
1243      let(:user) { create(:user, :unconfirmed) }
1244
1245      before do
1246        user.emails << create(:email, :confirmed)
1247      end
1248
1249      it 'does not affect the confirmed status' do
1250        expect { user.emails.confirmed.destroy_all }.not_to change { user.confirmed? } # rubocop: disable Cop/DestroyAll
1251      end
1252    end
1253
1254    describe 'when changing email' do
1255      let(:user) { create(:user) }
1256      let(:new_email) { 'new-email@example.com' }
1257
1258      context 'if notification_email was nil' do
1259        it 'sets :unconfirmed_email' do
1260          expect do
1261            user.tap { |u| u.update!(email: new_email) }.reload
1262          end.to change(user, :unconfirmed_email).to(new_email)
1263        end
1264
1265        it 'does not change notification_email or notification_email_or_default before email is confirmed' do
1266          expect do
1267            user.tap { |u| u.update!(email: new_email) }.reload
1268          end.not_to change(user, :notification_email_or_default)
1269
1270          expect(user.notification_email).to be_nil
1271        end
1272
1273        it 'updates notification_email_or_default to the new email once confirmed' do
1274          user.update!(email: new_email)
1275
1276          expect do
1277            user.tap(&:confirm).reload
1278          end.to change(user, :notification_email_or_default).to eq(new_email)
1279
1280          expect(user.notification_email).to be_nil
1281        end
1282      end
1283
1284      context 'when notification_email is set to a secondary email' do
1285        let!(:email_attrs) { attributes_for(:email, :confirmed, user: user) }
1286        let(:secondary) { create(:email, :confirmed, email: 'secondary@example.com', user: user) }
1287
1288        before do
1289          user.emails.create!(email_attrs)
1290          user.tap { |u| u.update!(notification_email: email_attrs[:email]) }.reload
1291        end
1292
1293        it 'does not change notification_email to email before email is confirmed' do
1294          expect do
1295            user.tap { |u| u.update!(email: new_email) }.reload
1296          end.not_to change(user, :notification_email)
1297        end
1298
1299        it 'does not change notification_email to email once confirmed' do
1300          user.update!(email: new_email)
1301
1302          expect do
1303            user.tap(&:confirm).reload
1304          end.not_to change(user, :notification_email)
1305        end
1306      end
1307    end
1308
1309    describe '#update_invalid_gpg_signatures' do
1310      let(:user) do
1311        create(:user, email: 'tula.torphy@abshire.ca').tap do |user|
1312          user.skip_reconfirmation!
1313        end
1314      end
1315
1316      it 'does nothing when the name is updated' do
1317        expect(user).not_to receive(:update_invalid_gpg_signatures)
1318        user.update!(name: 'Bette')
1319      end
1320
1321      it 'synchronizes the gpg keys when the email is updated' do
1322        expect(user).to receive(:update_invalid_gpg_signatures).at_most(:twice)
1323        user.update!(email: 'shawnee.ritchie@denesik.com')
1324      end
1325    end
1326  end
1327
1328  describe 'name getters' do
1329    let(:user) { create(:user, name: 'Kane Martin William') }
1330
1331    it 'derives first name from full name, if not present' do
1332      expect(user.first_name).to eq('Kane')
1333    end
1334
1335    it 'derives last name from full name, if not present' do
1336      expect(user.last_name).to eq('Martin William')
1337    end
1338  end
1339
1340  describe '#highest_role' do
1341    let_it_be(:user) { create(:user) }
1342
1343    context 'when user_highest_role does not exist' do
1344      it 'returns NO_ACCESS' do
1345        expect(user.highest_role).to eq(Gitlab::Access::NO_ACCESS)
1346      end
1347    end
1348
1349    context 'when user_highest_role exists' do
1350      context 'stored highest access level is nil' do
1351        it 'returns Gitlab::Access::NO_ACCESS' do
1352          create(:user_highest_role, user: user)
1353
1354          expect(user.highest_role).to eq(Gitlab::Access::NO_ACCESS)
1355        end
1356      end
1357
1358      context 'stored highest access level present' do
1359        context 'with association :user_highest_role' do
1360          let(:another_user) { create(:user) }
1361
1362          before do
1363            create(:user_highest_role, :maintainer, user: user)
1364            create(:user_highest_role, :developer, user: another_user)
1365          end
1366
1367          it 'returns the correct highest role' do
1368            users = User.includes(:user_highest_role).where(id: [user.id, another_user.id])
1369
1370            expect(users.collect { |u| [u.id, u.highest_role] }).to contain_exactly(
1371              [user.id, Gitlab::Access::MAINTAINER],
1372              [another_user.id, Gitlab::Access::DEVELOPER]
1373            )
1374          end
1375        end
1376      end
1377    end
1378  end
1379
1380  describe '#credit_card_validated_at' do
1381    let_it_be(:user) { create(:user) }
1382
1383    context 'when credit_card_validation does not exist' do
1384      it 'returns nil' do
1385        expect(user.credit_card_validated_at).to be nil
1386      end
1387    end
1388
1389    context 'when credit_card_validation exists' do
1390      it 'returns the credit card validated time' do
1391        credit_card_validated_time = Time.current - 1.day
1392
1393        create(:credit_card_validation, credit_card_validated_at: credit_card_validated_time, user: user)
1394
1395        expect(user.credit_card_validated_at).to eq(credit_card_validated_time)
1396      end
1397    end
1398  end
1399
1400  describe '#update_tracked_fields!', :clean_gitlab_redis_shared_state do
1401    let(:request) { OpenStruct.new(remote_ip: "127.0.0.1") }
1402    let(:user) { create(:user) }
1403
1404    it 'writes trackable attributes' do
1405      expect do
1406        user.update_tracked_fields!(request)
1407      end.to change { user.reload.current_sign_in_at }
1408    end
1409
1410    it 'does not write trackable attributes when called a second time within the hour' do
1411      user.update_tracked_fields!(request)
1412
1413      expect do
1414        user.update_tracked_fields!(request)
1415      end.not_to change { user.reload.current_sign_in_at }
1416    end
1417
1418    it 'writes trackable attributes for a different user' do
1419      user2 = create(:user)
1420
1421      user.update_tracked_fields!(request)
1422
1423      expect do
1424        user2.update_tracked_fields!(request)
1425      end.to change { user2.reload.current_sign_in_at }
1426    end
1427
1428    it 'does not write if the DB is in read-only mode' do
1429      expect(Gitlab::Database).to receive(:read_only?).and_return(true)
1430
1431      expect do
1432        user.update_tracked_fields!(request)
1433      end.not_to change { user.reload.current_sign_in_at }
1434    end
1435  end
1436
1437  shared_context 'user keys' do
1438    let(:user) { create(:user) }
1439    let!(:key) { create(:key, user: user) }
1440    let!(:deploy_key) { create(:deploy_key, user: user) }
1441  end
1442
1443  describe '#keys' do
1444    include_context 'user keys'
1445
1446    context 'with key and deploy key stored' do
1447      it 'returns stored key, but not deploy_key' do
1448        expect(user.keys).to include key
1449        expect(user.keys).not_to include deploy_key
1450      end
1451    end
1452  end
1453
1454  describe '#accessible_deploy_keys' do
1455    let(:user) { create(:user) }
1456    let(:project) { create(:project) }
1457    let!(:private_deploy_keys_project) { create(:deploy_keys_project) }
1458    let!(:public_deploy_keys_project) { create(:deploy_keys_project) }
1459    let!(:accessible_deploy_keys_project) { create(:deploy_keys_project, project: project) }
1460
1461    before do
1462      public_deploy_keys_project.deploy_key.update!(public: true)
1463      project.add_developer(user)
1464    end
1465
1466    it 'user can only see deploy keys accessible to right projects' do
1467      expect(user.accessible_deploy_keys).to match_array([public_deploy_keys_project.deploy_key,
1468                                                          accessible_deploy_keys_project.deploy_key])
1469    end
1470  end
1471
1472  describe '#deploy_keys' do
1473    include_context 'user keys'
1474
1475    context 'with key and deploy key stored' do
1476      it 'returns stored deploy key, but not normal key' do
1477        expect(user.deploy_keys).to include deploy_key
1478        expect(user.deploy_keys).not_to include key
1479      end
1480    end
1481  end
1482
1483  describe '#confirm' do
1484    before do
1485      allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true)
1486    end
1487
1488    let(:user) { create(:user, :unconfirmed, unconfirmed_email: 'test@gitlab.com') }
1489
1490    it 'returns unconfirmed' do
1491      expect(user.confirmed?).to be_falsey
1492    end
1493
1494    it 'confirms a user' do
1495      user.confirm
1496      expect(user.confirmed?).to be_truthy
1497    end
1498
1499    it 'adds the confirmed primary email to emails' do
1500      expect(user.emails.confirmed.map(&:email)).not_to include(user.email)
1501
1502      user.confirm
1503
1504      expect(user.emails.confirmed.map(&:email)).to include(user.email)
1505    end
1506  end
1507
1508  context 'if the user is created with confirmed_at set to a time' do
1509    let!(:user) { create(:user, email: 'test@gitlab.com', confirmed_at: Time.now.utc) }
1510
1511    it 'adds the confirmed primary email to emails upon creation' do
1512      expect(user.emails.confirmed.map(&:email)).to include(user.email)
1513    end
1514  end
1515
1516  describe '#to_reference' do
1517    let(:user) { create(:user) }
1518
1519    it 'returns a String reference to the object' do
1520      expect(user.to_reference).to eq "@#{user.username}"
1521    end
1522  end
1523
1524  describe '#generate_password' do
1525    it 'does not generate password by default' do
1526      user = create(:user, password: 'abcdefghe')
1527
1528      expect(user.password).to eq('abcdefghe')
1529    end
1530  end
1531
1532  describe 'ensure user preference' do
1533    it 'has user preference upon user initialization' do
1534      user = build(:user)
1535
1536      expect(user.user_preference).to be_present
1537      expect(user.user_preference).not_to be_persisted
1538    end
1539  end
1540
1541  describe 'ensure incoming email token' do
1542    it 'has incoming email token' do
1543      user = create(:user)
1544
1545      expect(user.incoming_email_token).not_to be_blank
1546    end
1547
1548    it 'uses SecureRandom to generate the incoming email token' do
1549      allow_next_instance_of(User) do |user|
1550        allow(user).to receive(:update_highest_role)
1551      end
1552
1553      allow_next_instance_of(Namespaces::UserNamespace) do |namespace|
1554        allow(namespace).to receive(:schedule_sync_event_worker)
1555      end
1556
1557      expect(SecureRandom).to receive(:hex).with(no_args).and_return('3b8ca303')
1558
1559      user = create(:user)
1560
1561      expect(user.incoming_email_token).to eql('gitlab')
1562    end
1563  end
1564
1565  describe '#ensure_user_rights_and_limits' do
1566    describe 'with external user' do
1567      let(:user) { create(:user, external: true) }
1568
1569      it 'receives callback when external changes' do
1570        expect(user).to receive(:ensure_user_rights_and_limits)
1571
1572        user.update!(external: false)
1573      end
1574
1575      it 'ensures correct rights and limits for user' do
1576        stub_config_setting(default_can_create_group: true)
1577
1578        expect { user.update!(external: false) }.to change { user.can_create_group }.to(true)
1579          .and change { user.projects_limit }.to(Gitlab::CurrentSettings.default_projects_limit)
1580      end
1581    end
1582
1583    describe 'without external user' do
1584      let(:user) { create(:user, external: false) }
1585
1586      it 'receives callback when external changes' do
1587        expect(user).to receive(:ensure_user_rights_and_limits)
1588
1589        user.update!(external: true)
1590      end
1591
1592      it 'ensures correct rights and limits for user' do
1593        expect { user.update!(external: true) }.to change { user.can_create_group }.to(false)
1594          .and change { user.projects_limit }.to(0)
1595      end
1596    end
1597  end
1598
1599  describe 'feed token' do
1600    it 'ensures a feed token on read' do
1601      user = create(:user, feed_token: nil)
1602      feed_token = user.feed_token
1603
1604      expect(feed_token).not_to be_blank
1605      expect(user.reload.feed_token).to eq feed_token
1606    end
1607
1608    it 'ensures no feed token when disabled' do
1609      allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(true)
1610
1611      user = create(:user, feed_token: nil)
1612      feed_token = user.feed_token
1613
1614      expect(feed_token).to be_blank
1615      expect(user.reload.feed_token).to be_blank
1616    end
1617  end
1618
1619  describe 'static object token' do
1620    it 'ensures a static object token on read' do
1621      user = create(:user, static_object_token: nil)
1622      static_object_token = user.static_object_token
1623
1624      expect(static_object_token).not_to be_blank
1625      expect(user.reload.static_object_token).to eq static_object_token
1626    end
1627  end
1628
1629  describe 'enabled_static_object_token' do
1630    let_it_be(:static_object_token) { 'ilqx6jm1u945macft4eff0nw' }
1631
1632    it 'returns incoming email token when supported' do
1633      allow(Gitlab::CurrentSettings).to receive(:static_objects_external_storage_enabled?).and_return(true)
1634
1635      user = create(:user, static_object_token: static_object_token)
1636
1637      expect(user.enabled_static_object_token).to eq(static_object_token)
1638    end
1639
1640    it 'returns `nil` when not supported' do
1641      allow(Gitlab::CurrentSettings).to receive(:static_objects_external_storage_enabled?).and_return(false)
1642
1643      user = create(:user, static_object_token: static_object_token)
1644
1645      expect(user.enabled_static_object_token).to be_nil
1646    end
1647  end
1648
1649  describe 'enabled_incoming_email_token' do
1650    let_it_be(:incoming_email_token) { 'ilqx6jm1u945macft4eff0nw' }
1651
1652    it 'returns incoming email token when supported' do
1653      allow(Gitlab::IncomingEmail).to receive(:supports_issue_creation?).and_return(true)
1654
1655      user = create(:user, incoming_email_token: incoming_email_token)
1656
1657      expect(user.enabled_incoming_email_token).to eq(incoming_email_token)
1658    end
1659
1660    it 'returns `nil` when not supported' do
1661      allow(Gitlab::IncomingEmail).to receive(:supports_issue_creation?).and_return(false)
1662
1663      user = create(:user, incoming_email_token: incoming_email_token)
1664
1665      expect(user.enabled_incoming_email_token).to be_nil
1666    end
1667  end
1668
1669  describe '#recently_sent_password_reset?' do
1670    it 'is false when reset_password_sent_at is nil' do
1671      user = build_stubbed(:user, reset_password_sent_at: nil)
1672
1673      expect(user.recently_sent_password_reset?).to eq false
1674    end
1675
1676    it 'is false when sent more than one minute ago' do
1677      user = build_stubbed(:user, reset_password_sent_at: 5.minutes.ago)
1678
1679      expect(user.recently_sent_password_reset?).to eq false
1680    end
1681
1682    it 'is true when sent less than one minute ago' do
1683      user = build_stubbed(:user, reset_password_sent_at: Time.current)
1684
1685      expect(user.recently_sent_password_reset?).to eq true
1686    end
1687  end
1688
1689  describe '#disable_two_factor!' do
1690    it 'clears all 2FA-related fields' do
1691      user = create(:user, :two_factor)
1692
1693      expect(user).to be_two_factor_enabled
1694      expect(user.encrypted_otp_secret).not_to be_nil
1695      expect(user.otp_backup_codes).not_to be_nil
1696      expect(user.otp_grace_period_started_at).not_to be_nil
1697
1698      user.disable_two_factor!
1699
1700      expect(user).not_to be_two_factor_enabled
1701      expect(user.encrypted_otp_secret).to be_nil
1702      expect(user.encrypted_otp_secret_iv).to be_nil
1703      expect(user.encrypted_otp_secret_salt).to be_nil
1704      expect(user.otp_backup_codes).to be_nil
1705      expect(user.otp_grace_period_started_at).to be_nil
1706    end
1707  end
1708
1709  describe '#two_factor_otp_enabled?' do
1710    let_it_be(:user) { create(:user) }
1711
1712    context 'when 2FA is enabled by an MFA Device' do
1713      let(:user) { create(:user, :two_factor) }
1714
1715      it { expect(user.two_factor_otp_enabled?).to eq(true) }
1716    end
1717
1718    context 'FortiAuthenticator' do
1719      context 'when enabled via GitLab settings' do
1720        before do
1721          allow(::Gitlab.config.forti_authenticator).to receive(:enabled).and_return(true)
1722        end
1723
1724        context 'when feature is disabled for the user' do
1725          before do
1726            stub_feature_flags(forti_authenticator: false)
1727          end
1728
1729          it { expect(user.two_factor_otp_enabled?).to eq(false) }
1730        end
1731
1732        context 'when feature is enabled for the user' do
1733          before do
1734            stub_feature_flags(forti_authenticator: user)
1735          end
1736
1737          it { expect(user.two_factor_otp_enabled?).to eq(true) }
1738        end
1739      end
1740
1741      context 'when disabled via GitLab settings' do
1742        before do
1743          allow(::Gitlab.config.forti_authenticator).to receive(:enabled).and_return(false)
1744        end
1745
1746        it { expect(user.two_factor_otp_enabled?).to eq(false) }
1747      end
1748    end
1749
1750    context 'FortiTokenCloud' do
1751      context 'when enabled via GitLab settings' do
1752        before do
1753          allow(::Gitlab.config.forti_token_cloud).to receive(:enabled).and_return(true)
1754        end
1755
1756        context 'when feature is disabled for the user' do
1757          before do
1758            stub_feature_flags(forti_token_cloud: false)
1759          end
1760
1761          it { expect(user.two_factor_otp_enabled?).to eq(false) }
1762        end
1763
1764        context 'when feature is enabled for the user' do
1765          before do
1766            stub_feature_flags(forti_token_cloud: user)
1767          end
1768
1769          it { expect(user.two_factor_otp_enabled?).to eq(true) }
1770        end
1771      end
1772
1773      context 'when disabled via GitLab settings' do
1774        before do
1775          allow(::Gitlab.config.forti_token_cloud).to receive(:enabled).and_return(false)
1776        end
1777
1778        it { expect(user.two_factor_otp_enabled?).to eq(false) }
1779      end
1780    end
1781  end
1782
1783  context 'two_factor_u2f_enabled?' do
1784    let_it_be(:user) { create(:user, :two_factor) }
1785
1786    context 'when webauthn feature flag is enabled' do
1787      context 'user has no U2F registration' do
1788        it { expect(user.two_factor_u2f_enabled?).to eq(false) }
1789      end
1790
1791      context 'user has existing U2F registration' do
1792        it 'returns false' do
1793          device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5))
1794          create(:u2f_registration, name: 'my u2f device',
1795                 user: user,
1796                 certificate: Base64.strict_encode64(device.cert_raw),
1797                 key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
1798                 public_key: Base64.strict_encode64(device.origin_public_key_raw))
1799
1800          expect(user.two_factor_u2f_enabled?).to eq(false)
1801        end
1802      end
1803    end
1804
1805    context 'when webauthn feature flag is disabled' do
1806      before do
1807        stub_feature_flags(webauthn: false)
1808      end
1809
1810      context 'user has no U2F registration' do
1811        it { expect(user.two_factor_u2f_enabled?).to eq(false) }
1812      end
1813
1814      context 'user has existing U2F registration' do
1815        it 'returns true' do
1816          device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5))
1817          create(:u2f_registration, name: 'my u2f device',
1818                 user: user,
1819                 certificate: Base64.strict_encode64(device.cert_raw),
1820                 key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
1821                 public_key: Base64.strict_encode64(device.origin_public_key_raw))
1822
1823          expect(user.two_factor_u2f_enabled?).to eq(true)
1824        end
1825      end
1826    end
1827  end
1828
1829  describe 'projects' do
1830    before do
1831      @user = create(:user)
1832
1833      @project = create(:project, namespace: @user.namespace)
1834      @project_2 = create(:project, group: create(:group)) do |project|
1835        project.add_maintainer(@user)
1836      end
1837      @project_3 = create(:project, group: create(:group)) do |project|
1838        project.add_developer(@user)
1839      end
1840    end
1841
1842    it { expect(@user.authorized_projects).to include(@project) }
1843    it { expect(@user.authorized_projects).to include(@project_2) }
1844    it { expect(@user.authorized_projects).to include(@project_3) }
1845    it { expect(@user.owned_projects).to include(@project) }
1846    it { expect(@user.owned_projects).not_to include(@project_2) }
1847    it { expect(@user.owned_projects).not_to include(@project_3) }
1848    it { expect(@user.personal_projects).to include(@project) }
1849    it { expect(@user.personal_projects).not_to include(@project_2) }
1850    it { expect(@user.personal_projects).not_to include(@project_3) }
1851  end
1852
1853  describe 'groups' do
1854    let(:user) { create(:user) }
1855    let(:group) { create(:group) }
1856
1857    before do
1858      group.add_owner(user)
1859    end
1860
1861    it { expect(user.several_namespaces?).to be_truthy }
1862    it { expect(user.authorized_groups).to eq([group]) }
1863    it { expect(user.owned_groups).to eq([group]) }
1864    it { expect(user.namespaces).to contain_exactly(user.namespace, group) }
1865    it { expect(user.manageable_namespaces).to contain_exactly(user.namespace, group) }
1866
1867    context 'with owned groups only' do
1868      before do
1869        other_group = create(:group)
1870        other_group.add_developer(user)
1871      end
1872
1873      it { expect(user.namespaces(owned_only: true)).to contain_exactly(user.namespace, group) }
1874    end
1875
1876    context 'with child groups' do
1877      let!(:subgroup) { create(:group, parent: group) }
1878
1879      describe '#manageable_namespaces' do
1880        it 'includes all the namespaces the user can manage' do
1881          expect(user.manageable_namespaces).to contain_exactly(user.namespace, group, subgroup)
1882        end
1883      end
1884
1885      describe '#manageable_groups' do
1886        shared_examples 'manageable groups examples' do
1887          it 'includes all the namespaces the user can manage' do
1888            expect(user.manageable_groups).to contain_exactly(group, subgroup)
1889          end
1890
1891          it 'does not include duplicates if a membership was added for the subgroup' do
1892            subgroup.add_owner(user)
1893
1894            expect(user.manageable_groups).to contain_exactly(group, subgroup)
1895          end
1896        end
1897
1898        it_behaves_like 'manageable groups examples'
1899
1900        context 'when feature flag :linear_user_manageable_groups is disabled' do
1901          before do
1902            stub_feature_flags(linear_user_manageable_groups: false)
1903          end
1904
1905          it_behaves_like 'manageable groups examples'
1906        end
1907      end
1908
1909      describe '#manageable_groups_with_routes' do
1910        it 'eager loads routes from manageable groups' do
1911          control_count =
1912            ActiveRecord::QueryRecorder.new(skip_cached: false) do
1913              user.manageable_groups_with_routes.map(&:route)
1914            end.count
1915
1916          create(:group, parent: subgroup)
1917
1918          expect do
1919            user.manageable_groups_with_routes.map(&:route)
1920          end.not_to exceed_all_query_limit(control_count)
1921        end
1922      end
1923    end
1924  end
1925
1926  describe 'group multiple owners' do
1927    before do
1928      @user = create :user
1929      @user2 = create :user
1930      @group = create :group
1931      @group.add_owner(@user)
1932
1933      @group.add_user(@user2, GroupMember::OWNER)
1934    end
1935
1936    it { expect(@user2.several_namespaces?).to be_truthy }
1937  end
1938
1939  describe 'namespaced' do
1940    before do
1941      @user = create :user
1942      @project = create(:project, namespace: @user.namespace)
1943    end
1944
1945    it { expect(@user.several_namespaces?).to be_falsey }
1946    it { expect(@user.namespaces).to eq([@user.namespace]) }
1947  end
1948
1949  describe 'blocking user' do
1950    let_it_be_with_refind(:user) { create(:user, name: 'John Smith') }
1951
1952    it 'blocks user' do
1953      user.block
1954
1955      expect(user.blocked?).to be_truthy
1956    end
1957
1958    context 'when user has running CI pipelines' do
1959      let(:pipelines) { build_list(:ci_pipeline, 3, :running) }
1960
1961      it 'drops all running pipelines and related jobs' do
1962        drop_service = double
1963        disable_service = double
1964
1965        expect(user).to receive(:pipelines).and_return(pipelines)
1966        expect(Ci::DropPipelineService).to receive(:new).and_return(drop_service)
1967        expect(drop_service).to receive(:execute_async_for_all).with(pipelines, :user_blocked, user)
1968
1969        expect(Ci::DisableUserPipelineSchedulesService).to receive(:new).and_return(disable_service)
1970        expect(disable_service).to receive(:execute).with(user)
1971
1972        user.block!
1973      end
1974
1975      it 'does not drop running pipelines if the transaction rolls back' do
1976        expect(Ci::DropPipelineService).not_to receive(:new)
1977        expect(Ci::DisableUserPipelineSchedulesService).not_to receive(:new)
1978
1979        User.transaction do
1980          user.block
1981
1982          raise ActiveRecord::Rollback
1983        end
1984      end
1985    end
1986
1987    context 'when user has active CI pipeline schedules' do
1988      let_it_be(:schedule) { create(:ci_pipeline_schedule, active: true, owner: user) }
1989
1990      it 'disables any pipeline schedules' do
1991        expect { user.block }.to change { schedule.reload.active? }.to(false)
1992      end
1993    end
1994  end
1995
1996  describe 'deactivating a user' do
1997    let(:user) { create(:user, name: 'John Smith') }
1998
1999    context 'an active user' do
2000      it 'can be deactivated' do
2001        user.deactivate
2002
2003        expect(user.deactivated?).to be_truthy
2004      end
2005
2006      context 'when user deactivation emails are disabled' do
2007        before do
2008          stub_application_setting(user_deactivation_emails_enabled: false)
2009        end
2010        it 'does not send deactivated user an email' do
2011          expect(NotificationService).not_to receive(:new)
2012
2013          user.deactivate
2014        end
2015      end
2016
2017      context 'when user deactivation emails are enabled' do
2018        it 'sends deactivated user an email' do
2019          expect_next_instance_of(NotificationService) do |notification|
2020            allow(notification).to receive(:user_deactivated).with(user.name, user.notification_email_or_default)
2021          end
2022
2023          user.deactivate
2024        end
2025      end
2026    end
2027
2028    context 'a user who is blocked' do
2029      before do
2030        user.block
2031      end
2032
2033      it 'cannot be deactivated' do
2034        user.deactivate
2035
2036        expect(user.reload.deactivated?).to be_falsy
2037      end
2038    end
2039  end
2040
2041  describe 'blocking a user pending approval' do
2042    let(:user) { create(:user) }
2043
2044    before do
2045      user.block_pending_approval
2046    end
2047
2048    context 'an active user' do
2049      it 'can be blocked pending approval' do
2050        expect(user.blocked_pending_approval?).to eq(true)
2051      end
2052
2053      it 'behaves like a blocked user' do
2054        expect(user.blocked?).to eq(true)
2055      end
2056    end
2057  end
2058
2059  describe '.instance_access_request_approvers_to_be_notified' do
2060    let_it_be(:admin_issue_board_list) { create_list(:user, 12, :admin, :with_sign_ins) }
2061
2062    it 'returns up to the ten most recently active instance admins' do
2063      active_admins_in_recent_sign_in_desc_order = User.admins.active.order_recent_sign_in.limit(10)
2064
2065      expect(User.instance_access_request_approvers_to_be_notified).to eq(active_admins_in_recent_sign_in_desc_order)
2066    end
2067  end
2068
2069  describe 'banning and unbanning a user', :aggregate_failures do
2070    let(:user) { create(:user) }
2071
2072    context 'banning a user' do
2073      it 'bans and blocks the user' do
2074        user.ban
2075
2076        expect(user.banned?).to eq(true)
2077        expect(user.blocked?).to eq(true)
2078      end
2079
2080      it 'creates a BannedUser record' do
2081        expect { user.ban }.to change { Users::BannedUser.count }.by(1)
2082        expect(Users::BannedUser.last.user_id).to eq(user.id)
2083      end
2084    end
2085
2086    context 'unbanning a user' do
2087      before do
2088        user.ban!
2089      end
2090
2091      it 'unbans the user' do
2092        user.unban
2093
2094        expect(user.banned?).to eq(false)
2095        expect(user.active?).to eq(true)
2096      end
2097
2098      it 'deletes the BannedUser record' do
2099        expect { user.unban }.to change { Users::BannedUser.count }.by(-1)
2100        expect(Users::BannedUser.where(user_id: user.id)).not_to exist
2101      end
2102    end
2103  end
2104
2105  describe '.filter_items' do
2106    let(:user) { double }
2107
2108    it 'filters by active users by default' do
2109      expect(described_class).to receive(:active_without_ghosts).and_return([user])
2110
2111      expect(described_class.filter_items(nil)).to include user
2112    end
2113
2114    it 'filters by admins' do
2115      expect(described_class).to receive(:admins).and_return([user])
2116
2117      expect(described_class.filter_items('admins')).to include user
2118    end
2119
2120    it 'filters by blocked' do
2121      expect(described_class).to receive(:blocked).and_return([user])
2122
2123      expect(described_class.filter_items('blocked')).to include user
2124    end
2125
2126    it 'filters by banned' do
2127      expect(described_class).to receive(:banned).and_return([user])
2128
2129      expect(described_class.filter_items('banned')).to include user
2130    end
2131
2132    it 'filters by blocked pending approval' do
2133      expect(described_class).to receive(:blocked_pending_approval).and_return([user])
2134
2135      expect(described_class.filter_items('blocked_pending_approval')).to include user
2136    end
2137
2138    it 'filters by deactivated' do
2139      expect(described_class).to receive(:deactivated).and_return([user])
2140
2141      expect(described_class.filter_items('deactivated')).to include user
2142    end
2143
2144    it 'filters by two_factor_disabled' do
2145      expect(described_class).to receive(:without_two_factor).and_return([user])
2146
2147      expect(described_class.filter_items('two_factor_disabled')).to include user
2148    end
2149
2150    it 'filters by two_factor_enabled' do
2151      expect(described_class).to receive(:with_two_factor).and_return([user])
2152
2153      expect(described_class.filter_items('two_factor_enabled')).to include user
2154    end
2155
2156    it 'filters by wop' do
2157      expect(described_class).to receive(:without_projects).and_return([user])
2158
2159      expect(described_class.filter_items('wop')).to include user
2160    end
2161  end
2162
2163  describe '.without_projects' do
2164    let!(:project) { create(:project, :public) }
2165    let!(:user) { create(:user) }
2166    let!(:user_without_project) { create(:user) }
2167    let!(:user_without_project2) { create(:user) }
2168
2169    before do
2170      # add user to project
2171      project.add_maintainer(user)
2172
2173      # create invite to project
2174      create(:project_member, :developer, project: project, invite_token: '1234', invite_email: 'inviteduser1@example.com')
2175
2176      # create request to join project
2177      project.request_access(user_without_project2)
2178    end
2179
2180    it { expect(described_class.without_projects).not_to include user }
2181    it { expect(described_class.without_projects).to include user_without_project }
2182    it { expect(described_class.without_projects).to include user_without_project2 }
2183  end
2184
2185  describe 'user creation' do
2186    describe 'normal user' do
2187      let(:user) { create(:user, name: 'John Smith') }
2188
2189      it { expect(user.admin?).to be_falsey }
2190      it { expect(user.require_ssh_key?).to be_truthy }
2191      it { expect(user.can_create_group?).to be_truthy }
2192      it { expect(user.can_create_project?).to be_truthy }
2193      it { expect(user.first_name).to eq('John') }
2194      it { expect(user.external).to be_falsey }
2195    end
2196
2197    describe 'with defaults' do
2198      let(:user) { described_class.new }
2199
2200      it 'applies defaults to user' do
2201        expect(user.projects_limit).to eq(Gitlab.config.gitlab.default_projects_limit)
2202        expect(user.can_create_group).to eq(Gitlab.config.gitlab.default_can_create_group)
2203        expect(user.theme_id).to eq(Gitlab.config.gitlab.default_theme)
2204        expect(user.external).to be_falsey
2205        expect(user.private_profile).to eq(false)
2206      end
2207    end
2208
2209    describe 'with default overrides' do
2210      let(:user) { described_class.new(projects_limit: 123, can_create_group: false, can_create_team: true) }
2211
2212      it 'applies defaults to user' do
2213        expect(user.projects_limit).to eq(123)
2214        expect(user.can_create_group).to be_falsey
2215        expect(user.theme_id).to eq(1)
2216      end
2217
2218      it 'does not undo projects_limit setting if it matches old DB default of 10' do
2219        # If the real default project limit is 10 then this test is worthless
2220        expect(Gitlab.config.gitlab.default_projects_limit).not_to eq(10)
2221        user = described_class.new(projects_limit: 10)
2222        expect(user.projects_limit).to eq(10)
2223      end
2224    end
2225
2226    context 'when Gitlab::CurrentSettings.user_default_external is true' do
2227      before do
2228        stub_application_setting(user_default_external: true)
2229      end
2230
2231      it 'creates external user by default' do
2232        user = create(:user)
2233
2234        expect(user.external).to be_truthy
2235        expect(user.can_create_group).to be_falsey
2236        expect(user.projects_limit).to be 0
2237      end
2238
2239      describe 'with default overrides' do
2240        it 'creates a non-external user' do
2241          user = create(:user, external: false)
2242
2243          expect(user.external).to be_falsey
2244        end
2245      end
2246    end
2247
2248    describe '#require_ssh_key?', :use_clean_rails_memory_store_caching do
2249      protocol_and_expectation = {
2250        'http' => false,
2251        'ssh' => true,
2252        '' => true
2253      }
2254
2255      protocol_and_expectation.each do |protocol, expected|
2256        it 'has correct require_ssh_key?' do
2257          stub_application_setting(enabled_git_access_protocol: protocol)
2258          user = build(:user)
2259
2260          expect(user.require_ssh_key?).to eq(expected)
2261        end
2262      end
2263
2264      it 'returns false when the user has 1 or more SSH keys' do
2265        key = create(:personal_key)
2266
2267        expect(key.user.require_ssh_key?).to eq(false)
2268      end
2269    end
2270  end
2271
2272  describe '.find_for_database_authentication' do
2273    it 'strips whitespace from login' do
2274      user = create(:user)
2275
2276      expect(described_class.find_for_database_authentication({ login: " #{user.username} " })).to eq user
2277    end
2278  end
2279
2280  describe '.find_by_any_email' do
2281    it 'finds user through private commit email' do
2282      user = create(:user)
2283      private_email = user.private_commit_email
2284
2285      expect(described_class.find_by_any_email(private_email)).to eq(user)
2286      expect(described_class.find_by_any_email(private_email, confirmed: true)).to eq(user)
2287    end
2288
2289    it 'finds by primary email' do
2290      user = create(:user, email: 'foo@example.com')
2291
2292      expect(described_class.find_by_any_email(user.email)).to eq user
2293      expect(described_class.find_by_any_email(user.email, confirmed: true)).to eq user
2294    end
2295
2296    it 'finds by uppercased email' do
2297      user = create(:user, email: 'foo@example.com')
2298
2299      expect(described_class.find_by_any_email(user.email.upcase)).to eq user
2300      expect(described_class.find_by_any_email(user.email.upcase, confirmed: true)).to eq user
2301    end
2302
2303    context 'finds by secondary email' do
2304      let(:user) { email.user }
2305
2306      context 'primary email confirmed' do
2307        context 'secondary email confirmed' do
2308          let!(:email) { create(:email, :confirmed, email: 'foo@example.com') }
2309
2310          it 'finds user respecting the confirmed flag' do
2311            expect(described_class.find_by_any_email(email.email)).to eq user
2312            expect(described_class.find_by_any_email(email.email, confirmed: true)).to eq user
2313          end
2314        end
2315
2316        context 'secondary email not confirmed' do
2317          let!(:email) { create(:email, email: 'foo@example.com') }
2318
2319          it 'finds user respecting the confirmed flag' do
2320            expect(described_class.find_by_any_email(email.email)).to eq user
2321            expect(described_class.find_by_any_email(email.email, confirmed: true)).to be_nil
2322          end
2323        end
2324      end
2325
2326      context 'primary email not confirmed' do
2327        let(:user) { create(:user, :unconfirmed) }
2328        let!(:email) { create(:email, :confirmed, user: user, email: 'foo@example.com') }
2329
2330        it 'finds user respecting the confirmed flag' do
2331          expect(described_class.find_by_any_email(email.email)).to eq user
2332          expect(described_class.find_by_any_email(email.email, confirmed: true)).to be_nil
2333        end
2334      end
2335    end
2336
2337    it 'returns nil when nothing found' do
2338      expect(described_class.find_by_any_email('')).to be_nil
2339    end
2340
2341    it 'returns nil when user is not confirmed' do
2342      user = create(:user, :unconfirmed, email: 'foo@example.com')
2343
2344      expect(described_class.find_by_any_email(user.email, confirmed: false)).to eq(user)
2345      expect(described_class.find_by_any_email(user.email, confirmed: true)).to be_nil
2346    end
2347  end
2348
2349  describe '.by_any_email' do
2350    it 'returns an ActiveRecord::Relation' do
2351      expect(described_class.by_any_email('foo@example.com'))
2352        .to be_a_kind_of(ActiveRecord::Relation)
2353    end
2354
2355    it 'returns a relation of users' do
2356      user = create(:user)
2357
2358      expect(described_class.by_any_email(user.email)).to eq([user])
2359    end
2360
2361    it 'returns a relation of users for confirmed users' do
2362      user = create(:user)
2363
2364      expect(described_class.by_any_email(user.email, confirmed: true)).to eq([user])
2365    end
2366
2367    it 'finds user through a private commit email' do
2368      user = create(:user)
2369      private_email = user.private_commit_email
2370
2371      expect(described_class.by_any_email(private_email)).to eq([user])
2372      expect(described_class.by_any_email(private_email, confirmed: true)).to eq([user])
2373    end
2374
2375    it 'finds user through a private commit email in an array' do
2376      user = create(:user)
2377      private_email = user.private_commit_email
2378
2379      expect(described_class.by_any_email([private_email])).to eq([user])
2380      expect(described_class.by_any_email([private_email], confirmed: true)).to eq([user])
2381    end
2382  end
2383
2384  describe '.search' do
2385    let_it_be(:user) { create(:user, name: 'user', username: 'usern', email: 'email@example.com') }
2386    let_it_be(:user2) { create(:user, name: 'user name', username: 'username', email: 'someemail@example.com') }
2387    let_it_be(:user3) { create(:user, name: 'us', username: 'se', email: 'foo@example.com') }
2388    let_it_be(:email) { create(:email, user: user, email: 'alias@example.com') }
2389
2390    describe 'name matching' do
2391      it 'returns users with a matching name with exact match first' do
2392        expect(described_class.search(user.name)).to eq([user, user2])
2393      end
2394
2395      it 'returns users with a partially matching name' do
2396        expect(described_class.search(user.name[0..2])).to eq([user, user2])
2397      end
2398
2399      it 'returns users with a matching name regardless of the casing' do
2400        expect(described_class.search(user2.name.upcase)).to eq([user2])
2401      end
2402
2403      it 'returns users with a exact matching name shorter than 3 chars' do
2404        expect(described_class.search(user3.name)).to eq([user3])
2405      end
2406
2407      it 'returns users with a exact matching name shorter than 3 chars regardless of the casing' do
2408        expect(described_class.search(user3.name.upcase)).to eq([user3])
2409      end
2410    end
2411
2412    describe 'email matching' do
2413      it 'returns users with a matching Email' do
2414        expect(described_class.search(user.email)).to eq([user])
2415      end
2416
2417      it 'does not return users with a partially matching Email' do
2418        expect(described_class.search(user.email[1...-1])).to be_empty
2419      end
2420
2421      it 'returns users with a matching Email regardless of the casing' do
2422        expect(described_class.search(user2.email.upcase)).to eq([user2])
2423      end
2424    end
2425
2426    describe 'secondary email matching' do
2427      it 'returns users with a matching secondary email' do
2428        expect(described_class.search(email.email)).to include(email.user)
2429      end
2430
2431      it 'does not return users with a matching part of secondary email' do
2432        expect(described_class.search(email.email[1...-1])).to be_empty
2433      end
2434
2435      it 'returns users with a matching secondary email regardless of the casing' do
2436        expect(described_class.search(email.email.upcase)).to include(email.user)
2437      end
2438    end
2439
2440    describe 'username matching' do
2441      it 'returns users with a matching username' do
2442        expect(described_class.search(user.username)).to eq([user, user2])
2443      end
2444
2445      it 'returns users with a matching username starting with a @' do
2446        expect(described_class.search("@#{user.username}")).to eq([user, user2])
2447      end
2448
2449      it 'returns users with a partially matching username' do
2450        expect(described_class.search(user.username[0..2])).to eq([user, user2])
2451      end
2452
2453      it 'returns users with a partially matching username starting with @' do
2454        expect(described_class.search("@#{user.username[0..2]}")).to eq([user, user2])
2455      end
2456
2457      it 'returns users with a matching username regardless of the casing' do
2458        expect(described_class.search(user2.username.upcase)).to eq([user2])
2459      end
2460
2461      it 'returns users with a exact matching username shorter than 3 chars' do
2462        expect(described_class.search(user3.username)).to eq([user3])
2463      end
2464
2465      it 'returns users with a exact matching username shorter than 3 chars regardless of the casing' do
2466        expect(described_class.search(user3.username.upcase)).to eq([user3])
2467      end
2468    end
2469
2470    it 'returns no matches for an empty string' do
2471      expect(described_class.search('')).to be_empty
2472    end
2473
2474    it 'returns no matches for nil' do
2475      expect(described_class.search(nil)).to be_empty
2476    end
2477  end
2478
2479  describe '.search_without_secondary_emails' do
2480    let_it_be(:user) { create(:user, name: 'John Doe', username: 'john.doe', email: 'someone.1@example.com' ) }
2481    let_it_be(:another_user) { create(:user, name: 'Albert Smith', username: 'albert.smith', email: 'another.2@example.com' ) }
2482    let_it_be(:email) { create(:email, user: another_user, email: 'alias@example.com') }
2483
2484    it 'returns users with a matching name' do
2485      expect(described_class.search_without_secondary_emails(user.name)).to eq([user])
2486    end
2487
2488    it 'returns users with a partially matching name' do
2489      expect(described_class.search_without_secondary_emails(user.name[0..2])).to eq([user])
2490    end
2491
2492    it 'returns users with a matching name regardless of the casing' do
2493      expect(described_class.search_without_secondary_emails(user.name.upcase)).to eq([user])
2494    end
2495
2496    it 'returns users with a matching email' do
2497      expect(described_class.search_without_secondary_emails(user.email)).to eq([user])
2498    end
2499
2500    it 'does not return users with a partially matching email' do
2501      expect(described_class.search_without_secondary_emails(user.email[1...-1])).to be_empty
2502    end
2503
2504    it 'returns users with a matching email regardless of the casing' do
2505      expect(described_class.search_without_secondary_emails(user.email.upcase)).to eq([user])
2506    end
2507
2508    it 'returns users with a matching username' do
2509      expect(described_class.search_without_secondary_emails(user.username)).to eq([user])
2510    end
2511
2512    it 'returns users with a partially matching username' do
2513      expect(described_class.search_without_secondary_emails(user.username[0..2])).to eq([user])
2514    end
2515
2516    it 'returns users with a matching username regardless of the casing' do
2517      expect(described_class.search_without_secondary_emails(user.username.upcase)).to eq([user])
2518    end
2519
2520    it 'does not return users with a matching whole secondary email' do
2521      expect(described_class.search_without_secondary_emails(email.email)).not_to include(email.user)
2522    end
2523
2524    it 'does not return users with a matching part of secondary email' do
2525      expect(described_class.search_without_secondary_emails(email.email[1...-1])).to be_empty
2526    end
2527
2528    it 'returns no matches for an empty string' do
2529      expect(described_class.search_without_secondary_emails('')).to be_empty
2530    end
2531
2532    it 'returns no matches for nil' do
2533      expect(described_class.search_without_secondary_emails(nil)).to be_empty
2534    end
2535  end
2536
2537  describe '.search_with_secondary_emails' do
2538    let_it_be(:user) { create(:user, name: 'John Doe', username: 'john.doe', email: 'someone.1@example.com' ) }
2539    let_it_be(:another_user) { create(:user, name: 'Albert Smith', username: 'albert.smith', email: 'another.2@example.com' ) }
2540    let_it_be(:email) { create(:email, user: another_user, email: 'alias@example.com') }
2541
2542    it 'returns users with a matching name' do
2543      expect(described_class.search_with_secondary_emails(user.name)).to eq([user])
2544    end
2545
2546    it 'returns users with a partially matching name' do
2547      expect(described_class.search_with_secondary_emails(user.name[0..2])).to eq([user])
2548    end
2549
2550    it 'returns users with a matching name regardless of the casing' do
2551      expect(described_class.search_with_secondary_emails(user.name.upcase)).to eq([user])
2552    end
2553
2554    it 'returns users with a matching email' do
2555      expect(described_class.search_with_secondary_emails(user.email)).to eq([user])
2556    end
2557
2558    it 'does not return users with a partially matching email' do
2559      expect(described_class.search_with_secondary_emails(user.email[1...-1])).to be_empty
2560    end
2561
2562    it 'returns users with a matching email regardless of the casing' do
2563      expect(described_class.search_with_secondary_emails(user.email.upcase)).to eq([user])
2564    end
2565
2566    it 'returns users with a matching username' do
2567      expect(described_class.search_with_secondary_emails(user.username)).to eq([user])
2568    end
2569
2570    it 'returns users with a partially matching username' do
2571      expect(described_class.search_with_secondary_emails(user.username[0..2])).to eq([user])
2572    end
2573
2574    it 'returns users with a matching username regardless of the casing' do
2575      expect(described_class.search_with_secondary_emails(user.username.upcase)).to eq([user])
2576    end
2577
2578    it 'returns users with a matching whole secondary email' do
2579      expect(described_class.search_with_secondary_emails(email.email)).to eq([email.user])
2580    end
2581
2582    it 'does not return users with a matching part of secondary email' do
2583      expect(described_class.search_with_secondary_emails(email.email[1...-1])).to be_empty
2584    end
2585
2586    it 'returns no matches for an empty string' do
2587      expect(described_class.search_with_secondary_emails('')).to be_empty
2588    end
2589
2590    it 'returns no matches for nil' do
2591      expect(described_class.search_with_secondary_emails(nil)).to be_empty
2592    end
2593  end
2594
2595  describe '.find_by_ssh_key_id' do
2596    let_it_be(:user) { create(:user) }
2597    let_it_be(:key) { create(:key, user: user) }
2598
2599    context 'using an existing SSH key ID' do
2600      it 'returns the corresponding User' do
2601        expect(described_class.find_by_ssh_key_id(key.id)).to eq(user)
2602      end
2603    end
2604
2605    it 'only performs a single query' do
2606      key # Don't count the queries for creating the key and user
2607
2608      expect { described_class.find_by_ssh_key_id(key.id) }
2609        .not_to exceed_query_limit(1)
2610    end
2611
2612    context 'using an invalid SSH key ID' do
2613      it 'returns nil' do
2614        expect(described_class.find_by_ssh_key_id(-1)).to be_nil
2615      end
2616    end
2617  end
2618
2619  describe '.by_login' do
2620    let(:username) { 'John' }
2621    let!(:user) { create(:user, username: username) }
2622
2623    it 'gets the correct user' do
2624      expect(described_class.by_login(user.email.upcase)).to eq user
2625      expect(described_class.by_login(user.email)).to eq user
2626      expect(described_class.by_login(username.downcase)).to eq user
2627      expect(described_class.by_login(username)).to eq user
2628      expect(described_class.by_login(nil)).to be_nil
2629      expect(described_class.by_login('')).to be_nil
2630    end
2631  end
2632
2633  describe '.find_by_username' do
2634    it 'returns nil if not found' do
2635      expect(described_class.find_by_username('JohnDoe')).to be_nil
2636    end
2637
2638    it 'is case-insensitive' do
2639      user = create(:user, username: 'JohnDoe')
2640
2641      expect(described_class.find_by_username('JOHNDOE')).to eq user
2642    end
2643  end
2644
2645  describe '.find_by_username!' do
2646    it 'raises RecordNotFound' do
2647      expect { described_class.find_by_username!('JohnDoe') }
2648        .to raise_error(ActiveRecord::RecordNotFound)
2649    end
2650
2651    it 'is case-insensitive' do
2652      user = create(:user, username: 'JohnDoe')
2653
2654      expect(described_class.find_by_username!('JOHNDOE')).to eq user
2655    end
2656  end
2657
2658  describe '.find_by_full_path' do
2659    let!(:user) { create(:user, namespace: create(:user_namespace)) }
2660
2661    context 'with a route matching the given path' do
2662      let!(:route) { user.namespace.route }
2663
2664      it 'returns the user' do
2665        expect(described_class.find_by_full_path(route.path)).to eq(user)
2666      end
2667
2668      it 'is case-insensitive' do
2669        expect(described_class.find_by_full_path(route.path.upcase)).to eq(user)
2670        expect(described_class.find_by_full_path(route.path.downcase)).to eq(user)
2671      end
2672
2673      context 'with a redirect route matching the given path' do
2674        let!(:redirect_route) { user.namespace.redirect_routes.create!(path: 'foo') }
2675
2676        context 'without the follow_redirects option' do
2677          it 'returns nil' do
2678            expect(described_class.find_by_full_path(redirect_route.path)).to eq(nil)
2679          end
2680        end
2681
2682        context 'with the follow_redirects option set to true' do
2683          it 'returns the user' do
2684            expect(described_class.find_by_full_path(redirect_route.path, follow_redirects: true)).to eq(user)
2685          end
2686
2687          it 'is case-insensitive' do
2688            expect(described_class.find_by_full_path(redirect_route.path.upcase, follow_redirects: true)).to eq(user)
2689            expect(described_class.find_by_full_path(redirect_route.path.downcase, follow_redirects: true)).to eq(user)
2690          end
2691        end
2692      end
2693
2694      context 'without a route or a redirect route matching the given path' do
2695        context 'without the follow_redirects option' do
2696          it 'returns nil' do
2697            expect(described_class.find_by_full_path('unknown')).to eq(nil)
2698          end
2699        end
2700        context 'with the follow_redirects option set to true' do
2701          it 'returns nil' do
2702            expect(described_class.find_by_full_path('unknown', follow_redirects: true)).to eq(nil)
2703          end
2704        end
2705      end
2706
2707      context 'with a group route matching the given path' do
2708        let!(:group) { create(:group, path: 'group_path') }
2709
2710        context 'when the group namespace has an owner_id (legacy data)' do
2711          before do
2712            group.update!(owner_id: user.id)
2713          end
2714
2715          it 'returns nil' do
2716            expect(described_class.find_by_full_path('group_path')).to eq(nil)
2717          end
2718        end
2719
2720        context 'when the group namespace does not have an owner_id' do
2721          it 'returns nil' do
2722            expect(described_class.find_by_full_path('group_path')).to eq(nil)
2723          end
2724        end
2725      end
2726    end
2727  end
2728
2729  describe 'all_ssh_keys' do
2730    it { is_expected.to have_many(:keys).dependent(:destroy) }
2731
2732    it 'has all ssh keys' do
2733      user = create :user
2734      key = create :key, key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD33bWLBxu48Sev9Fert1yzEO4WGcWglWF7K/AwblIUFselOt/QdOL9DSjpQGxLagO1s9wl53STIO8qGS4Ms0EJZyIXOEFMjFJ5xmjSy+S37By4sG7SsltQEHMxtbtFOaW5LV2wCrX+rUsRNqLMamZjgjcPO0/EgGCXIGMAYW4O7cwGZdXWYIhQ1Vwy+CsVMDdPkPgBXqK7nR/ey8KMs8ho5fMNgB5hBw/AL9fNGhRw3QTD6Q12Nkhl4VZES2EsZqlpNnJttnPdp847DUsT6yuLRlfiQfz5Cn9ysHFdXObMN5VYIiPFwHeYCZp1X2S4fDZooRE8uOLTfxWHPXwrhqSH", user_id: user.id
2735
2736      expect(user.all_ssh_keys).to include(a_string_starting_with(key.key))
2737    end
2738  end
2739
2740  describe '#avatar_type' do
2741    let(:user) { create(:user) }
2742
2743    it 'is true if avatar is image' do
2744      user.update_attribute(:avatar, 'uploads/avatar.png')
2745
2746      expect(user.avatar_type).to be_truthy
2747    end
2748
2749    it 'is false if avatar is html page' do
2750      user.update_attribute(:avatar, 'uploads/avatar.html')
2751      user.avatar_type
2752
2753      expect(user.errors.added?(:avatar, "file format is not supported. Please try one of the following supported formats: png, jpg, jpeg, gif, bmp, tiff, ico, webp")).to be true
2754    end
2755  end
2756
2757  describe '#avatar_url' do
2758    let(:user) { create(:user, :with_avatar) }
2759
2760    context 'when avatar file is uploaded' do
2761      it 'shows correct avatar url' do
2762        expect(user.avatar_url).to eq(user.avatar.url)
2763        expect(user.avatar_url(only_path: false)).to eq([Gitlab.config.gitlab.url, user.avatar.url].join)
2764      end
2765    end
2766  end
2767
2768  describe '#clear_avatar_caches' do
2769    let(:user) { create(:user) }
2770
2771    it 'clears the avatar cache when saving' do
2772      allow(user).to receive(:avatar_changed?).and_return(true)
2773
2774      expect(Gitlab::AvatarCache).to receive(:delete_by_email).with(*user.verified_emails)
2775
2776      user.update!(avatar: fixture_file_upload('spec/fixtures/dk.png'))
2777    end
2778  end
2779
2780  describe '#accept_pending_invitations!' do
2781    let(:user) { create(:user, email: 'user@email.com') }
2782    let!(:project_member_invite) { create(:project_member, :invited, invite_email: user.email) }
2783    let!(:group_member_invite) { create(:group_member, :invited, invite_email: user.email) }
2784    let!(:external_project_member_invite) { create(:project_member, :invited, invite_email: 'external@email.com') }
2785    let!(:external_group_member_invite) { create(:group_member, :invited, invite_email: 'external@email.com') }
2786
2787    it 'accepts all the user members pending invitations and returns the accepted_members' do
2788      accepted_members = user.accept_pending_invitations!
2789
2790      expect(accepted_members).to match_array([project_member_invite, group_member_invite])
2791      expect(group_member_invite.reload).not_to be_invite
2792      expect(project_member_invite.reload).not_to be_invite
2793      expect(external_project_member_invite.reload).to be_invite
2794      expect(external_group_member_invite.reload).to be_invite
2795    end
2796  end
2797
2798  describe '#all_emails' do
2799    let(:user) { create(:user) }
2800    let!(:email_confirmed) { create :email, user: user, confirmed_at: Time.current }
2801    let!(:email_unconfirmed) { create :email, user: user }
2802
2803    context 'when `include_private_email` is true' do
2804      it 'returns all emails' do
2805        expect(user.reload.all_emails).to contain_exactly(
2806          user.email,
2807          user.private_commit_email,
2808          email_unconfirmed.email,
2809          email_confirmed.email
2810        )
2811      end
2812    end
2813
2814    context 'when `include_private_email` is false' do
2815      it 'does not include the private commit email' do
2816        expect(user.reload.all_emails(include_private_email: false)).to contain_exactly(
2817          user.email,
2818          email_unconfirmed.email,
2819          email_confirmed.email
2820        )
2821      end
2822    end
2823  end
2824
2825  describe '#verified_emails' do
2826    let(:user) { create(:user) }
2827
2828    it 'returns only confirmed emails' do
2829      email_confirmed = create :email, user: user, confirmed_at: Time.current
2830      create :email, user: user
2831
2832      expect(user.verified_emails).to contain_exactly(
2833        user.email,
2834        user.private_commit_email,
2835        email_confirmed.email
2836      )
2837    end
2838  end
2839
2840  describe '#public_verified_emails' do
2841    let(:user) { create(:user) }
2842
2843    it 'returns only confirmed public emails' do
2844      email_confirmed = create :email, user: user, confirmed_at: Time.current
2845      create :email, user: user
2846
2847      expect(user.public_verified_emails).to contain_exactly(
2848        user.email,
2849        email_confirmed.email
2850      )
2851    end
2852
2853    it 'returns confirmed public emails plus main user email when user is not confirmed' do
2854      user = create(:user, confirmed_at: nil)
2855      email_confirmed = create :email, user: user, confirmed_at: Time.current
2856      create :email, user: user
2857
2858      expect(user.public_verified_emails).to contain_exactly(
2859        user.email,
2860        email_confirmed.email
2861      )
2862    end
2863  end
2864
2865  describe '#verified_email?' do
2866    let(:user) { create(:user) }
2867
2868    it 'returns true when the email is verified/confirmed' do
2869      email_confirmed = create :email, user: user, confirmed_at: Time.current
2870      create :email, user: user
2871      user.reload
2872
2873      expect(user.verified_email?(user.email)).to be_truthy
2874      expect(user.verified_email?(email_confirmed.email.titlecase)).to be_truthy
2875    end
2876
2877    it 'returns true when user is found through private commit email' do
2878      expect(user.verified_email?(user.private_commit_email)).to be_truthy
2879    end
2880
2881    it 'returns true for an outdated private commit email' do
2882      old_email = user.private_commit_email
2883
2884      user.update!(username: 'changed-username')
2885
2886      expect(user.verified_email?(old_email)).to be_truthy
2887    end
2888
2889    it 'returns false when the email is not verified/confirmed' do
2890      email_unconfirmed = create :email, user: user
2891      user.reload
2892
2893      expect(user.verified_email?(email_unconfirmed.email)).to be_falsy
2894    end
2895  end
2896
2897  context 'crowd synchronized user' do
2898    describe '#crowd_user?' do
2899      it 'is true if provider is crowd' do
2900        user = create(:omniauth_user, provider: 'crowd')
2901
2902        expect(user.crowd_user?).to be_truthy
2903      end
2904
2905      it 'is false for other providers' do
2906        user = create(:omniauth_user, provider: 'other-provider')
2907
2908        expect(user.crowd_user?).to be_falsey
2909      end
2910
2911      it 'is false if no extern_uid is provided' do
2912        user = create(:omniauth_user, extern_uid: nil)
2913
2914        expect(user.crowd_user?).to be_falsey
2915      end
2916    end
2917  end
2918
2919  describe '#requires_ldap_check?' do
2920    let(:user) { described_class.new }
2921
2922    it 'is false when LDAP is disabled' do
2923      # Create a condition which would otherwise cause 'true' to be returned
2924      allow(user).to receive(:ldap_user?).and_return(true)
2925      user.last_credential_check_at = nil
2926
2927      expect(user.requires_ldap_check?).to be_falsey
2928    end
2929
2930    context 'when LDAP is enabled' do
2931      before do
2932        allow(Gitlab.config.ldap).to receive(:enabled).and_return(true)
2933      end
2934
2935      it 'is false for non-LDAP users' do
2936        allow(user).to receive(:ldap_user?).and_return(false)
2937
2938        expect(user.requires_ldap_check?).to be_falsey
2939      end
2940
2941      context 'and when the user is an LDAP user' do
2942        before do
2943          allow(user).to receive(:ldap_user?).and_return(true)
2944        end
2945
2946        it 'is true when the user has never had an LDAP check before' do
2947          user.last_credential_check_at = nil
2948
2949          expect(user.requires_ldap_check?).to be_truthy
2950        end
2951
2952        it 'is true when the last LDAP check happened over 1 hour ago' do
2953          user.last_credential_check_at = 2.hours.ago
2954
2955          expect(user.requires_ldap_check?).to be_truthy
2956        end
2957      end
2958    end
2959  end
2960
2961  context 'ldap synchronized user' do
2962    describe '#ldap_user?' do
2963      it 'is true if provider name starts with ldap' do
2964        user = create(:omniauth_user, provider: 'ldapmain')
2965
2966        expect(user.ldap_user?).to be_truthy
2967      end
2968
2969      it 'is false for other providers' do
2970        user = create(:omniauth_user, provider: 'other-provider')
2971
2972        expect(user.ldap_user?).to be_falsey
2973      end
2974
2975      it 'is false if no extern_uid is provided' do
2976        user = create(:omniauth_user, extern_uid: nil)
2977
2978        expect(user.ldap_user?).to be_falsey
2979      end
2980    end
2981
2982    describe '#ldap_identity' do
2983      it 'returns ldap identity' do
2984        user = create :omniauth_user
2985
2986        expect(user.ldap_identity.provider).not_to be_empty
2987      end
2988    end
2989
2990    describe '#matches_identity?' do
2991      it 'finds the identity when the DN is formatted differently' do
2992        user = create(:omniauth_user, provider: 'ldapmain', extern_uid: 'uid=john smith,ou=people,dc=example,dc=com')
2993
2994        expect(user.matches_identity?('ldapmain', 'uid=John Smith, ou=People, dc=example, dc=com')).to eq(true)
2995      end
2996    end
2997
2998    describe '#ldap_block' do
2999      let(:user) { create(:omniauth_user, provider: 'ldapmain', name: 'John Smith') }
3000
3001      it 'blocks user flaging the action caming from ldap' do
3002        user.ldap_block
3003
3004        expect(user.blocked?).to be_truthy
3005        expect(user.ldap_blocked?).to be_truthy
3006      end
3007
3008      context 'on a read-only instance' do
3009        before do
3010          allow(Gitlab::Database).to receive(:read_only?).and_return(true)
3011        end
3012
3013        it 'does not block user' do
3014          user.ldap_block
3015
3016          expect(user.blocked?).to be_falsey
3017          expect(user.ldap_blocked?).to be_falsey
3018        end
3019      end
3020    end
3021  end
3022
3023  describe '#full_website_url' do
3024    let(:user) { create(:user) }
3025
3026    it 'begins with http if website url omits it' do
3027      user.website_url = 'test.com'
3028
3029      expect(user.full_website_url).to eq 'http://test.com'
3030    end
3031
3032    it 'begins with http if website url begins with http' do
3033      user.website_url = 'http://test.com'
3034
3035      expect(user.full_website_url).to eq 'http://test.com'
3036    end
3037
3038    it 'begins with https if website url begins with https' do
3039      user.website_url = 'https://test.com'
3040
3041      expect(user.full_website_url).to eq 'https://test.com'
3042    end
3043  end
3044
3045  describe '#short_website_url' do
3046    let(:user) { create(:user) }
3047
3048    it 'does not begin with http if website url omits it' do
3049      user.website_url = 'test.com'
3050
3051      expect(user.short_website_url).to eq 'test.com'
3052    end
3053
3054    it 'does not begin with http if website url begins with http' do
3055      user.website_url = 'http://test.com'
3056
3057      expect(user.short_website_url).to eq 'test.com'
3058    end
3059
3060    it 'does not begin with https if website url begins with https' do
3061      user.website_url = 'https://test.com'
3062
3063      expect(user.short_website_url).to eq 'test.com'
3064    end
3065  end
3066
3067  describe '#sanitize_attrs' do
3068    let(:user) { build(:user, name: 'test <& user', skype: 'test&user') }
3069
3070    it 'encodes HTML entities in the Skype attribute' do
3071      expect { user.sanitize_attrs }.to change { user.skype }.to('test&amp;user')
3072    end
3073
3074    it 'does not encode HTML entities in the name attribute' do
3075      expect { user.sanitize_attrs }.not_to change { user.name }
3076    end
3077
3078    it 'sanitizes attr from html tags' do
3079      user = create(:user, name: '<a href="//example.com">Test<a>', twitter: '<a href="//evil.com">https://twitter.com<a>')
3080
3081      expect(user.name).to eq('Test')
3082      expect(user.twitter).to eq('https://twitter.com')
3083    end
3084
3085    it 'sanitizes attr from js scripts' do
3086      user = create(:user, name: '<script>alert("Test")</script>')
3087
3088      expect(user.name).to eq("alert(\"Test\")")
3089    end
3090
3091    it 'sanitizes attr from iframe scripts' do
3092      user = create(:user, name: 'User"><iframe src=javascript:alert()><iframe>')
3093
3094      expect(user.name).to eq('User">')
3095    end
3096  end
3097
3098  describe '#starred?' do
3099    it 'determines if user starred a project' do
3100      user = create :user
3101      project1 = create(:project, :public)
3102      project2 = create(:project, :public)
3103
3104      expect(user.starred?(project1)).to be_falsey
3105      expect(user.starred?(project2)).to be_falsey
3106
3107      star1 = UsersStarProject.create!(project: project1, user: user)
3108
3109      expect(user.starred?(project1)).to be_truthy
3110      expect(user.starred?(project2)).to be_falsey
3111
3112      star2 = UsersStarProject.create!(project: project2, user: user)
3113
3114      expect(user.starred?(project1)).to be_truthy
3115      expect(user.starred?(project2)).to be_truthy
3116
3117      star1.destroy!
3118
3119      expect(user.starred?(project1)).to be_falsey
3120      expect(user.starred?(project2)).to be_truthy
3121
3122      star2.destroy!
3123
3124      expect(user.starred?(project1)).to be_falsey
3125      expect(user.starred?(project2)).to be_falsey
3126    end
3127  end
3128
3129  describe '#toggle_star' do
3130    it 'toggles stars' do
3131      user = create :user
3132      project = create(:project, :public)
3133
3134      expect(user.starred?(project)).to be_falsey
3135
3136      user.toggle_star(project)
3137
3138      expect(user.starred?(project)).to be_truthy
3139
3140      user.toggle_star(project)
3141
3142      expect(user.starred?(project)).to be_falsey
3143    end
3144  end
3145
3146  describe '#following?' do
3147    it 'check if following another user' do
3148      user = create :user
3149      followee1 = create :user
3150
3151      expect(user.follow(followee1)).to be_truthy
3152
3153      expect(user.following?(followee1)).to be_truthy
3154
3155      expect(user.unfollow(followee1)).to be_truthy
3156
3157      expect(user.following?(followee1)).to be_falsey
3158    end
3159  end
3160
3161  describe '#follow' do
3162    it 'follow another user' do
3163      user = create :user
3164      followee1 = create :user
3165      followee2 = create :user
3166
3167      expect(user.followees).to be_empty
3168
3169      expect(user.follow(followee1)).to be_truthy
3170      expect(user.follow(followee1)).to be_falsey
3171
3172      expect(user.followees).to contain_exactly(followee1)
3173
3174      expect(user.follow(followee2)).to be_truthy
3175      expect(user.follow(followee2)).to be_falsey
3176
3177      expect(user.followees).to contain_exactly(followee1, followee2)
3178    end
3179
3180    it 'follow itself is not possible' do
3181      user = create :user
3182
3183      expect(user.followees).to be_empty
3184
3185      expect(user.follow(user)).to be_falsey
3186
3187      expect(user.followees).to be_empty
3188    end
3189  end
3190
3191  describe '#unfollow' do
3192    it 'unfollow another user' do
3193      user = create :user
3194      followee1 = create :user
3195      followee2 = create :user
3196
3197      expect(user.followees).to be_empty
3198
3199      expect(user.follow(followee1)).to be_truthy
3200      expect(user.follow(followee1)).to be_falsey
3201
3202      expect(user.follow(followee2)).to be_truthy
3203      expect(user.follow(followee2)).to be_falsey
3204
3205      expect(user.followees).to contain_exactly(followee1, followee2)
3206
3207      expect(user.unfollow(followee1)).to be_truthy
3208      expect(user.unfollow(followee1)).to be_falsey
3209
3210      expect(user.followees).to contain_exactly(followee2)
3211
3212      expect(user.unfollow(followee2)).to be_truthy
3213      expect(user.unfollow(followee2)).to be_falsey
3214
3215      expect(user.followees).to be_empty
3216    end
3217  end
3218
3219  describe '#notification_email_or_default' do
3220    let(:email) { 'gonzo@muppets.com' }
3221
3222    context 'when the column in the database is null' do
3223      subject { create(:user, email: email, notification_email: nil) }
3224
3225      it 'defaults to the primary email' do
3226        expect(subject.notification_email).to be nil
3227        expect(subject.notification_email_or_default).to eq(email)
3228      end
3229    end
3230  end
3231
3232  describe '.find_by_private_commit_email' do
3233    context 'with email' do
3234      let_it_be(:user) { create(:user) }
3235
3236      it 'returns user through private commit email' do
3237        expect(described_class.find_by_private_commit_email(user.private_commit_email)).to eq(user)
3238      end
3239
3240      it 'returns nil when email other than private_commit_email is used' do
3241        expect(described_class.find_by_private_commit_email(user.email)).to be_nil
3242      end
3243    end
3244
3245    it 'returns nil when email is nil' do
3246      expect(described_class.find_by_private_commit_email(nil)).to be_nil
3247    end
3248  end
3249
3250  describe '#sort_by_attribute' do
3251    before do
3252      described_class.delete_all
3253      @user = create :user, created_at: Date.today, current_sign_in_at: Date.today, name: 'Alpha'
3254      @user1 = create :user, created_at: Date.today - 1, current_sign_in_at: Date.today - 1, name: 'Omega'
3255      @user2 = create :user, created_at: Date.today - 2, name: 'Beta'
3256    end
3257
3258    context 'when sort by recent_sign_in' do
3259      let(:users) { described_class.sort_by_attribute('recent_sign_in') }
3260
3261      it 'sorts users by recent sign-in time' do
3262        expect(users.first).to eq(@user)
3263        expect(users.second).to eq(@user1)
3264      end
3265
3266      it 'pushes users who never signed in to the end' do
3267        expect(users.third).to eq(@user2)
3268      end
3269    end
3270
3271    context 'when sort by oldest_sign_in' do
3272      let(:users) { described_class.sort_by_attribute('oldest_sign_in') }
3273
3274      it 'sorts users by the oldest sign-in time' do
3275        expect(users.first).to eq(@user1)
3276        expect(users.second).to eq(@user)
3277      end
3278
3279      it 'pushes users who never signed in to the end' do
3280        expect(users.third).to eq(@user2)
3281      end
3282    end
3283
3284    it 'sorts users in descending order by their creation time' do
3285      expect(described_class.sort_by_attribute('created_desc').first).to eq(@user)
3286    end
3287
3288    it 'sorts users in ascending order by their creation time' do
3289      expect(described_class.sort_by_attribute('created_asc').first).to eq(@user2)
3290    end
3291
3292    it 'sorts users by id in descending order when nil is passed' do
3293      expect(described_class.sort_by_attribute(nil).first).to eq(@user2)
3294    end
3295  end
3296
3297  describe '#last_active_at' do
3298    let(:last_activity_on) { 5.days.ago.to_date }
3299    let(:current_sign_in_at) { 8.days.ago }
3300
3301    context 'for a user that has `last_activity_on` set' do
3302      let(:user) { create(:user, last_activity_on: last_activity_on) }
3303
3304      it 'returns `last_activity_on` with current time zone' do
3305        expect(user.last_active_at).to eq(last_activity_on.to_time.in_time_zone)
3306      end
3307    end
3308
3309    context 'for a user that has `current_sign_in_at` set' do
3310      let(:user) { create(:user, current_sign_in_at: current_sign_in_at) }
3311
3312      it 'returns `current_sign_in_at`' do
3313        expect(user.last_active_at).to eq(current_sign_in_at)
3314      end
3315    end
3316
3317    context 'for a user that has both `current_sign_in_at` & ``last_activity_on`` set' do
3318      let(:user) { create(:user, current_sign_in_at: current_sign_in_at, last_activity_on: last_activity_on) }
3319
3320      it 'returns the latest among `current_sign_in_at` & `last_activity_on`' do
3321        latest_event = [current_sign_in_at, last_activity_on.to_time.in_time_zone].max
3322        expect(user.last_active_at).to eq(latest_event)
3323      end
3324    end
3325
3326    context 'for a user that does not have both `current_sign_in_at` & `last_activity_on` set' do
3327      let(:user) { create(:user, current_sign_in_at: nil, last_activity_on: nil) }
3328
3329      it 'returns nil' do
3330        expect(user.last_active_at).to eq(nil)
3331      end
3332    end
3333  end
3334
3335  describe '#can_be_deactivated?' do
3336    let(:activity) { {} }
3337    let(:user) { create(:user, name: 'John Smith', **activity) }
3338    let(:day_within_minium_inactive_days_threshold) { User::MINIMUM_INACTIVE_DAYS.pred.days.ago }
3339    let(:day_outside_minium_inactive_days_threshold) { User::MINIMUM_INACTIVE_DAYS.next.days.ago }
3340
3341    shared_examples 'not eligible for deactivation' do
3342      it 'returns false' do
3343        expect(user.can_be_deactivated?).to be_falsey
3344      end
3345    end
3346
3347    shared_examples 'eligible for deactivation' do
3348      it 'returns true' do
3349        expect(user.can_be_deactivated?).to be_truthy
3350      end
3351    end
3352
3353    context 'a user who is not active' do
3354      before do
3355        user.block
3356      end
3357
3358      it_behaves_like 'not eligible for deactivation'
3359    end
3360
3361    context 'a user who has activity within the specified minimum inactive days' do
3362      let(:activity) { { last_activity_on: day_within_minium_inactive_days_threshold } }
3363
3364      it_behaves_like 'not eligible for deactivation'
3365    end
3366
3367    context 'a user who has signed in within the specified minimum inactive days' do
3368      let(:activity) { { current_sign_in_at: day_within_minium_inactive_days_threshold } }
3369
3370      it_behaves_like 'not eligible for deactivation'
3371    end
3372
3373    context 'a user who has no activity within the specified minimum inactive days' do
3374      let(:activity) { { last_activity_on: day_outside_minium_inactive_days_threshold } }
3375
3376      it_behaves_like 'eligible for deactivation'
3377    end
3378
3379    context 'a user who has not signed in within the specified minimum inactive days' do
3380      let(:activity) { { current_sign_in_at: day_outside_minium_inactive_days_threshold } }
3381
3382      it_behaves_like 'eligible for deactivation'
3383    end
3384
3385    context 'a user who is internal' do
3386      it 'returns false' do
3387        internal_user = create(:user, :bot)
3388
3389        expect(internal_user.can_be_deactivated?).to be_falsey
3390      end
3391    end
3392  end
3393
3394  describe '#contributed_projects' do
3395    subject { create(:user) }
3396
3397    let!(:project1) { create(:project) }
3398    let!(:project2) { fork_project(project3) }
3399    let!(:project3) { create(:project) }
3400    let!(:merge_request) { create(:merge_request, source_project: project2, target_project: project3, author: subject) }
3401    let!(:push_event) { create(:push_event, project: project1, author: subject) }
3402    let!(:merge_event) { create(:event, :created, project: project3, target: merge_request, author: subject) }
3403
3404    before do
3405      project1.add_maintainer(subject)
3406      project2.add_maintainer(subject)
3407    end
3408
3409    it 'includes IDs for projects the user has pushed to' do
3410      expect(subject.contributed_projects).to include(project1)
3411    end
3412
3413    it 'includes IDs for projects the user has had merge requests merged into' do
3414      expect(subject.contributed_projects).to include(project3)
3415    end
3416
3417    it "doesn't include IDs for unrelated projects" do
3418      expect(subject.contributed_projects).not_to include(project2)
3419    end
3420  end
3421
3422  describe '#fork_of' do
3423    let(:user) { create(:user) }
3424
3425    it "returns a user's fork of a project" do
3426      project = create(:project, :public)
3427      user_fork = fork_project(project, user, namespace: user.namespace)
3428
3429      expect(user.fork_of(project)).to eq(user_fork)
3430    end
3431
3432    it 'returns nil if the project does not have a fork network' do
3433      project = create(:project)
3434
3435      expect(user.fork_of(project)).to be_nil
3436    end
3437  end
3438
3439  describe '#can_be_removed?' do
3440    subject { create(:user) }
3441
3442    context 'no owned groups' do
3443      it { expect(subject.can_be_removed?).to be_truthy }
3444    end
3445
3446    context 'has owned groups' do
3447      before do
3448        group = create(:group)
3449        group.add_owner(subject)
3450      end
3451
3452      it { expect(subject.can_be_removed?).to be_falsey }
3453    end
3454  end
3455
3456  describe '#solo_owned_groups' do
3457    let_it_be_with_refind(:user) { create(:user) }
3458
3459    subject(:solo_owned_groups) { user.solo_owned_groups }
3460
3461    context 'no owned groups' do
3462      it { is_expected.to be_empty }
3463    end
3464
3465    context 'has owned groups' do
3466      let_it_be(:group) { create(:group) }
3467
3468      before do
3469        group.add_owner(user)
3470      end
3471
3472      context 'not solo owner' do
3473        let_it_be(:user2) { create(:user) }
3474
3475        before do
3476          group.add_owner(user2)
3477        end
3478
3479        it { is_expected.to be_empty }
3480      end
3481
3482      context 'solo owner' do
3483        it { is_expected.to include(group) }
3484
3485        it 'avoids N+1 queries' do
3486          fresh_user = User.find(user.id)
3487          control_count = ActiveRecord::QueryRecorder.new do
3488            fresh_user.solo_owned_groups
3489          end.count
3490
3491          create(:group).add_owner(user)
3492
3493          expect { solo_owned_groups }.not_to exceed_query_limit(control_count)
3494        end
3495      end
3496    end
3497  end
3498
3499  describe '#can_remove_self?' do
3500    let(:user) { create(:user) }
3501
3502    it 'returns true' do
3503      expect(user.can_remove_self?).to eq true
3504    end
3505  end
3506
3507  describe '#recent_push' do
3508    let(:user) { build(:user) }
3509    let(:project) { build(:project) }
3510    let(:event) { build(:push_event) }
3511
3512    it 'returns the last push event for the user' do
3513      expect_any_instance_of(Users::LastPushEventService)
3514        .to receive(:last_event_for_user)
3515        .and_return(event)
3516
3517      expect(user.recent_push).to eq(event)
3518    end
3519
3520    it 'returns the last push event for a project when one is given' do
3521      expect_any_instance_of(Users::LastPushEventService)
3522        .to receive(:last_event_for_project)
3523        .and_return(event)
3524
3525      expect(user.recent_push(project)).to eq(event)
3526    end
3527  end
3528
3529  describe '#authorized_groups' do
3530    let!(:user) { create(:user) }
3531    let!(:private_group) { create(:group) }
3532    let!(:child_group) { create(:group, parent: private_group) }
3533
3534    let!(:project_group) { create(:group) }
3535    let!(:project) { create(:project, group: project_group) }
3536
3537    before do
3538      private_group.add_user(user, Gitlab::Access::MAINTAINER)
3539      project.add_maintainer(user)
3540    end
3541
3542    subject { user.authorized_groups }
3543
3544    it { is_expected.to contain_exactly private_group, project_group }
3545
3546    context 'with shared memberships' do
3547      let!(:shared_group) { create(:group) }
3548      let!(:other_group) { create(:group) }
3549
3550      before do
3551        create(:group_group_link, shared_group: shared_group, shared_with_group: private_group)
3552        create(:group_group_link, shared_group: private_group, shared_with_group: other_group)
3553      end
3554
3555      it { is_expected.to include shared_group }
3556      it { is_expected.not_to include other_group }
3557    end
3558  end
3559
3560  describe '#membership_groups' do
3561    let_it_be(:user) { create(:user) }
3562
3563    let_it_be(:parent_group) do
3564      create(:group).tap do |g|
3565        g.add_user(user, Gitlab::Access::MAINTAINER)
3566      end
3567    end
3568
3569    let_it_be(:child_group) { create(:group, parent: parent_group) }
3570    let_it_be(:other_group) { create(:group) }
3571
3572    subject { user.membership_groups }
3573
3574    specify { is_expected.to contain_exactly(parent_group, child_group) }
3575  end
3576
3577  describe '#authorizations_for_projects' do
3578    let!(:user) { create(:user) }
3579
3580    subject { Project.where("EXISTS (?)", user.authorizations_for_projects) }
3581
3582    it 'includes projects that belong to a user, but no other projects' do
3583      owned = create(:project, :private, namespace: user.namespace)
3584      member = create(:project, :private).tap { |p| p.add_maintainer(user) }
3585      other = create(:project)
3586
3587      expect(subject).to include(owned)
3588      expect(subject).to include(member)
3589      expect(subject).not_to include(other)
3590    end
3591
3592    it 'includes projects a user has access to, but no other projects' do
3593      other_user = create(:user)
3594      accessible = create(:project, :private, namespace: other_user.namespace) do |project|
3595        project.add_developer(user)
3596      end
3597      other = create(:project)
3598
3599      expect(subject).to include(accessible)
3600      expect(subject).not_to include(other)
3601    end
3602
3603    context 'with min_access_level' do
3604      let!(:user) { create(:user) }
3605      let!(:project) { create(:project, :private, namespace: user.namespace) }
3606
3607      before do
3608        project.add_developer(user)
3609      end
3610
3611      subject { Project.where("EXISTS (?)", user.authorizations_for_projects(min_access_level: min_access_level)) }
3612
3613      context 'when developer access' do
3614        let(:min_access_level) { Gitlab::Access::DEVELOPER }
3615
3616        it 'includes projects a user has access to' do
3617          expect(subject).to include(project)
3618        end
3619      end
3620
3621      context 'when owner access' do
3622        let(:min_access_level) { Gitlab::Access::OWNER }
3623
3624        it 'does not include projects with higher access level' do
3625          expect(subject).not_to include(project)
3626        end
3627      end
3628    end
3629  end
3630
3631  describe '#authorized_projects', :delete do
3632    context 'with a minimum access level' do
3633      it 'includes projects for which the user is an owner' do
3634        user = create(:user)
3635        project = create(:project, :private, namespace: user.namespace)
3636
3637        expect(user.authorized_projects(Gitlab::Access::REPORTER))
3638          .to contain_exactly(project)
3639      end
3640
3641      it 'includes projects for which the user is a maintainer' do
3642        user = create(:user)
3643        project = create(:project, :private)
3644
3645        project.add_maintainer(user)
3646
3647        expect(user.authorized_projects(Gitlab::Access::REPORTER))
3648          .to contain_exactly(project)
3649      end
3650    end
3651
3652    it "includes user's personal projects" do
3653      user    = create(:user)
3654      project = create(:project, :private, namespace: user.namespace)
3655
3656      expect(user.authorized_projects).to include(project)
3657    end
3658
3659    it 'includes personal projects user has been given access to' do
3660      user1   = create(:user)
3661      user2   = create(:user)
3662      project = create(:project, :private, namespace: user1.namespace)
3663
3664      project.add_developer(user2)
3665
3666      expect(user2.authorized_projects).to include(project)
3667    end
3668
3669    it 'includes projects of groups user has been added to' do
3670      group   = create(:group)
3671      project = create(:project, group: group)
3672      user    = create(:user)
3673
3674      group.add_developer(user)
3675
3676      expect(user.authorized_projects).to include(project)
3677    end
3678
3679    it 'does not include projects of groups user has been removed from', :sidekiq_inline do
3680      group   = create(:group)
3681      project = create(:project, group: group)
3682      user    = create(:user)
3683
3684      member = group.add_developer(user)
3685
3686      expect(user.authorized_projects).to include(project)
3687
3688      member.destroy!
3689
3690      expect(user.authorized_projects).not_to include(project)
3691    end
3692
3693    it "includes projects shared with user's group" do
3694      user    = create(:user)
3695      project = create(:project, :private)
3696      group   = create(:group) do |group|
3697        group.add_reporter(user)
3698      end
3699      create(:project_group_link, group: group, project: project)
3700
3701      expect(user.authorized_projects).to include(project)
3702    end
3703
3704    it 'does not include destroyed projects user had access to' do
3705      user1   = create(:user)
3706      user2   = create(:user)
3707      project = create(:project, :private, namespace: user1.namespace)
3708
3709      project.add_developer(user2)
3710
3711      expect(user2.authorized_projects).to include(project)
3712
3713      project.destroy!
3714
3715      expect(user2.authorized_projects).not_to include(project)
3716    end
3717
3718    it 'does not include projects of destroyed groups user had access to' do
3719      group   = create(:group)
3720      project = create(:project, namespace: group)
3721      user    = create(:user)
3722
3723      group.add_developer(user)
3724
3725      expect(user.authorized_projects).to include(project)
3726
3727      group.destroy!
3728
3729      expect(user.authorized_projects).not_to include(project)
3730    end
3731  end
3732
3733  describe '#projects_where_can_admin_issues' do
3734    let(:user) { create(:user) }
3735
3736    it 'includes projects for which the user access level is above or equal to reporter' do
3737      reporter_project  = create(:project) { |p| p.add_reporter(user) }
3738      developer_project = create(:project) { |p| p.add_developer(user) }
3739      maintainer_project = create(:project) { |p| p.add_maintainer(user) }
3740
3741      expect(user.projects_where_can_admin_issues.to_a).to match_array([maintainer_project, developer_project, reporter_project])
3742      expect(user.can?(:admin_issue, maintainer_project)).to eq(true)
3743      expect(user.can?(:admin_issue, developer_project)).to eq(true)
3744      expect(user.can?(:admin_issue, reporter_project)).to eq(true)
3745    end
3746
3747    it 'does not include for which the user access level is below reporter' do
3748      project = create(:project)
3749      guest_project = create(:project) { |p| p.add_guest(user) }
3750
3751      expect(user.projects_where_can_admin_issues.to_a).to be_empty
3752      expect(user.can?(:admin_issue, guest_project)).to eq(false)
3753      expect(user.can?(:admin_issue, project)).to eq(false)
3754    end
3755
3756    it 'does not include archived projects' do
3757      project = create(:project, :archived)
3758
3759      expect(user.projects_where_can_admin_issues.to_a).to be_empty
3760      expect(user.can?(:admin_issue, project)).to eq(false)
3761    end
3762
3763    it 'does not include projects for which issues are disabled' do
3764      project = create(:project, :issues_disabled)
3765
3766      expect(user.projects_where_can_admin_issues.to_a).to be_empty
3767      expect(user.can?(:admin_issue, project)).to eq(false)
3768    end
3769  end
3770
3771  describe '#ci_owned_runners' do
3772    let(:user) { create(:user) }
3773
3774    shared_examples :nested_groups_owner do
3775      context 'when the user is the owner of a multi-level group' do
3776        before do
3777          set_permissions_for_users
3778        end
3779
3780        it 'loads all the runners in the tree of groups' do
3781          expect(user.ci_owned_runners).to contain_exactly(runner, group_runner)
3782        end
3783
3784        it 'returns true for owns_runner?' do
3785          expect(user.owns_runner?(runner)).to eq(true)
3786          expect(user.owns_runner?(group_runner)).to eq(true)
3787        end
3788      end
3789    end
3790
3791    shared_examples :group_owner do
3792      context 'when the user is the owner of a one level group' do
3793        before do
3794          group.add_owner(user)
3795        end
3796
3797        it 'loads the runners in the group' do
3798          expect(user.ci_owned_runners).to contain_exactly(group_runner)
3799        end
3800
3801        it 'returns true for owns_runner?' do
3802          expect(user.owns_runner?(group_runner)).to eq(true)
3803        end
3804      end
3805    end
3806
3807    shared_examples :project_owner do
3808      context 'when the user is the owner of a project' do
3809        it 'loads the runner belonging to the project' do
3810          expect(user.ci_owned_runners).to contain_exactly(runner)
3811        end
3812
3813        it 'returns true for owns_runner?' do
3814          expect(user.owns_runner?(runner)).to eq(true)
3815        end
3816      end
3817    end
3818
3819    shared_examples :project_member do
3820      context 'when the user is a maintainer' do
3821        before do
3822          add_user(:maintainer)
3823        end
3824
3825        it 'loads the runners of the project' do
3826          expect(user.ci_owned_runners).to contain_exactly(project_runner)
3827        end
3828
3829        it 'returns true for owns_runner?' do
3830          expect(user.owns_runner?(project_runner)).to eq(true)
3831        end
3832      end
3833
3834      context 'when the user is a developer' do
3835        before do
3836          add_user(:developer)
3837        end
3838
3839        it 'does not load any runner' do
3840          expect(user.ci_owned_runners).to be_empty
3841        end
3842
3843        it 'returns false for owns_runner?' do
3844          expect(user.owns_runner?(project_runner)).to eq(false)
3845        end
3846      end
3847
3848      context 'when the user is a reporter' do
3849        before do
3850          add_user(:reporter)
3851        end
3852
3853        it 'does not load any runner' do
3854          expect(user.ci_owned_runners).to be_empty
3855        end
3856
3857        it 'returns false for owns_runner?' do
3858          expect(user.owns_runner?(project_runner)).to eq(false)
3859        end
3860      end
3861
3862      context 'when the user is a guest' do
3863        before do
3864          add_user(:guest)
3865        end
3866
3867        it 'does not load any runner' do
3868          expect(user.ci_owned_runners).to be_empty
3869        end
3870
3871        it 'returns false for owns_runner?' do
3872          expect(user.owns_runner?(project_runner)).to eq(false)
3873        end
3874      end
3875    end
3876
3877    shared_examples :group_member do
3878      context 'when the user is a maintainer' do
3879        before do
3880          add_user(:maintainer)
3881        end
3882
3883        it 'does not load the runners of the group' do
3884          expect(user.ci_owned_runners).to be_empty
3885        end
3886
3887        it 'returns false for owns_runner?' do
3888          expect(user.owns_runner?(runner)).to eq(false)
3889        end
3890      end
3891
3892      context 'when the user is a developer' do
3893        before do
3894          add_user(:developer)
3895        end
3896
3897        it 'does not load any runner' do
3898          expect(user.ci_owned_runners).to be_empty
3899        end
3900
3901        it 'returns false for owns_runner?' do
3902          expect(user.owns_runner?(runner)).to eq(false)
3903        end
3904      end
3905
3906      context 'when the user is a reporter' do
3907        before do
3908          add_user(:reporter)
3909        end
3910
3911        it 'does not load any runner' do
3912          expect(user.ci_owned_runners).to be_empty
3913        end
3914
3915        it 'returns false for owns_runner?' do
3916          expect(user.owns_runner?(runner)).to eq(false)
3917        end
3918      end
3919
3920      context 'when the user is a guest' do
3921        before do
3922          add_user(:guest)
3923        end
3924
3925        it 'does not load any runner' do
3926          expect(user.ci_owned_runners).to be_empty
3927        end
3928
3929        it 'returns false for owns_runner?' do
3930          expect(user.owns_runner?(runner)).to eq(false)
3931        end
3932      end
3933    end
3934
3935    context 'without any projects nor groups' do
3936      it 'does not load any runner' do
3937        expect(user.ci_owned_runners).to be_empty
3938      end
3939
3940      it 'returns false for owns_runner?' do
3941        expect(user.owns_runner?(create(:ci_runner))).to eq(false)
3942      end
3943    end
3944
3945    context 'with runner in a personal project' do
3946      let!(:namespace) { create(:user_namespace, owner: user) }
3947      let!(:project) { create(:project, namespace: namespace) }
3948      let!(:runner) { create(:ci_runner, :project, projects: [project]) }
3949
3950      it_behaves_like :project_owner
3951    end
3952
3953    context 'with group runner in a non owned group' do
3954      let!(:group) { create(:group) }
3955      let!(:runner) { create(:ci_runner, :group, groups: [group]) }
3956
3957      def add_user(access)
3958        group.add_user(user, access)
3959      end
3960
3961      it_behaves_like :group_member
3962    end
3963
3964    context 'with group runner in an owned group' do
3965      let!(:group) { create(:group) }
3966      let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
3967
3968      it_behaves_like :group_owner
3969    end
3970
3971    context 'with group runner in an owned group and group runner in a different owner subgroup' do
3972      let!(:group) { create(:group) }
3973      let!(:runner) { create(:ci_runner, :group, groups: [group]) }
3974      let!(:subgroup) { create(:group, parent: group) }
3975      let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
3976      let!(:another_user) { create(:user) }
3977
3978      def set_permissions_for_users
3979        group.add_owner(user)
3980        subgroup.add_owner(another_user)
3981      end
3982
3983      it_behaves_like :nested_groups_owner
3984    end
3985
3986    context 'with personal project runner in an an owned group and a group runner in that same group' do
3987      let!(:group) { create(:group) }
3988      let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
3989      let!(:project) { create(:project, group: group) }
3990      let!(:runner) { create(:ci_runner, :project, projects: [project]) }
3991
3992      def set_permissions_for_users
3993        group.add_owner(user)
3994      end
3995
3996      it_behaves_like :nested_groups_owner
3997    end
3998
3999    context 'with personal project runner in an owned group and a group runner in a subgroup' do
4000      let!(:group) { create(:group) }
4001      let!(:subgroup) { create(:group, parent: group) }
4002      let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
4003      let!(:project) { create(:project, group: group) }
4004      let!(:runner) { create(:ci_runner, :project, projects: [project]) }
4005
4006      def set_permissions_for_users
4007        group.add_owner(user)
4008      end
4009
4010      it_behaves_like :nested_groups_owner
4011    end
4012
4013    context 'with personal project runner in an owned group in an owned namespace and a group runner in that group' do
4014      let!(:namespace) { create(:user_namespace, owner: user) }
4015      let!(:group) { create(:group) }
4016      let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
4017      let!(:project) { create(:project, namespace: namespace, group: group) }
4018      let!(:runner) { create(:ci_runner, :project, projects: [project]) }
4019
4020      def set_permissions_for_users
4021        group.add_owner(user)
4022      end
4023
4024      it_behaves_like :nested_groups_owner
4025    end
4026
4027    context 'with personal project runner in an owned namespace, an owned group, a subgroup and a group runner in that subgroup' do
4028      let!(:namespace) { create(:user_namespace, owner: user) }
4029      let!(:group) { create(:group) }
4030      let!(:subgroup) { create(:group, parent: group) }
4031      let!(:group_runner) { create(:ci_runner, :group, groups: [subgroup]) }
4032      let!(:project) { create(:project, namespace: namespace, group: group) }
4033      let!(:runner) { create(:ci_runner, :project, projects: [project]) }
4034
4035      def set_permissions_for_users
4036        group.add_owner(user)
4037      end
4038
4039      it_behaves_like :nested_groups_owner
4040    end
4041
4042    context 'with a project runner that belong to projects that belong to a not owned group' do
4043      let!(:group) { create(:group) }
4044      let!(:project) { create(:project, group: group) }
4045      let!(:project_runner) { create(:ci_runner, :project, projects: [project]) }
4046
4047      def add_user(access)
4048        project.add_user(user, access)
4049      end
4050
4051      it_behaves_like :project_member
4052    end
4053
4054    context 'with project runners that belong to projects that do not belong to any group' do
4055      let!(:project) { create(:project) }
4056      let!(:runner) { create(:ci_runner, :project, projects: [project]) }
4057
4058      it 'does not load any runner' do
4059        expect(user.ci_owned_runners).to be_empty
4060      end
4061    end
4062
4063    context 'with a group runner that belongs to a subgroup of a group owned by another user' do
4064      let!(:group) { create(:group) }
4065      let!(:subgroup) { create(:group, parent: group) }
4066      let!(:runner) { create(:ci_runner, :group, groups: [subgroup]) }
4067      let!(:another_user) { create(:user) }
4068
4069      def add_user(access)
4070        subgroup.add_user(user, access)
4071        group.add_user(another_user, :owner)
4072      end
4073
4074      it_behaves_like :group_member
4075    end
4076  end
4077
4078  describe '#projects_with_reporter_access_limited_to' do
4079    let(:project1) { create(:project) }
4080    let(:project2) { create(:project) }
4081    let(:user) { create(:user) }
4082
4083    before do
4084      project1.add_reporter(user)
4085      project2.add_guest(user)
4086    end
4087
4088    it 'returns the projects when using a single project ID' do
4089      projects = user.projects_with_reporter_access_limited_to(project1.id)
4090
4091      expect(projects).to eq([project1])
4092    end
4093
4094    it 'returns the projects when using an Array of project IDs' do
4095      projects = user.projects_with_reporter_access_limited_to([project1.id])
4096
4097      expect(projects).to eq([project1])
4098    end
4099
4100    it 'returns the projects when using an ActiveRecord relation' do
4101      projects = user
4102        .projects_with_reporter_access_limited_to(Project.select(:id))
4103
4104      expect(projects).to eq([project1])
4105    end
4106
4107    it 'does not return projects you do not have reporter access to' do
4108      projects = user.projects_with_reporter_access_limited_to(project2.id)
4109
4110      expect(projects).to be_empty
4111    end
4112  end
4113
4114  describe '#all_expanded_groups' do
4115    # foo/bar would also match foo/barbaz instead of just foo/bar and foo/bar/baz
4116    let!(:user) { create(:user) }
4117
4118    #                group
4119    #        _______ (foo) _______
4120    #       |                     |
4121    #       |                     |
4122    # nested_group_1        nested_group_2
4123    # (bar)                 (barbaz)
4124    #       |                     |
4125    #       |                     |
4126    # nested_group_1_1      nested_group_2_1
4127    # (baz)                 (baz)
4128    #
4129    let!(:group) { create :group }
4130    let!(:nested_group_1) { create :group, parent: group, name: 'bar' }
4131    let!(:nested_group_1_1) { create :group, parent: nested_group_1, name: 'baz' }
4132    let!(:nested_group_2) { create :group, parent: group, name: 'barbaz' }
4133    let!(:nested_group_2_1) { create :group, parent: nested_group_2, name: 'baz' }
4134
4135    subject { user.all_expanded_groups }
4136
4137    context 'user is not a member of any group' do
4138      it 'returns an empty array' do
4139        is_expected.to eq([])
4140      end
4141    end
4142
4143    context 'user is member of all groups' do
4144      before do
4145        group.add_reporter(user)
4146        nested_group_1.add_developer(user)
4147        nested_group_1_1.add_maintainer(user)
4148        nested_group_2.add_developer(user)
4149        nested_group_2_1.add_maintainer(user)
4150      end
4151
4152      it 'returns all groups' do
4153        is_expected.to match_array [
4154          group,
4155          nested_group_1, nested_group_1_1,
4156          nested_group_2, nested_group_2_1
4157        ]
4158      end
4159    end
4160
4161    context 'user is member of the top group' do
4162      before do
4163        group.add_owner(user)
4164      end
4165
4166      it 'returns all groups' do
4167        is_expected.to match_array [
4168          group,
4169          nested_group_1, nested_group_1_1,
4170          nested_group_2, nested_group_2_1
4171        ]
4172      end
4173    end
4174
4175    context 'user is member of the first child (internal node), branch 1' do
4176      before do
4177        nested_group_1.add_owner(user)
4178      end
4179
4180      it 'returns the groups in the hierarchy' do
4181        is_expected.to match_array [
4182          group,
4183          nested_group_1, nested_group_1_1
4184        ]
4185      end
4186    end
4187
4188    context 'user is member of the first child (internal node), branch 2' do
4189      before do
4190        nested_group_2.add_owner(user)
4191      end
4192
4193      it 'returns the groups in the hierarchy' do
4194        is_expected.to match_array [
4195          group,
4196          nested_group_2, nested_group_2_1
4197        ]
4198      end
4199    end
4200
4201    context 'user is member of the last child (leaf node)' do
4202      before do
4203        nested_group_1_1.add_owner(user)
4204      end
4205
4206      it 'returns the groups in the hierarchy' do
4207        is_expected.to match_array [
4208          group,
4209          nested_group_1, nested_group_1_1
4210        ]
4211      end
4212    end
4213
4214    context 'when the user is not saved' do
4215      let(:user) { build(:user) }
4216
4217      it 'returns empty when there are no groups or ancestor groups for the user' do
4218        is_expected.to eq([])
4219      end
4220    end
4221  end
4222
4223  describe '#refresh_authorized_projects', :clean_gitlab_redis_shared_state do
4224    let(:project1) { create(:project) }
4225    let(:project2) { create(:project) }
4226    let(:user) { create(:user) }
4227
4228    before do
4229      project1.add_reporter(user)
4230      project2.add_guest(user)
4231
4232      user.project_authorizations.delete_all
4233      user.refresh_authorized_projects
4234    end
4235
4236    it 'refreshes the list of authorized projects' do
4237      expect(user.project_authorizations.count).to eq(2)
4238    end
4239
4240    it 'stores the correct access levels' do
4241      expect(user.project_authorizations.where(access_level: Gitlab::Access::GUEST).exists?).to eq(true)
4242      expect(user.project_authorizations.where(access_level: Gitlab::Access::REPORTER).exists?).to eq(true)
4243    end
4244  end
4245
4246  describe '#remove_project_authorizations' do
4247    let_it_be(:project1) { create(:project) }
4248    let_it_be(:project2) { create(:project) }
4249    let_it_be(:project3) { create(:project) }
4250    let_it_be(:user) { create(:user) }
4251
4252    it 'removes the project authorizations of the user, in specified projects' do
4253      create(:project_authorization, user: user, project: project1)
4254      create(:project_authorization, user: user, project: project2)
4255      create(:project_authorization, user: user, project: project3)
4256
4257      user.remove_project_authorizations([project1.id, project2.id])
4258
4259      expect(user.project_authorizations.pluck(:project_id)).to match_array([project3.id])
4260    end
4261  end
4262
4263  describe '#access_level=' do
4264    let(:user) { build(:user) }
4265
4266    it 'does nothing for an invalid access level' do
4267      user.access_level = :invalid_access_level
4268
4269      expect(user.access_level).to eq(:regular)
4270      expect(user.admin).to be false
4271    end
4272
4273    it "assigns the 'admin' access level" do
4274      user.access_level = :admin
4275
4276      expect(user.access_level).to eq(:admin)
4277      expect(user.admin).to be true
4278    end
4279
4280    it "doesn't clear existing access levels when an invalid access level is passed in" do
4281      user.access_level = :admin
4282      user.access_level = :invalid_access_level
4283
4284      expect(user.access_level).to eq(:admin)
4285      expect(user.admin).to be true
4286    end
4287
4288    it 'accepts string values in addition to symbols' do
4289      user.access_level = 'admin'
4290
4291      expect(user.access_level).to eq(:admin)
4292      expect(user.admin).to be true
4293    end
4294  end
4295
4296  describe '#can_read_all_resources?', :request_store do
4297    it 'returns false for regular user' do
4298      user = build_stubbed(:user)
4299
4300      expect(user.can_read_all_resources?).to be_falsy
4301    end
4302
4303    context 'for admin user' do
4304      include_context 'custom session'
4305
4306      let(:user) { build_stubbed(:user, :admin) }
4307
4308      context 'when admin mode is disabled' do
4309        it 'returns false' do
4310          expect(user.can_read_all_resources?).to be_falsy
4311        end
4312      end
4313
4314      context 'when admin mode is enabled' do
4315        before do
4316          Gitlab::Auth::CurrentUserMode.new(user).request_admin_mode!
4317          Gitlab::Auth::CurrentUserMode.new(user).enable_admin_mode!(password: user.password)
4318        end
4319
4320        it 'returns true' do
4321          expect(user.can_read_all_resources?).to be_truthy
4322        end
4323      end
4324    end
4325  end
4326
4327  describe '#can_admin_all_resources?', :request_store do
4328    it 'returns false for regular user' do
4329      user = build_stubbed(:user)
4330
4331      expect(user.can_admin_all_resources?).to be_falsy
4332    end
4333
4334    context 'for admin user' do
4335      include_context 'custom session'
4336
4337      let(:user) { build_stubbed(:user, :admin) }
4338
4339      context 'when admin mode is disabled' do
4340        it 'returns false' do
4341          expect(user.can_admin_all_resources?).to be_falsy
4342        end
4343      end
4344
4345      context 'when admin mode is enabled' do
4346        before do
4347          Gitlab::Auth::CurrentUserMode.new(user).request_admin_mode!
4348          Gitlab::Auth::CurrentUserMode.new(user).enable_admin_mode!(password: user.password)
4349        end
4350
4351        it 'returns true' do
4352          expect(user.can_admin_all_resources?).to be_truthy
4353        end
4354      end
4355    end
4356  end
4357
4358  describe '.ghost' do
4359    it "creates a ghost user if one isn't already present" do
4360      ghost = described_class.ghost
4361
4362      expect(ghost).to be_ghost
4363      expect(ghost).to be_persisted
4364      expect(ghost.namespace).not_to be_nil
4365      expect(ghost.namespace).to be_persisted
4366      expect(ghost.user_type).to eq 'ghost'
4367    end
4368
4369    it 'does not create a second ghost user if one is already present' do
4370      expect do
4371        described_class.ghost
4372        described_class.ghost
4373      end.to change { described_class.count }.by(1)
4374      expect(described_class.ghost).to eq(described_class.ghost)
4375    end
4376
4377    context "when a regular user exists with the username 'ghost'" do
4378      it 'creates a ghost user with a non-conflicting username' do
4379        create(:user, username: 'ghost')
4380        ghost = described_class.ghost
4381
4382        expect(ghost).to be_persisted
4383        expect(ghost.username).to eq('ghost1')
4384      end
4385    end
4386
4387    context "when a regular user exists with the email 'ghost@example.com'" do
4388      it 'creates a ghost user with a non-conflicting email' do
4389        create(:user, email: 'ghost@example.com')
4390        ghost = described_class.ghost
4391
4392        expect(ghost).to be_persisted
4393        expect(ghost.email).to eq('ghost1@example.com')
4394      end
4395    end
4396
4397    context 'when a domain allowlist is in place' do
4398      before do
4399        stub_application_setting(domain_allowlist: ['gitlab.com'])
4400      end
4401
4402      it 'creates a ghost user' do
4403        expect(described_class.ghost).to be_persisted
4404      end
4405    end
4406  end
4407
4408  describe '#update_two_factor_requirement' do
4409    let(:user) { create :user }
4410
4411    context 'with 2FA requirement on groups' do
4412      let(:group1) { create :group, require_two_factor_authentication: true, two_factor_grace_period: 23 }
4413      let(:group2) { create :group, require_two_factor_authentication: true, two_factor_grace_period: 32 }
4414
4415      before do
4416        group1.add_user(user, GroupMember::OWNER)
4417        group2.add_user(user, GroupMember::OWNER)
4418
4419        user.update_two_factor_requirement
4420      end
4421
4422      it 'requires 2FA' do
4423        expect(user.require_two_factor_authentication_from_group).to be true
4424      end
4425
4426      it 'uses the shortest grace period' do
4427        expect(user.two_factor_grace_period).to be 23
4428      end
4429    end
4430
4431    context 'with 2FA requirement from expanded groups' do
4432      let!(:group1) { create :group, require_two_factor_authentication: true }
4433      let!(:group1a) { create :group, parent: group1 }
4434
4435      before do
4436        group1a.add_user(user, GroupMember::OWNER)
4437
4438        user.update_two_factor_requirement
4439      end
4440
4441      it 'requires 2FA' do
4442        expect(user.require_two_factor_authentication_from_group).to be true
4443      end
4444    end
4445
4446    context 'with 2FA requirement on nested child group' do
4447      let!(:group1) { create :group, require_two_factor_authentication: false }
4448      let!(:group1a) { create :group, require_two_factor_authentication: true, parent: group1 }
4449
4450      before do
4451        group1.add_user(user, GroupMember::OWNER)
4452
4453        user.update_two_factor_requirement
4454      end
4455
4456      it 'requires 2FA' do
4457        expect(user.require_two_factor_authentication_from_group).to be true
4458      end
4459    end
4460
4461    context "with 2FA requirement from shared project's group" do
4462      let!(:group1) { create :group, require_two_factor_authentication: true }
4463      let!(:group2) { create :group }
4464      let(:shared_project) { create(:project, namespace: group1) }
4465
4466      before do
4467        shared_project.project_group_links.create!(
4468          group: group2,
4469          group_access: ProjectGroupLink.default_access
4470        )
4471
4472        group2.add_user(user, GroupMember::OWNER)
4473      end
4474
4475      it 'does not require 2FA' do
4476        user.update_two_factor_requirement
4477
4478        expect(user.require_two_factor_authentication_from_group).to be false
4479      end
4480    end
4481
4482    context 'without 2FA requirement on groups' do
4483      let(:group) { create :group }
4484
4485      before do
4486        group.add_user(user, GroupMember::OWNER)
4487
4488        user.update_two_factor_requirement
4489      end
4490
4491      it 'does not require 2FA' do
4492        expect(user.require_two_factor_authentication_from_group).to be false
4493      end
4494
4495      it 'falls back to the default grace period' do
4496        expect(user.two_factor_grace_period).to be 48
4497      end
4498    end
4499
4500    context 'when the user is not saved' do
4501      let(:user) { build(:user) }
4502
4503      it 'does not raise an ActiveRecord::StatementInvalid statement exception' do
4504        expect { user.update_two_factor_requirement }.not_to raise_error
4505      end
4506    end
4507  end
4508
4509  describe '#source_groups_of_two_factor_authentication_requirement' do
4510    let_it_be(:group_not_requiring_2FA) { create :group }
4511
4512    let(:user) { create :user }
4513
4514    before do
4515      group.add_user(user, GroupMember::OWNER)
4516      group_not_requiring_2FA.add_user(user, GroupMember::OWNER)
4517    end
4518
4519    context 'when user is direct member of group requiring 2FA' do
4520      let_it_be(:group) { create :group, require_two_factor_authentication: true }
4521
4522      it 'returns group requiring 2FA' do
4523        expect(user.source_groups_of_two_factor_authentication_requirement).to contain_exactly(group)
4524      end
4525    end
4526
4527    context 'when user is member of group which parent requires 2FA' do
4528      let_it_be(:parent_group) { create :group, require_two_factor_authentication: true }
4529      let_it_be(:group) { create :group, parent: parent_group }
4530
4531      it 'returns group requiring 2FA' do
4532        expect(user.source_groups_of_two_factor_authentication_requirement).to contain_exactly(group)
4533      end
4534    end
4535
4536    context 'when user is member of group which child requires 2FA' do
4537      let_it_be(:group) { create :group }
4538      let_it_be(:child_group) { create :group, require_two_factor_authentication: true, parent: group }
4539
4540      it 'returns group requiring 2FA' do
4541        expect(user.source_groups_of_two_factor_authentication_requirement).to contain_exactly(group)
4542      end
4543    end
4544  end
4545
4546  describe '.active' do
4547    before do
4548      described_class.ghost
4549      create(:user, name: 'user', state: 'active')
4550      create(:user, name: 'user', state: 'blocked')
4551    end
4552
4553    it 'only counts active and non internal users' do
4554      expect(described_class.active.count).to eq(1)
4555    end
4556  end
4557
4558  describe 'preferred language' do
4559    it 'is English by default' do
4560      user = create(:user)
4561
4562      expect(user.preferred_language).to eq('en')
4563    end
4564  end
4565
4566  describe '#invalidate_issue_cache_counts' do
4567    let(:user) { build_stubbed(:user) }
4568
4569    it 'invalidates cache for issue counter' do
4570      cache_mock = double
4571
4572      expect(cache_mock).to receive(:delete).with(['users', user.id, 'assigned_open_issues_count'])
4573
4574      allow(Rails).to receive(:cache).and_return(cache_mock)
4575
4576      user.invalidate_issue_cache_counts
4577    end
4578  end
4579
4580  describe '#invalidate_merge_request_cache_counts' do
4581    let(:user) { build_stubbed(:user) }
4582
4583    it 'invalidates cache for Merge Request counter' do
4584      cache_mock = double
4585
4586      expect(cache_mock).to receive(:delete).with(['users', user.id, 'assigned_open_merge_requests_count'])
4587      expect(cache_mock).to receive(:delete).with(['users', user.id, 'review_requested_open_merge_requests_count'])
4588
4589      allow(Rails).to receive(:cache).and_return(cache_mock)
4590
4591      user.invalidate_merge_request_cache_counts
4592    end
4593  end
4594
4595  describe '#invalidate_personal_projects_count' do
4596    let(:user) { build_stubbed(:user) }
4597
4598    it 'invalidates cache for personal projects counter' do
4599      cache_mock = double
4600
4601      expect(cache_mock).to receive(:delete).with(['users', user.id, 'personal_projects_count'])
4602
4603      allow(Rails).to receive(:cache).and_return(cache_mock)
4604
4605      user.invalidate_personal_projects_count
4606    end
4607  end
4608
4609  describe '#allow_password_authentication_for_web?' do
4610    context 'regular user' do
4611      let(:user) { build(:user) }
4612
4613      it 'returns true when password authentication is enabled for the web interface' do
4614        expect(user.allow_password_authentication_for_web?).to be_truthy
4615      end
4616
4617      it 'returns false when password authentication is disabled for the web interface' do
4618        stub_application_setting(password_authentication_enabled_for_web: false)
4619
4620        expect(user.allow_password_authentication_for_web?).to be_falsey
4621      end
4622    end
4623
4624    it 'returns false for ldap user' do
4625      user = create(:omniauth_user, provider: 'ldapmain')
4626
4627      expect(user.allow_password_authentication_for_web?).to be_falsey
4628    end
4629  end
4630
4631  describe '#allow_password_authentication_for_git?' do
4632    context 'regular user' do
4633      let(:user) { build(:user) }
4634
4635      it 'returns true when password authentication is enabled for Git' do
4636        expect(user.allow_password_authentication_for_git?).to be_truthy
4637      end
4638
4639      it 'returns false when password authentication is disabled Git' do
4640        stub_application_setting(password_authentication_enabled_for_git: false)
4641
4642        expect(user.allow_password_authentication_for_git?).to be_falsey
4643      end
4644    end
4645
4646    it 'returns false for ldap user' do
4647      user = create(:omniauth_user, provider: 'ldapmain')
4648
4649      expect(user.allow_password_authentication_for_git?).to be_falsey
4650    end
4651  end
4652
4653  describe '#assigned_open_merge_requests_count' do
4654    it 'returns number of open merge requests from non-archived projects' do
4655      user    = create(:user)
4656      project = create(:project, :public)
4657      archived_project = create(:project, :public, :archived)
4658
4659      create(:merge_request, source_project: project, author: user, assignees: [user])
4660      create(:merge_request, :closed, source_project: project, author: user, assignees: [user])
4661      create(:merge_request, source_project: archived_project, author: user, assignees: [user])
4662
4663      expect(user.assigned_open_merge_requests_count(force: true)).to eq 1
4664    end
4665  end
4666
4667  describe '#review_requested_open_merge_requests_count' do
4668    it 'returns number of open merge requests from non-archived projects' do
4669      user    = create(:user)
4670      project = create(:project, :public)
4671      archived_project = create(:project, :public, :archived)
4672
4673      create(:merge_request, source_project: project, author: user, reviewers: [user])
4674      create(:merge_request, :closed, source_project: project, author: user, reviewers: [user])
4675      create(:merge_request, source_project: archived_project, author: user, reviewers: [user])
4676
4677      expect(user.review_requested_open_merge_requests_count(force: true)).to eq 1
4678    end
4679  end
4680
4681  describe '#assigned_open_issues_count' do
4682    it 'returns number of open issues from non-archived projects' do
4683      user    = create(:user)
4684      project = create(:project, :public)
4685      archived_project = create(:project, :public, :archived)
4686
4687      create(:issue, project: project, author: user, assignees: [user])
4688      create(:issue, :closed, project: project, author: user, assignees: [user])
4689      create(:issue, project: archived_project, author: user, assignees: [user])
4690
4691      expect(user.assigned_open_issues_count(force: true)).to eq 1
4692    end
4693  end
4694
4695  describe '#personal_projects_count' do
4696    it 'returns the number of personal projects using a single query' do
4697      user = build(:user)
4698      projects = double(:projects, count: 1)
4699
4700      expect(user).to receive(:personal_projects).and_return(projects)
4701
4702      expect(user.personal_projects_count).to eq(1)
4703    end
4704  end
4705
4706  describe '#projects_limit_left' do
4707    it 'returns the number of projects that can be created by the user' do
4708      user = build(:user)
4709
4710      allow(user).to receive(:projects_limit).and_return(10)
4711      allow(user).to receive(:personal_projects_count).and_return(5)
4712
4713      expect(user.projects_limit_left).to eq(5)
4714    end
4715  end
4716
4717  describe '#ensure_namespace_correct' do
4718    context 'for a new user' do
4719      let(:user) { build(:user) }
4720
4721      it 'creates the namespace' do
4722        expect(user.namespace).to be_nil
4723
4724        user.save!
4725
4726        expect(user.namespace).not_to be_nil
4727        expect(user.namespace).to be_kind_of(Namespaces::UserNamespace)
4728      end
4729
4730      it 'creates the namespace setting' do
4731        user.save!
4732
4733        expect(user.namespace.namespace_settings).to be_persisted
4734      end
4735    end
4736
4737    context 'for an existing user' do
4738      let(:username) { 'foo' }
4739      let(:user) { create(:user, username: username) }
4740
4741      context 'when the user is updated' do
4742        context 'when the username or name is changed' do
4743          let(:new_username) { 'bar' }
4744
4745          it 'changes the namespace (just to compare to when username is not changed)' do
4746            expect do
4747              travel_to(1.second.from_now) do
4748                user.update!(username: new_username)
4749              end
4750            end.to change { user.namespace.updated_at }
4751          end
4752
4753          it 'updates the namespace path when the username was changed' do
4754            user.update!(username: new_username)
4755
4756            expect(user.namespace.path).to eq(new_username)
4757          end
4758
4759          it 'updates the namespace name if the name was changed' do
4760            user.update!(name: 'New name')
4761
4762            expect(user.namespace.name).to eq('New name')
4763          end
4764
4765          it 'updates nested routes for the namespace if the name was changed' do
4766            project = create(:project, namespace: user.namespace)
4767
4768            user.update!(name: 'New name')
4769
4770            expect(project.route.reload.name).to include('New name')
4771          end
4772
4773          context 'when there is a validation error (namespace name taken) while updating namespace' do
4774            let!(:conflicting_namespace) { create(:group, path: new_username) }
4775
4776            it 'causes the user save to fail' do
4777              expect(user.update(username: new_username)).to be_falsey
4778              expect(user.namespace.errors.messages[:path].first).to eq(_('has already been taken'))
4779            end
4780
4781            it 'adds the namespace errors to the user' do
4782              user.username = new_username
4783
4784              expect(user).to be_invalid
4785              expect(user.errors[:base]).to include('A user, alias, or group already exists with that username.')
4786            end
4787          end
4788        end
4789
4790        context 'when the username is not changed' do
4791          it 'does not change the namespace' do
4792            expect do
4793              user.update!(email: 'asdf@asdf.com')
4794            end.not_to change { user.namespace.updated_at }
4795          end
4796        end
4797      end
4798    end
4799  end
4800
4801  describe '#username_changed_hook' do
4802    context 'for a new user' do
4803      let(:user) { build(:user) }
4804
4805      it 'does not trigger system hook' do
4806        expect(user).not_to receive(:system_hook_service)
4807
4808        user.save!
4809      end
4810    end
4811
4812    context 'for an existing user' do
4813      let(:user) { create(:user, username: 'old-username') }
4814
4815      context 'when the username is changed' do
4816        let(:new_username) { 'very-new-name' }
4817
4818        it 'triggers the rename system hook' do
4819          system_hook_service = SystemHooksService.new
4820          expect(system_hook_service).to receive(:execute_hooks_for).with(user, :rename)
4821          expect(user).to receive(:system_hook_service).and_return(system_hook_service)
4822
4823          user.update!(username: new_username)
4824        end
4825      end
4826
4827      context 'when the username is not changed' do
4828        it 'does not trigger system hook' do
4829          expect(user).not_to receive(:system_hook_service)
4830
4831          user.update!(email: 'asdf@asdf.com')
4832        end
4833      end
4834    end
4835  end
4836
4837  describe '#will_save_change_to_login?' do
4838    let(:user) { create(:user, username: 'old-username', email: 'old-email@example.org') }
4839    let(:new_username) { 'new-name' }
4840    let(:new_email) { 'new-email@example.org' }
4841
4842    subject { user.will_save_change_to_login? }
4843
4844    context 'when the username is changed' do
4845      before do
4846        user.username = new_username
4847      end
4848
4849      it { is_expected.to be true }
4850    end
4851
4852    context 'when the email is changed' do
4853      before do
4854        user.email = new_email
4855      end
4856
4857      it { is_expected.to be true }
4858    end
4859
4860    context 'when both email and username are changed' do
4861      before do
4862        user.username = new_username
4863        user.email = new_email
4864      end
4865
4866      it { is_expected.to be true }
4867    end
4868
4869    context "when email and username aren't changed" do
4870      before do
4871        user.name = 'new_name'
4872      end
4873
4874      it { is_expected.to be_falsy }
4875    end
4876  end
4877
4878  describe '#sync_attribute?' do
4879    let(:user) { described_class.new }
4880
4881    context 'oauth user' do
4882      it 'returns true if name can be synced' do
4883        stub_omniauth_setting(sync_profile_attributes: %w(name location))
4884
4885        expect(user.sync_attribute?(:name)).to be_truthy
4886      end
4887
4888      it 'returns true if email can be synced' do
4889        stub_omniauth_setting(sync_profile_attributes: %w(name email))
4890
4891        expect(user.sync_attribute?(:email)).to be_truthy
4892      end
4893
4894      it 'returns true if location can be synced' do
4895        stub_omniauth_setting(sync_profile_attributes: %w(location email))
4896
4897        expect(user.sync_attribute?(:email)).to be_truthy
4898      end
4899
4900      it 'returns false if name can not be synced' do
4901        stub_omniauth_setting(sync_profile_attributes: %w(location email))
4902
4903        expect(user.sync_attribute?(:name)).to be_falsey
4904      end
4905
4906      it 'returns false if email can not be synced' do
4907        stub_omniauth_setting(sync_profile_attributes: %w(location name))
4908
4909        expect(user.sync_attribute?(:email)).to be_falsey
4910      end
4911
4912      it 'returns false if location can not be synced' do
4913        stub_omniauth_setting(sync_profile_attributes: %w(name email))
4914
4915        expect(user.sync_attribute?(:location)).to be_falsey
4916      end
4917
4918      it 'returns true for all syncable attributes if all syncable attributes can be synced' do
4919        stub_omniauth_setting(sync_profile_attributes: true)
4920
4921        expect(user.sync_attribute?(:name)).to be_truthy
4922        expect(user.sync_attribute?(:email)).to be_truthy
4923        expect(user.sync_attribute?(:location)).to be_truthy
4924      end
4925
4926      it 'returns false for all syncable attributes but email if no syncable attributes are declared' do
4927        expect(user.sync_attribute?(:name)).to be_falsey
4928        expect(user.sync_attribute?(:email)).to be_truthy
4929        expect(user.sync_attribute?(:location)).to be_falsey
4930      end
4931    end
4932
4933    context 'ldap user' do
4934      it 'returns true for email if ldap user' do
4935        allow(user).to receive(:ldap_user?).and_return(true)
4936
4937        expect(user.sync_attribute?(:name)).to be_falsey
4938        expect(user.sync_attribute?(:email)).to be_truthy
4939        expect(user.sync_attribute?(:location)).to be_falsey
4940      end
4941
4942      it 'returns true for email and location if ldap user and location declared as syncable' do
4943        allow(user).to receive(:ldap_user?).and_return(true)
4944        stub_omniauth_setting(sync_profile_attributes: %w(location))
4945
4946        expect(user.sync_attribute?(:name)).to be_falsey
4947        expect(user.sync_attribute?(:email)).to be_truthy
4948        expect(user.sync_attribute?(:location)).to be_truthy
4949      end
4950    end
4951  end
4952
4953  describe '#confirm_deletion_with_password?' do
4954    where(
4955      password_automatically_set: [true, false],
4956      ldap_user: [true, false],
4957      password_authentication_disabled: [true, false]
4958    )
4959
4960    with_them do
4961      let!(:user) { create(:user, password_automatically_set: password_automatically_set) }
4962      let!(:identity) { create(:identity, user: user) if ldap_user }
4963
4964      # Only confirm deletion with password if all inputs are false
4965      let(:expected) { !(password_automatically_set || ldap_user || password_authentication_disabled) }
4966
4967      before do
4968        stub_application_setting(password_authentication_enabled_for_web: !password_authentication_disabled)
4969        stub_application_setting(password_authentication_enabled_for_git: !password_authentication_disabled)
4970      end
4971
4972      it 'returns false unless all inputs are true' do
4973        expect(user.confirm_deletion_with_password?).to eq(expected)
4974      end
4975    end
4976  end
4977
4978  describe '#delete_async' do
4979    let(:user) { create(:user) }
4980    let(:deleted_by) { create(:user) }
4981
4982    it 'blocks the user then schedules them for deletion if a hard delete is specified' do
4983      expect(DeleteUserWorker).to receive(:perform_async).with(deleted_by.id, user.id, hard_delete: true)
4984
4985      user.delete_async(deleted_by: deleted_by, params: { hard_delete: true })
4986
4987      expect(user).to be_blocked
4988    end
4989
4990    it 'schedules user for deletion without blocking them' do
4991      expect(DeleteUserWorker).to receive(:perform_async).with(deleted_by.id, user.id, {})
4992
4993      user.delete_async(deleted_by: deleted_by)
4994
4995      expect(user).not_to be_blocked
4996    end
4997  end
4998
4999  describe '#max_member_access_for_project_ids' do
5000    shared_examples 'max member access for projects' do
5001      let(:user) { create(:user) }
5002      let(:group) { create(:group) }
5003      let(:owner_project) { create(:project, group: group) }
5004      let(:maintainer_project) { create(:project) }
5005      let(:reporter_project) { create(:project) }
5006      let(:developer_project) { create(:project) }
5007      let(:guest_project) { create(:project) }
5008      let(:no_access_project) { create(:project) }
5009
5010      let(:projects) do
5011        [owner_project, maintainer_project, reporter_project, developer_project, guest_project, no_access_project].map(&:id)
5012      end
5013
5014      let(:expected) do
5015        {
5016          owner_project.id => Gitlab::Access::OWNER,
5017          maintainer_project.id => Gitlab::Access::MAINTAINER,
5018          reporter_project.id => Gitlab::Access::REPORTER,
5019          developer_project.id => Gitlab::Access::DEVELOPER,
5020          guest_project.id => Gitlab::Access::GUEST,
5021          no_access_project.id => Gitlab::Access::NO_ACCESS
5022        }
5023      end
5024
5025      before do
5026        create(:group_member, user: user, group: group)
5027        maintainer_project.add_maintainer(user)
5028        reporter_project.add_reporter(user)
5029        developer_project.add_developer(user)
5030        guest_project.add_guest(user)
5031      end
5032
5033      it 'returns correct roles for different projects' do
5034        expect(user.max_member_access_for_project_ids(projects)).to eq(expected)
5035      end
5036    end
5037
5038    context 'with RequestStore enabled', :request_store do
5039      include_examples 'max member access for projects'
5040
5041      def access_levels(projects)
5042        user.max_member_access_for_project_ids(projects)
5043      end
5044
5045      it 'does not perform extra queries when asked for projects who have already been found' do
5046        access_levels(projects)
5047
5048        expect { access_levels(projects) }.not_to exceed_query_limit(0)
5049
5050        expect(access_levels(projects)).to eq(expected)
5051      end
5052
5053      it 'only requests the extra projects when uncached projects are passed' do
5054        second_maintainer_project = create(:project)
5055        second_developer_project = create(:project)
5056        second_maintainer_project.add_maintainer(user)
5057        second_developer_project.add_developer(user)
5058
5059        all_projects = projects + [second_maintainer_project.id, second_developer_project.id]
5060
5061        expected_all = expected.merge(second_maintainer_project.id => Gitlab::Access::MAINTAINER,
5062                                      second_developer_project.id => Gitlab::Access::DEVELOPER)
5063
5064        access_levels(projects)
5065
5066        queries = ActiveRecord::QueryRecorder.new { access_levels(all_projects) }
5067
5068        expect(queries.count).to eq(1)
5069        expect(queries.log_message).to match(/\W(#{second_maintainer_project.id}, #{second_developer_project.id})\W/)
5070        expect(access_levels(all_projects)).to eq(expected_all)
5071      end
5072    end
5073
5074    context 'with RequestStore disabled' do
5075      include_examples 'max member access for projects'
5076    end
5077  end
5078
5079  describe '#max_member_access_for_group_ids' do
5080    shared_examples 'max member access for groups' do
5081      let(:user) { create(:user) }
5082      let(:owner_group) { create(:group) }
5083      let(:maintainer_group) { create(:group) }
5084      let(:reporter_group) { create(:group) }
5085      let(:developer_group) { create(:group) }
5086      let(:guest_group) { create(:group) }
5087      let(:no_access_group) { create(:group) }
5088
5089      let(:groups) do
5090        [owner_group, maintainer_group, reporter_group, developer_group, guest_group, no_access_group].map(&:id)
5091      end
5092
5093      let(:expected) do
5094        {
5095          owner_group.id => Gitlab::Access::OWNER,
5096          maintainer_group.id => Gitlab::Access::MAINTAINER,
5097          reporter_group.id => Gitlab::Access::REPORTER,
5098          developer_group.id => Gitlab::Access::DEVELOPER,
5099          guest_group.id => Gitlab::Access::GUEST,
5100          no_access_group.id => Gitlab::Access::NO_ACCESS
5101        }
5102      end
5103
5104      before do
5105        owner_group.add_owner(user)
5106        maintainer_group.add_maintainer(user)
5107        reporter_group.add_reporter(user)
5108        developer_group.add_developer(user)
5109        guest_group.add_guest(user)
5110      end
5111
5112      it 'returns correct roles for different groups' do
5113        expect(user.max_member_access_for_group_ids(groups)).to eq(expected)
5114      end
5115    end
5116
5117    context 'with RequestStore enabled', :request_store do
5118      include_examples 'max member access for groups'
5119
5120      def access_levels(groups)
5121        user.max_member_access_for_group_ids(groups)
5122      end
5123
5124      it 'does not perform extra queries when asked for groups who have already been found' do
5125        access_levels(groups)
5126
5127        expect { access_levels(groups) }.not_to exceed_query_limit(0)
5128
5129        expect(access_levels(groups)).to eq(expected)
5130      end
5131
5132      it 'only requests the extra groups when uncached groups are passed' do
5133        second_maintainer_group = create(:group)
5134        second_developer_group = create(:group)
5135        second_maintainer_group.add_maintainer(user)
5136        second_developer_group.add_developer(user)
5137
5138        all_groups = groups + [second_maintainer_group.id, second_developer_group.id]
5139
5140        expected_all = expected.merge(second_maintainer_group.id => Gitlab::Access::MAINTAINER,
5141                                      second_developer_group.id => Gitlab::Access::DEVELOPER)
5142
5143        access_levels(groups)
5144
5145        queries = ActiveRecord::QueryRecorder.new { access_levels(all_groups) }
5146
5147        expect(queries.count).to eq(1)
5148        expect(queries.log_message).to match(/\W(#{second_maintainer_group.id}, #{second_developer_group.id})\W/)
5149        expect(access_levels(all_groups)).to eq(expected_all)
5150      end
5151    end
5152
5153    context 'with RequestStore disabled' do
5154      include_examples 'max member access for groups'
5155    end
5156  end
5157
5158  context 'changing a username' do
5159    let(:user) { create(:user, username: 'foo') }
5160
5161    it 'creates a redirect route' do
5162      expect { user.update!(username: 'bar') }
5163        .to change { RedirectRoute.where(path: 'foo').count }.by(1)
5164    end
5165
5166    it 'deletes the redirect when a user with the old username was created' do
5167      user.update!(username: 'bar')
5168
5169      expect { create(:user, username: 'foo') }
5170        .to change { RedirectRoute.where(path: 'foo').count }.by(-1)
5171    end
5172  end
5173
5174  describe '#required_terms_not_accepted?' do
5175    let(:user) { build(:user) }
5176    let(:project_bot) { create(:user, :project_bot) }
5177
5178    subject { user.required_terms_not_accepted? }
5179
5180    context 'when terms are not enforced' do
5181      it { is_expected.to be_falsey }
5182    end
5183
5184    context 'when terms are enforced' do
5185      before do
5186        enforce_terms
5187      end
5188
5189      it 'is not accepted by the user' do
5190        expect(subject).to be_truthy
5191      end
5192
5193      it 'is accepted by the user' do
5194        accept_terms(user)
5195
5196        expect(subject).to be_falsey
5197      end
5198
5199      it 'auto accepts the term for project bots' do
5200        expect(project_bot.required_terms_not_accepted?).to be_falsey
5201      end
5202    end
5203  end
5204
5205  describe '#increment_failed_attempts!' do
5206    subject(:user) { create(:user, failed_attempts: 0) }
5207
5208    it 'logs failed sign-in attempts' do
5209      expect { user.increment_failed_attempts! }.to change(user, :failed_attempts).from(0).to(1)
5210    end
5211
5212    it 'does not log failed sign-in attempts when in a GitLab read-only instance' do
5213      allow(Gitlab::Database).to receive(:read_only?) { true }
5214
5215      expect { user.increment_failed_attempts! }.not_to change(user, :failed_attempts)
5216    end
5217  end
5218
5219  describe '#requires_usage_stats_consent?' do
5220    let(:user) { create(:user, :admin, created_at: 8.days.ago) }
5221
5222    before do
5223      allow(user).to receive(:has_current_license?).and_return false
5224    end
5225
5226    context 'in single-user environment' do
5227      it 'requires user consent after one week' do
5228        create(:user, :ghost)
5229
5230        expect(user.requires_usage_stats_consent?).to be true
5231      end
5232
5233      it 'requires user consent after one week if there is another ghost user' do
5234        expect(user.requires_usage_stats_consent?).to be true
5235      end
5236
5237      it 'does not require consent in the first week' do
5238        user.created_at = 6.days.ago
5239
5240        expect(user.requires_usage_stats_consent?).to be false
5241      end
5242
5243      it 'does not require consent if usage stats were set by this user' do
5244        create(:application_setting, usage_stats_set_by_user_id: user.id)
5245
5246        expect(user.requires_usage_stats_consent?).to be false
5247      end
5248    end
5249
5250    context 'in multi-user environment' do
5251      before do
5252        create(:user)
5253      end
5254
5255      it 'does not require consent' do
5256        expect(user.requires_usage_stats_consent?).to be false
5257      end
5258    end
5259  end
5260
5261  context 'with uploads' do
5262    it_behaves_like 'model with uploads', false do
5263      let(:model_object) { create(:user, :with_avatar) }
5264      let(:upload_attribute) { :avatar }
5265      let(:uploader_class) { AttachmentUploader }
5266    end
5267  end
5268
5269  describe '.union_with_user' do
5270    context 'when no user ID is provided' do
5271      it 'returns the input relation' do
5272        user = create(:user)
5273
5274        expect(described_class.union_with_user).to eq([user])
5275      end
5276    end
5277
5278    context 'when a user ID is provided' do
5279      it 'includes the user object in the returned relation' do
5280        user1 = create(:user)
5281        user2 = create(:user)
5282        users = described_class.where(id: user1.id).union_with_user(user2.id)
5283
5284        expect(users).to include(user1)
5285        expect(users).to include(user2)
5286      end
5287
5288      it 'does not re-apply any WHERE conditions on the outer query' do
5289        relation = described_class.where(id: 1).union_with_user(2)
5290
5291        expect(relation.arel.where_sql).to be_nil
5292      end
5293    end
5294  end
5295
5296  describe '.optionally_search' do
5297    context 'using nil as the argument' do
5298      it 'returns the current relation' do
5299        user = create(:user)
5300
5301        expect(described_class.optionally_search).to eq([user])
5302      end
5303    end
5304
5305    context 'using an empty String as the argument' do
5306      it 'returns the current relation' do
5307        user = create(:user)
5308
5309        expect(described_class.optionally_search('')).to eq([user])
5310      end
5311    end
5312
5313    context 'using a non-empty String' do
5314      it 'returns users matching the search query' do
5315        user1 = create(:user)
5316        create(:user)
5317
5318        expect(described_class.optionally_search(user1.name)).to eq([user1])
5319      end
5320    end
5321  end
5322
5323  describe '.where_not_in' do
5324    context 'without an argument' do
5325      it 'returns the current relation' do
5326        user = create(:user)
5327
5328        expect(described_class.where_not_in).to eq([user])
5329      end
5330    end
5331
5332    context 'using a list of user IDs' do
5333      it 'excludes the users from the returned relation' do
5334        user1 = create(:user)
5335        user2 = create(:user)
5336
5337        expect(described_class.where_not_in([user2.id])).to eq([user1])
5338      end
5339    end
5340  end
5341
5342  describe '.reorder_by_name' do
5343    it 'reorders the input relation' do
5344      user1 = create(:user, name: 'A')
5345      user2 = create(:user, name: 'B')
5346
5347      expect(described_class.reorder_by_name).to eq([user1, user2])
5348    end
5349  end
5350
5351  describe '#notification_settings_for' do
5352    let(:user) { create(:user) }
5353    let(:source) { nil }
5354
5355    subject { user.notification_settings_for(source) }
5356
5357    context 'when source is nil' do
5358      it 'returns a blank global notification settings object' do
5359        expect(subject.source).to eq(nil)
5360        expect(subject.notification_email).to eq(nil)
5361        expect(subject.level).to eq('global')
5362      end
5363    end
5364
5365    context 'when source is a Group' do
5366      let(:group) { create(:group) }
5367
5368      subject { user.notification_settings_for(group, inherit: true) }
5369
5370      context 'when group has no existing notification settings' do
5371        context 'when group has no ancestors' do
5372          it 'will be a default Global notification setting' do
5373            expect(subject.notification_email).to eq(nil)
5374            expect(subject.level).to eq('global')
5375          end
5376        end
5377
5378        context 'when group has ancestors' do
5379          context 'when an ancestor has a level other than Global' do
5380            let(:ancestor) { create(:group) }
5381            let(:group) { create(:group, parent: ancestor) }
5382            let(:email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
5383
5384            before do
5385              create(:notification_setting, user: user, source: ancestor, level: 'participating', notification_email: email.email)
5386            end
5387
5388            it 'has the same level set' do
5389              expect(subject.level).to eq('participating')
5390            end
5391
5392            it 'has the same email set' do
5393              expect(subject.notification_email).to eq('ancestor@example.com')
5394            end
5395
5396            context 'when inherit is false' do
5397              subject { user.notification_settings_for(group) }
5398
5399              it 'does not inherit settings' do
5400                expect(subject.notification_email).to eq(nil)
5401                expect(subject.level).to eq('global')
5402              end
5403            end
5404          end
5405
5406          context 'when an ancestor has a Global level but has an email set' do
5407            let(:grand_ancestor) { create(:group) }
5408            let(:ancestor) { create(:group, parent: grand_ancestor) }
5409            let(:group) { create(:group, parent: ancestor) }
5410            let(:ancestor_email) { create(:email, :confirmed, email: 'ancestor@example.com', user: user) }
5411            let(:grand_email) { create(:email, :confirmed, email: 'grand@example.com', user: user) }
5412
5413            before do
5414              create(:notification_setting, user: user, source: grand_ancestor, level: 'participating', notification_email: grand_email.email)
5415              create(:notification_setting, user: user, source: ancestor, level: 'global', notification_email: ancestor_email.email)
5416            end
5417
5418            it 'has the same email set' do
5419              expect(subject.level).to eq('global')
5420              expect(subject.notification_email).to eq('ancestor@example.com')
5421            end
5422          end
5423        end
5424      end
5425    end
5426  end
5427
5428  describe '#notification_settings_for_groups' do
5429    let_it_be(:user) { create(:user) }
5430    let_it_be(:groups) { create_list(:group, 2) }
5431
5432    subject { user.notification_settings_for_groups(arg) }
5433
5434    before do
5435      groups.each do |group|
5436        group.add_maintainer(user)
5437      end
5438    end
5439
5440    shared_examples_for 'notification_settings_for_groups method' do
5441      it 'returns NotificationSetting objects for provided groups', :aggregate_failures do
5442        expect(subject.count).to eq(groups.count)
5443        expect(subject.map(&:source_id)).to match_array(groups.map(&:id))
5444      end
5445    end
5446
5447    context 'when given an ActiveRecord relationship' do
5448      let_it_be(:arg) { Group.where(id: groups.map(&:id)) }
5449
5450      it_behaves_like 'notification_settings_for_groups method'
5451
5452      it 'uses #select to maintain lazy querying behavior' do
5453        expect(arg).to receive(:select).and_call_original
5454
5455        subject
5456      end
5457    end
5458
5459    context 'when given an Array of Groups' do
5460      let_it_be(:arg) { groups }
5461
5462      it_behaves_like 'notification_settings_for_groups method'
5463    end
5464  end
5465
5466  describe '#notification_email_for' do
5467    let(:user) { create(:user) }
5468    let(:group) { create(:group) }
5469
5470    subject { user.notification_email_for(group) }
5471
5472    context 'when group is nil' do
5473      let(:group) { nil }
5474
5475      it 'returns global notification email' do
5476        is_expected.to eq(user.notification_email_or_default)
5477      end
5478    end
5479
5480    context 'when group has no notification email set' do
5481      it 'returns global notification email' do
5482        create(:notification_setting, user: user, source: group, notification_email: '')
5483
5484        is_expected.to eq(user.notification_email_or_default)
5485      end
5486    end
5487
5488    context 'when group has notification email set' do
5489      it 'returns group notification email' do
5490        group_notification_email = 'user+group@example.com'
5491        create(:email, :confirmed, user: user, email: group_notification_email)
5492        create(:notification_setting, user: user, source: group, notification_email: group_notification_email)
5493
5494        is_expected.to eq(group_notification_email)
5495      end
5496    end
5497  end
5498
5499  describe '#password_expired?' do
5500    let(:user) { build(:user, password_expires_at: password_expires_at) }
5501
5502    subject { user.password_expired? }
5503
5504    context 'when password_expires_at is not set' do
5505      let(:password_expires_at) {}
5506
5507      it 'returns false' do
5508        is_expected.to be_falsey
5509      end
5510    end
5511
5512    context 'when password_expires_at is in the past' do
5513      let(:password_expires_at) { 1.minute.ago }
5514
5515      it 'returns true' do
5516        is_expected.to be_truthy
5517      end
5518    end
5519
5520    context 'when password_expires_at is in the future' do
5521      let(:password_expires_at) { 1.minute.from_now }
5522
5523      it 'returns false' do
5524        is_expected.to be_falsey
5525      end
5526    end
5527  end
5528
5529  describe '#password_expired_if_applicable?' do
5530    let(:user) { build(:user, password_expires_at: password_expires_at) }
5531
5532    subject { user.password_expired_if_applicable? }
5533
5534    shared_examples 'password expired not applicable' do
5535      context 'when password_expires_at is not set' do
5536        let(:password_expires_at) {}
5537
5538        it 'returns false' do
5539          is_expected.to be_falsey
5540        end
5541      end
5542
5543      context 'when password_expires_at is in the past' do
5544        let(:password_expires_at) { 1.minute.ago }
5545
5546        it 'returns false' do
5547          is_expected.to be_falsey
5548        end
5549      end
5550
5551      context 'when password_expires_at is in the future' do
5552        let(:password_expires_at) { 1.minute.from_now }
5553
5554        it 'returns false' do
5555          is_expected.to be_falsey
5556        end
5557      end
5558    end
5559
5560    context 'with a regular user' do
5561      context 'when password_expires_at is not set' do
5562        let(:password_expires_at) {}
5563
5564        it 'returns false' do
5565          is_expected.to be_falsey
5566        end
5567      end
5568
5569      context 'when password_expires_at is in the past' do
5570        let(:password_expires_at) { 1.minute.ago }
5571
5572        it 'returns true' do
5573          is_expected.to be_truthy
5574        end
5575      end
5576
5577      context 'when password_expires_at is in the future' do
5578        let(:password_expires_at) { 1.minute.from_now }
5579
5580        it 'returns false' do
5581          is_expected.to be_falsey
5582        end
5583      end
5584    end
5585
5586    context 'when user is a bot' do
5587      before do
5588        allow(user).to receive(:bot?).and_return(true)
5589      end
5590
5591      it_behaves_like 'password expired not applicable'
5592    end
5593
5594    context 'when password_automatically_set is true' do
5595      let(:user) { create(:omniauth_user, provider: 'ldap')}
5596
5597      it_behaves_like 'password expired not applicable'
5598    end
5599
5600    context 'when allow_password_authentication is false' do
5601      before do
5602        allow(user).to receive(:allow_password_authentication?).and_return(false)
5603      end
5604
5605      it_behaves_like 'password expired not applicable'
5606    end
5607  end
5608
5609  describe '#read_only_attribute?' do
5610    context 'when synced attributes metadata is present' do
5611      it 'delegates to synced_attributes_metadata' do
5612        subject.build_user_synced_attributes_metadata
5613
5614        expect(subject.build_user_synced_attributes_metadata)
5615          .to receive(:read_only?).with(:email).and_return('return-value')
5616        expect(subject.read_only_attribute?(:email)).to eq('return-value')
5617      end
5618    end
5619
5620    context 'when synced attributes metadata is not present' do
5621      it 'is false for any attribute' do
5622        expect(subject.read_only_attribute?(:email)).to be_falsey
5623      end
5624    end
5625  end
5626
5627  describe '.active_without_ghosts' do
5628    let_it_be(:user1) { create(:user, :external) }
5629    let_it_be(:user2) { create(:user, state: 'blocked') }
5630    let_it_be(:user3) { create(:user, :ghost) }
5631    let_it_be(:user4) { create(:user, user_type: :support_bot) }
5632    let_it_be(:user5) { create(:user, state: 'blocked', user_type: :support_bot) }
5633    let_it_be(:user6) { create(:user, user_type: :automation_bot) }
5634
5635    it 'returns all active users including active bots but ghost users' do
5636      expect(described_class.active_without_ghosts).to match_array([user1, user4, user6])
5637    end
5638  end
5639
5640  describe '#dismissed_callout?' do
5641    let_it_be(:user, refind: true) { create(:user) }
5642    let_it_be(:feature_name) { Users::Callout.feature_names.each_key.first }
5643
5644    context 'when no callout dismissal record exists' do
5645      it 'returns false when no ignore_dismissal_earlier_than provided' do
5646        expect(user.dismissed_callout?(feature_name: feature_name)).to eq false
5647      end
5648    end
5649
5650    context 'when dismissed callout exists' do
5651      before_all do
5652        create(:callout, user: user, feature_name: feature_name, dismissed_at: 4.months.ago)
5653      end
5654
5655      it 'returns true when no ignore_dismissal_earlier_than provided' do
5656        expect(user.dismissed_callout?(feature_name: feature_name)).to eq true
5657      end
5658
5659      it 'returns true when ignore_dismissal_earlier_than is earlier than dismissed_at' do
5660        expect(user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: 6.months.ago)).to eq true
5661      end
5662
5663      it 'returns false when ignore_dismissal_earlier_than is later than dismissed_at' do
5664        expect(user.dismissed_callout?(feature_name: feature_name, ignore_dismissal_earlier_than: 3.months.ago)).to eq false
5665      end
5666    end
5667  end
5668
5669  describe '#find_or_initialize_callout' do
5670    let_it_be(:user, refind: true) { create(:user) }
5671    let_it_be(:feature_name) { Users::Callout.feature_names.each_key.first }
5672
5673    subject(:find_or_initialize_callout) { user.find_or_initialize_callout(feature_name) }
5674
5675    context 'when callout exists' do
5676      let!(:callout) { create(:callout, user: user, feature_name: feature_name) }
5677
5678      it 'returns existing callout' do
5679        expect(find_or_initialize_callout).to eq(callout)
5680      end
5681    end
5682
5683    context 'when callout does not exist' do
5684      context 'when feature name is valid' do
5685        it 'initializes a new callout' do
5686          expect(find_or_initialize_callout).to be_a_new(Users::Callout)
5687        end
5688
5689        it 'is valid' do
5690          expect(find_or_initialize_callout).to be_valid
5691        end
5692      end
5693
5694      context 'when feature name is not valid' do
5695        let(:feature_name) { 'notvalid' }
5696
5697        it 'initializes a new callout' do
5698          expect(find_or_initialize_callout).to be_a_new(Users::Callout)
5699        end
5700
5701        it 'is not valid' do
5702          expect(find_or_initialize_callout).not_to be_valid
5703        end
5704      end
5705    end
5706  end
5707
5708  describe '#dismissed_callout_for_group?' do
5709    let_it_be(:user, refind: true) { create(:user) }
5710    let_it_be(:group) { create(:group) }
5711    let_it_be(:feature_name) { Users::GroupCallout.feature_names.each_key.first }
5712
5713    context 'when no callout dismissal record exists' do
5714      it 'returns false when no ignore_dismissal_earlier_than provided' do
5715        expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group)).to eq false
5716      end
5717    end
5718
5719    context 'when dismissed callout exists' do
5720      before_all do
5721        create(:group_callout,
5722               user: user,
5723               group_id: group.id,
5724               feature_name: feature_name,
5725               dismissed_at: 4.months.ago)
5726      end
5727
5728      it 'returns true when no ignore_dismissal_earlier_than provided' do
5729        expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group)).to eq true
5730      end
5731
5732      it 'returns true when ignore_dismissal_earlier_than is earlier than dismissed_at' do
5733        expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group, ignore_dismissal_earlier_than: 6.months.ago)).to eq true
5734      end
5735
5736      it 'returns false when ignore_dismissal_earlier_than is later than dismissed_at' do
5737        expect(user.dismissed_callout_for_group?(feature_name: feature_name, group: group, ignore_dismissal_earlier_than: 3.months.ago)).to eq false
5738      end
5739    end
5740  end
5741
5742  describe '#find_or_initialize_group_callout' do
5743    let_it_be(:user, refind: true) { create(:user) }
5744    let_it_be(:group) { create(:group) }
5745    let_it_be(:feature_name) { Users::GroupCallout.feature_names.each_key.first }
5746
5747    subject(:callout_with_source) do
5748      user.find_or_initialize_group_callout(feature_name, group.id)
5749    end
5750
5751    context 'when callout exists' do
5752      let!(:callout) do
5753        create(:group_callout, user: user, feature_name: feature_name, group_id: group.id)
5754      end
5755
5756      it 'returns existing callout' do
5757        expect(callout_with_source).to eq(callout)
5758      end
5759    end
5760
5761    context 'when callout does not exist' do
5762      context 'when feature name is valid' do
5763        it 'initializes a new callout' do
5764          expect(callout_with_source).to be_a_new(Users::GroupCallout)
5765        end
5766
5767        it 'is valid' do
5768          expect(callout_with_source).to be_valid
5769        end
5770      end
5771
5772      context 'when feature name is not valid' do
5773        let(:feature_name) { 'notvalid' }
5774
5775        it 'initializes a new callout' do
5776          expect(callout_with_source).to be_a_new(Users::GroupCallout)
5777        end
5778
5779        it 'is not valid' do
5780          expect(callout_with_source).not_to be_valid
5781        end
5782      end
5783    end
5784  end
5785
5786  describe '#hook_attrs' do
5787    let(:user) { create(:user) }
5788    let(:user_attributes) do
5789      {
5790        id: user.id,
5791        name: user.name,
5792        username: user.username,
5793        avatar_url: user.avatar_url(only_path: false)
5794      }
5795    end
5796
5797    context 'with a public email' do
5798      it 'includes id, name, username, avatar_url, and email' do
5799        user.public_email = "hello@hello.com"
5800        user_attributes[:email] = user.public_email
5801        expect(user.hook_attrs).to eq(user_attributes)
5802      end
5803    end
5804
5805    context 'without a public email' do
5806      it "does not include email if user's email is private" do
5807        user_attributes[:email] = "[REDACTED]"
5808        expect(user.hook_attrs).to eq(user_attributes)
5809      end
5810    end
5811  end
5812
5813  describe 'user credit card validation' do
5814    context 'when user is initialized' do
5815      let(:user) { build(:user) }
5816
5817      it { expect(user.credit_card_validation).not_to be_present }
5818    end
5819
5820    context 'when create user without credit card validation' do
5821      let(:user) { create(:user) }
5822
5823      it { expect(user.credit_card_validation).not_to be_present }
5824    end
5825
5826    context 'when user credit card validation exists' do
5827      let(:user) { create(:user, :with_credit_card_validation) }
5828
5829      it { expect(user.credit_card_validation).to be_persisted }
5830    end
5831  end
5832
5833  describe 'user detail' do
5834    context 'when user is initialized' do
5835      let(:user) { build(:user) }
5836
5837      it { expect(user.user_detail).to be_present }
5838      it { expect(user.user_detail).not_to be_persisted }
5839    end
5840
5841    context 'when user detail exists' do
5842      let(:user) { create(:user, job_title: 'Engineer') }
5843
5844      it { expect(user.user_detail).to be_persisted }
5845    end
5846  end
5847
5848  describe '#current_highest_access_level' do
5849    let_it_be(:user) { create(:user) }
5850
5851    context 'when no memberships exist' do
5852      it 'returns nil' do
5853        expect(user.current_highest_access_level).to be_nil
5854      end
5855    end
5856
5857    context 'when memberships exist' do
5858      it 'returns the highest access level for non requested memberships' do
5859        create(:group_member, :reporter, user_id: user.id)
5860        create(:project_member, :guest, user_id: user.id)
5861        create(:project_member, :maintainer, user_id: user.id, requested_at: Time.current)
5862
5863        expect(user.current_highest_access_level).to eq(Gitlab::Access::REPORTER)
5864      end
5865    end
5866  end
5867
5868  context 'when after_commit :update_highest_role' do
5869    describe 'create user' do
5870      subject { create(:user) }
5871
5872      it 'schedules a job in the future', :aggregate_failures, :clean_gitlab_redis_shared_state do
5873        allow_next_instance_of(Gitlab::ExclusiveLease) do |instance|
5874          allow(instance).to receive(:try_obtain).and_return('uuid')
5875        end
5876
5877        expect(UpdateHighestRoleWorker).to receive(:perform_in).and_call_original
5878
5879        expect { subject }.to change(UpdateHighestRoleWorker.jobs, :size).by(1)
5880      end
5881    end
5882
5883    context 'when user already exists' do
5884      let!(:user) { create(:user) }
5885      let(:user_id) { user.id }
5886
5887      describe 'update user' do
5888        using RSpec::Parameterized::TableSyntax
5889
5890        where(:attributes) do
5891          [
5892            { state: 'blocked' },
5893            { user_type: :ghost },
5894            { user_type: :alert_bot },
5895            { user_type: :support_bot },
5896            { user_type: :security_bot },
5897            { user_type: :automation_bot }
5898          ]
5899        end
5900
5901        with_them do
5902          context 'when state was changed' do
5903            subject { user.update!(attributes) }
5904
5905            include_examples 'update highest role with exclusive lease'
5906          end
5907        end
5908
5909        context 'when state was not changed' do
5910          subject { user.update!(email: 'newmail@example.com') }
5911
5912          include_examples 'does not update the highest role'
5913        end
5914      end
5915
5916      describe 'destroy user' do
5917        subject { user.destroy! }
5918
5919        include_examples 'does not update the highest role'
5920      end
5921    end
5922  end
5923
5924  describe '#active_for_authentication?' do
5925    subject(:active_for_authentication?) { user.active_for_authentication? }
5926
5927    let(:user) { create(:user) }
5928
5929    context 'when user is blocked' do
5930      before do
5931        user.block
5932      end
5933
5934      it { is_expected.to be false }
5935
5936      it 'does not check if LDAP is allowed' do
5937        stub_ldap_setting(enabled: true)
5938
5939        expect(Gitlab::Auth::Ldap::Access).not_to receive(:allowed?)
5940
5941        active_for_authentication?
5942      end
5943    end
5944
5945    context 'when user is a ghost user' do
5946      before do
5947        user.update!(user_type: :ghost)
5948      end
5949
5950      it { is_expected.to be false }
5951    end
5952
5953    context 'when user is ldap_blocked' do
5954      before do
5955        user.ldap_block
5956      end
5957
5958      it 'rechecks if LDAP is allowed when LDAP is enabled' do
5959        stub_ldap_setting(enabled: true)
5960
5961        expect(Gitlab::Auth::Ldap::Access).to receive(:allowed?)
5962
5963        active_for_authentication?
5964      end
5965
5966      it 'does not check if LDAP is allowed when LDAP is not enabled' do
5967        stub_ldap_setting(enabled: false)
5968
5969        expect(Gitlab::Auth::Ldap::Access).not_to receive(:allowed?)
5970
5971        active_for_authentication?
5972      end
5973    end
5974
5975    context 'based on user type' do
5976      using RSpec::Parameterized::TableSyntax
5977
5978      where(:user_type, :expected_result) do
5979        'human'             | true
5980        'alert_bot'         | false
5981        'support_bot'       | false
5982        'security_bot'      | false
5983        'automation_bot'    | false
5984      end
5985
5986      with_them do
5987        before do
5988          user.update!(user_type: user_type)
5989        end
5990
5991        it { is_expected.to be expected_result }
5992      end
5993    end
5994  end
5995
5996  describe '#inactive_message' do
5997    subject { user.inactive_message }
5998
5999    let(:user) { create(:user) }
6000
6001    context 'when user is blocked' do
6002      before do
6003        user.block
6004      end
6005
6006      it { is_expected.to eq :blocked }
6007    end
6008
6009    context 'when user is an internal user' do
6010      before do
6011        user.update!(user_type: :ghost)
6012      end
6013
6014      it { is_expected.to be :forbidden }
6015    end
6016
6017    context 'when user is locked' do
6018      before do
6019        user.lock_access!
6020      end
6021
6022      it { is_expected.to be :locked }
6023    end
6024
6025    context 'when user is blocked pending approval' do
6026      before do
6027        user.block_pending_approval!
6028      end
6029
6030      it { is_expected.to be :blocked_pending_approval }
6031    end
6032  end
6033
6034  describe '#password_required?' do
6035    let_it_be(:user) { create(:user) }
6036
6037    shared_examples 'does not require password to be present' do
6038      it { expect(user).not_to validate_presence_of(:password) }
6039
6040      it { expect(user).not_to validate_presence_of(:password_confirmation) }
6041    end
6042
6043    context 'when user is an internal user' do
6044      before do
6045        user.update!(user_type: 'alert_bot')
6046      end
6047
6048      it_behaves_like 'does not require password to be present'
6049    end
6050
6051    context 'when user is a project bot user' do
6052      before do
6053        user.update!(user_type: 'project_bot')
6054      end
6055
6056      it_behaves_like 'does not require password to be present'
6057    end
6058  end
6059
6060  describe 'can_trigger_notifications?' do
6061    context 'when user is not confirmed' do
6062      let_it_be(:user) { create(:user, :unconfirmed) }
6063
6064      it 'returns false' do
6065        expect(user.can_trigger_notifications?).to be(false)
6066      end
6067    end
6068
6069    context 'when user is blocked' do
6070      let_it_be(:user) { create(:user, :blocked) }
6071
6072      it 'returns false' do
6073        expect(user.can_trigger_notifications?).to be(false)
6074      end
6075    end
6076
6077    context 'when user is a ghost' do
6078      let_it_be(:user) { create(:user, :ghost) }
6079
6080      it 'returns false' do
6081        expect(user.can_trigger_notifications?).to be(false)
6082      end
6083    end
6084
6085    context 'when user is confirmed and neither blocked or a ghost' do
6086      let_it_be(:user) { create(:user) }
6087
6088      it 'returns true' do
6089        expect(user.can_trigger_notifications?).to be(true)
6090      end
6091    end
6092  end
6093
6094  context 'bot users' do
6095    shared_examples 'bot users' do |bot_type|
6096      it 'creates the user if it does not exist' do
6097        expect do
6098          described_class.public_send(bot_type)
6099        end.to change { User.where(user_type: bot_type).count }.by(1)
6100      end
6101
6102      it 'creates a route for the namespace of the created user' do
6103        bot_user = described_class.public_send(bot_type)
6104
6105        expect(bot_user.namespace.route).to be_present
6106      end
6107
6108      it 'does not create a new user if it already exists' do
6109        described_class.public_send(bot_type)
6110
6111        expect do
6112          described_class.public_send(bot_type)
6113        end.not_to change { User.count }
6114      end
6115    end
6116
6117    shared_examples 'bot user avatars' do |bot_type, avatar_filename|
6118      it 'sets the custom avatar for the created bot' do
6119        bot_user = described_class.public_send(bot_type)
6120
6121        expect(bot_user.avatar.url).to be_present
6122        expect(bot_user.avatar.filename).to eq(avatar_filename)
6123      end
6124    end
6125
6126    it_behaves_like 'bot users', :alert_bot
6127    it_behaves_like 'bot users', :support_bot
6128    it_behaves_like 'bot users', :migration_bot
6129    it_behaves_like 'bot users', :security_bot
6130    it_behaves_like 'bot users', :ghost
6131    it_behaves_like 'bot users', :automation_bot
6132
6133    it_behaves_like 'bot user avatars', :alert_bot, 'alert-bot.png'
6134    it_behaves_like 'bot user avatars', :support_bot, 'support-bot.png'
6135    it_behaves_like 'bot user avatars', :security_bot, 'security-bot.png'
6136    it_behaves_like 'bot user avatars', :automation_bot, 'support-bot.png'
6137
6138    context 'when bot is the support_bot' do
6139      subject { described_class.support_bot }
6140
6141      it { is_expected.to be_confirmed }
6142    end
6143  end
6144
6145  describe '#confirmation_required_on_sign_in?' do
6146    subject { user.confirmation_required_on_sign_in? }
6147
6148    context 'when user is confirmed' do
6149      let(:user) { create(:user) }
6150
6151      it 'is falsey' do
6152        expect(user.confirmed?).to be_truthy
6153        expect(subject).to be_falsey
6154      end
6155    end
6156
6157    context 'when user is not confirmed' do
6158      let_it_be(:user) { build_stubbed(:user, :unconfirmed, confirmation_sent_at: Time.current) }
6159
6160      it 'is truthy when soft_email_confirmation feature is disabled' do
6161        stub_feature_flags(soft_email_confirmation: false)
6162        expect(subject).to be_truthy
6163      end
6164
6165      context 'when soft_email_confirmation feature is enabled' do
6166        before do
6167          stub_feature_flags(soft_email_confirmation: true)
6168        end
6169
6170        it 'is falsey when confirmation period is valid' do
6171          expect(subject).to be_falsey
6172        end
6173
6174        it 'is truthy when confirmation period is expired' do
6175          travel_to(User.allow_unconfirmed_access_for.from_now + 1.day) do
6176            expect(subject).to be_truthy
6177          end
6178        end
6179
6180        context 'when user has no confirmation email sent' do
6181          let(:user) { build(:user, :unconfirmed, confirmation_sent_at: nil) }
6182
6183          it 'is truthy' do
6184            expect(subject).to be_truthy
6185          end
6186        end
6187      end
6188    end
6189  end
6190
6191  describe '.dormant' do
6192    it 'returns dormant users' do
6193      freeze_time do
6194        not_that_long_ago = (described_class::MINIMUM_INACTIVE_DAYS - 1).days.ago.to_date
6195        too_long_ago = described_class::MINIMUM_INACTIVE_DAYS.days.ago.to_date
6196
6197        create(:user, :deactivated, last_activity_on: too_long_ago)
6198
6199        User::INTERNAL_USER_TYPES.map do |user_type|
6200          create(:user, state: :active, user_type: user_type, last_activity_on: too_long_ago)
6201        end
6202
6203        create(:user, last_activity_on: not_that_long_ago)
6204
6205        dormant_user = create(:user, last_activity_on: too_long_ago)
6206
6207        expect(described_class.dormant).to contain_exactly(dormant_user)
6208      end
6209    end
6210  end
6211
6212  describe '.with_no_activity' do
6213    it 'returns users with no activity' do
6214      freeze_time do
6215        not_that_long_ago = (described_class::MINIMUM_INACTIVE_DAYS - 1).days.ago.to_date
6216        too_long_ago = described_class::MINIMUM_INACTIVE_DAYS.days.ago.to_date
6217
6218        create(:user, :deactivated, last_activity_on: nil)
6219
6220        User::INTERNAL_USER_TYPES.map do |user_type|
6221          create(:user, state: :active, user_type: user_type, last_activity_on: nil)
6222        end
6223
6224        create(:user, last_activity_on: not_that_long_ago)
6225        create(:user, last_activity_on: too_long_ago)
6226
6227        user_with_no_activity = create(:user, last_activity_on: nil)
6228
6229        expect(described_class.with_no_activity).to contain_exactly(user_with_no_activity)
6230      end
6231    end
6232  end
6233
6234  describe '.by_provider_and_extern_uid' do
6235    it 'calls Identity model scope to ensure case-insensitive query', :aggregate_failures do
6236      expected_user = create(:user)
6237      create(:identity, extern_uid: 'some-other-name-id', provider: :github)
6238      create(:identity, extern_uid: 'my_github_id', provider: :gitlab)
6239      create(:identity)
6240      create(:identity, user: expected_user, extern_uid: 'my_github_id', provider: :github)
6241
6242      expect(Identity).to receive(:with_extern_uid).and_call_original
6243      expect(described_class.by_provider_and_extern_uid(:github, 'my_github_id')).to match_array([expected_user])
6244    end
6245  end
6246
6247  describe '#unset_secondary_emails_matching_deleted_email!' do
6248    let(:deleted_email) { 'kermit@muppets.com' }
6249
6250    subject { build(:user, commit_email: commit_email) }
6251
6252    context 'when no secondary email matches the deleted email' do
6253      let(:commit_email) { 'fozzie@muppets.com' }
6254
6255      it 'does nothing' do
6256        expect(subject).not_to receive(:save)
6257        subject.unset_secondary_emails_matching_deleted_email!(deleted_email)
6258        expect(subject.commit_email).to eq commit_email
6259      end
6260    end
6261
6262    context 'when a secondary email matches the deleted_email' do
6263      let(:commit_email) { deleted_email }
6264
6265      it 'un-sets the secondary email' do
6266        expect(subject).to receive(:save)
6267        subject.unset_secondary_emails_matching_deleted_email!(deleted_email)
6268        expect(subject.commit_email).to be nil
6269      end
6270    end
6271  end
6272
6273  describe '#groups_with_developer_maintainer_project_access' do
6274    let_it_be(:user) { create(:user) }
6275    let_it_be(:group1) { create(:group) }
6276
6277    let_it_be(:developer_group1) do
6278      create(:group).tap do |g|
6279        g.add_developer(user)
6280      end
6281    end
6282
6283    let_it_be(:developer_group2) do
6284      create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
6285        g.add_developer(user)
6286      end
6287    end
6288
6289    let_it_be(:guest_group1) do
6290      create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
6291        g.add_guest(user)
6292      end
6293    end
6294
6295    let_it_be(:developer_group1) do
6296      create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
6297        g.add_maintainer(user)
6298      end
6299    end
6300
6301    subject { user.send(:groups_with_developer_maintainer_project_access) }
6302
6303    specify { is_expected.to contain_exactly(developer_group2) }
6304  end
6305
6306  describe '.get_ids_by_username' do
6307    let(:user_name) { 'user_name' }
6308    let!(:user) { create(:user, username: user_name) }
6309    let(:user_id) { user.id }
6310
6311    it 'returns the id of each record matching username' do
6312      expect(described_class.get_ids_by_username([user_name])).to match_array([user_id])
6313    end
6314  end
6315
6316  describe 'user_project' do
6317    it 'returns users project matched by username and public visibility' do
6318      user = create(:user)
6319      public_project = create(:project, :public, path: user.username, namespace: user.namespace)
6320      create(:project, namespace: user.namespace)
6321
6322      expect(user.user_project).to eq(public_project)
6323    end
6324  end
6325
6326  describe 'user_readme' do
6327    it 'returns readme from user project' do
6328      user = create(:user)
6329      create(:project, :repository, :public, path: user.username, namespace: user.namespace)
6330
6331      expect(user.user_readme.name).to eq('README.md')
6332      expect(user.user_readme.data).to include('testme')
6333    end
6334
6335    it 'returns nil if project is private' do
6336      user = create(:user)
6337      create(:project, :repository, :private, path: user.username, namespace: user.namespace)
6338
6339      expect(user.user_readme).to be(nil)
6340    end
6341  end
6342
6343  it_behaves_like 'it has loose foreign keys' do
6344    let(:factory_name) { :user }
6345  end
6346end
6347