diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-20 09:16:11 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-20 09:16:11 +0000 |
commit | edaa33dee2ff2f7ea3fac488d41558eb5f86d68c (patch) | |
tree | 11f143effbfeba52329fb7afbd05e6e2a3790241 /spec/models/user_spec.rb | |
parent | d8a5691316400a0f7ec4f83832698f1988eb27c1 (diff) | |
download | gitlab-ce-edaa33dee2ff2f7ea3fac488d41558eb5f86d68c.tar.gz |
Add latest changes from gitlab-org/gitlab@14-7-stable-eev14.7.0-rc42
Diffstat (limited to 'spec/models/user_spec.rb')
-rw-r--r-- | spec/models/user_spec.rb | 329 |
1 files changed, 308 insertions, 21 deletions
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f8cea619233..ac2474ac393 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -83,6 +83,9 @@ RSpec.describe User do it { is_expected.to delegate_method(:registration_objective).to(:user_detail).allow_nil } it { is_expected.to delegate_method(:registration_objective=).to(:user_detail).with_arguments(:args).allow_nil } + + it { is_expected.to delegate_method(:requires_credit_card_verification).to(:user_detail).allow_nil } + it { is_expected.to delegate_method(:requires_credit_card_verification=).to(:user_detail).with_arguments(:args).allow_nil } end describe 'associations' do @@ -436,7 +439,7 @@ RSpec.describe User do subject { build(:user) } end - it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :public_email, :notification_email do + it_behaves_like 'an object with email-formatted attributes', :public_email, :notification_email do subject { create(:user).tap { |user| user.emails << build(:email, email: email_value, confirmed_at: Time.current) } } end @@ -542,6 +545,13 @@ RSpec.describe User do expect(user).to be_invalid expect(user.errors.messages[:email].first).to eq(expected_error) end + + it 'does not allow user to update email to a non-allowlisted domain' do + user = create(:user, email: "info@test.example.com") + + expect { user.update!(email: "test@notexample.com") } + .to raise_error(StandardError, 'Validation failed: Email is not allowed. Check with your administrator.') + end end context 'when a signup domain is allowed and subdomains are not allowed' do @@ -608,6 +618,13 @@ RSpec.describe User do user = build(:user, email: 'info@example.com', created_by_id: 1) expect(user).to be_valid end + + it 'does not allow user to update email to a denied domain' do + user = create(:user, email: 'info@test.com') + + expect { user.update!(email: 'info@example.com') } + .to raise_error(StandardError, 'Validation failed: Email is not allowed. Check with your administrator.') + end end context 'when a signup domain is denied but a wildcard subdomain is allowed' do @@ -679,6 +696,13 @@ RSpec.describe User do expect(user.errors.messages[:email].first).to eq(expected_error) end + it 'does not allow user to update email to a restricted domain' do + user = create(:user, email: 'info@test.com') + + expect { user.update!(email: 'info@gitlab.com') } + .to raise_error(StandardError, 'Validation failed: Email is not allowed. Check with your administrator.') + end + it 'does accept a valid email address' do user = build(:user, email: 'info@test.com') @@ -1398,7 +1422,7 @@ RSpec.describe User do end describe '#update_tracked_fields!', :clean_gitlab_redis_shared_state do - let(:request) { OpenStruct.new(remote_ip: "127.0.0.1") } + let(:request) { double('request', remote_ip: "127.0.0.1") } let(:user) { create(:user) } it 'writes trackable attributes' do @@ -1481,27 +1505,176 @@ RSpec.describe User do end describe '#confirm' do + let(:expired_confirmation_sent_at) { Date.today - described_class.confirm_within - 7.days } + let(:extant_confirmation_sent_at) { Date.today } + before do allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true) end - let(:user) { create(:user, :unconfirmed, unconfirmed_email: 'test@gitlab.com') } + let(:user) do + create(:user, :unconfirmed, unconfirmed_email: 'test@gitlab.com').tap do |user| + user.update!(confirmation_sent_at: confirmation_sent_at) + end + end - it 'returns unconfirmed' do - expect(user.confirmed?).to be_falsey + shared_examples_for 'unconfirmed user' do + it 'returns unconfirmed' do + expect(user.confirmed?).to be_falsey + end end - it 'confirms a user' do - user.confirm - expect(user.confirmed?).to be_truthy + context 'when the confirmation period has expired' do + let(:confirmation_sent_at) { expired_confirmation_sent_at } + + it_behaves_like 'unconfirmed user' + + it 'does not confirm the user' do + user.confirm + + expect(user.confirmed?).to be_falsey + end + + it 'does not add the confirmed primary email to emails' do + user.confirm + + expect(user.emails.confirmed.map(&:email)).not_to include(user.email) + end end - it 'adds the confirmed primary email to emails' do - expect(user.emails.confirmed.map(&:email)).not_to include(user.email) + context 'when the confirmation period has not expired' do + let(:confirmation_sent_at) { extant_confirmation_sent_at } - user.confirm + it_behaves_like 'unconfirmed user' - expect(user.emails.confirmed.map(&:email)).to include(user.email) + it 'confirms a user' do + user.confirm + expect(user.confirmed?).to be_truthy + end + + it 'adds the confirmed primary email to emails' do + expect(user.emails.confirmed.map(&:email)).not_to include(user.email) + + user.confirm + + expect(user.emails.confirmed.map(&:email)).to include(user.email) + end + + context 'when the primary email is already included in user.emails' do + let(:expired_confirmation_sent_at_for_email) { Date.today - Email.confirm_within - 7.days } + let(:extant_confirmation_sent_at_for_email) { Date.today } + + let!(:email) do + create(:email, email: user.unconfirmed_email, user: user).tap do |email| + email.update!(confirmation_sent_at: confirmation_sent_at_for_email) + end + end + + context 'when the confirmation period of the email record has expired' do + let(:confirmation_sent_at_for_email) { expired_confirmation_sent_at_for_email } + + it 'does not confirm the email record' do + user.confirm + + expect(email.reload.confirmed?).to be_falsey + end + end + + context 'when the confirmation period of the email record has not expired' do + let(:confirmation_sent_at_for_email) { extant_confirmation_sent_at_for_email } + + it 'confirms the email record' do + user.confirm + + expect(email.reload.confirmed?).to be_truthy + end + end + end + end + end + + describe '#force_confirm' do + let(:expired_confirmation_sent_at) { Date.today - described_class.confirm_within - 7.days } + let(:extant_confirmation_sent_at) { Date.today } + + let(:user) do + create(:user, :unconfirmed, unconfirmed_email: 'test@gitlab.com').tap do |user| + user.update!(confirmation_sent_at: confirmation_sent_at) + end + end + + shared_examples_for 'unconfirmed user' do + it 'returns unconfirmed' do + expect(user.confirmed?).to be_falsey + end + end + + shared_examples_for 'confirms the user on force_confirm' do + it 'confirms a user' do + user.force_confirm + expect(user.confirmed?).to be_truthy + end + end + + shared_examples_for 'adds the confirmed primary email to emails' do + it 'adds the confirmed primary email to emails' do + expect(user.emails.confirmed.map(&:email)).not_to include(user.email) + + user.force_confirm + + expect(user.emails.confirmed.map(&:email)).to include(user.email) + end + end + + shared_examples_for 'confirms the email record if the primary email was already present in user.emails' do + context 'when the primary email is already included in user.emails' do + let(:expired_confirmation_sent_at_for_email) { Date.today - Email.confirm_within - 7.days } + let(:extant_confirmation_sent_at_for_email) { Date.today } + + let!(:email) do + create(:email, email: user.unconfirmed_email, user: user).tap do |email| + email.update!(confirmation_sent_at: confirmation_sent_at_for_email) + end + end + + shared_examples_for 'confirms the email record' do + it 'confirms the email record' do + user.force_confirm + + expect(email.reload.confirmed?).to be_truthy + end + end + + context 'when the confirmation period of the email record has expired' do + let(:confirmation_sent_at_for_email) { expired_confirmation_sent_at_for_email } + + it_behaves_like 'confirms the email record' + end + + context 'when the confirmation period of the email record has not expired' do + let(:confirmation_sent_at_for_email) { extant_confirmation_sent_at_for_email } + + it_behaves_like 'confirms the email record' + end + end + end + + context 'when the confirmation period has expired' do + let(:confirmation_sent_at) { expired_confirmation_sent_at } + + it_behaves_like 'unconfirmed user' + it_behaves_like 'confirms the user on force_confirm' + it_behaves_like 'adds the confirmed primary email to emails' + it_behaves_like 'confirms the email record if the primary email was already present in user.emails' + end + + context 'when the confirmation period has not expired' do + let(:confirmation_sent_at) { extant_confirmation_sent_at } + + it_behaves_like 'unconfirmed user' + it_behaves_like 'confirms the user on force_confirm' + it_behaves_like 'adds the confirmed primary email to emails' + it_behaves_like 'confirms the email record if the primary email was already present in user.emails' end end @@ -1523,9 +1696,9 @@ RSpec.describe User do describe '#generate_password' do it 'does not generate password by default' do - user = create(:user, password: 'abcdefghe') + user = create(:user, password: Gitlab::Password.test_default) - expect(user.password).to eq('abcdefghe') + expect(user.password).to eq(Gitlab::Password.test_default) end end @@ -1624,6 +1797,29 @@ RSpec.describe User do expect(static_object_token).not_to be_blank expect(user.reload.static_object_token).to eq static_object_token end + + it 'generates an encrypted version of the token' do + user = create(:user, static_object_token: nil) + + expect(user[:static_object_token]).to be_nil + expect(user[:static_object_token_encrypted]).to be_nil + + user.static_object_token + + expect(user[:static_object_token]).to be_nil + expect(user[:static_object_token_encrypted]).to be_present + end + + it 'prefers an encoded version of the token' do + user = create(:user, static_object_token: nil) + + token = user.static_object_token + + user.update_column(:static_object_token, 'Test') + + expect(user.static_object_token).not_to eq('Test') + expect(user.static_object_token).to eq(token) + end end describe 'enabled_static_object_token' do @@ -1862,7 +2058,7 @@ RSpec.describe User do it { expect(user.authorized_groups).to eq([group]) } it { expect(user.owned_groups).to eq([group]) } it { expect(user.namespaces).to contain_exactly(user.namespace, group) } - it { expect(user.manageable_namespaces).to contain_exactly(user.namespace, group) } + it { expect(user.forkable_namespaces).to contain_exactly(user.namespace, group) } context 'with owned groups only' do before do @@ -1876,9 +2072,12 @@ RSpec.describe User do context 'with child groups' do let!(:subgroup) { create(:group, parent: group) } - describe '#manageable_namespaces' do - it 'includes all the namespaces the user can manage' do - expect(user.manageable_namespaces).to contain_exactly(user.namespace, group, subgroup) + describe '#forkable_namespaces' do + it 'includes all the namespaces the user can fork into' do + developer_group = create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) + developer_group.add_developer(user) + + expect(user.forkable_namespaces).to contain_exactly(user.namespace, group, subgroup, developer_group) end end @@ -2592,6 +2791,12 @@ RSpec.describe User do end end + describe '.user_search_minimum_char_limit' do + it 'returns true' do + expect(described_class.user_search_minimum_char_limit).to be(true) + end + end + describe '.find_by_ssh_key_id' do let_it_be(:user) { create(:user) } let_it_be(:key) { create(:key, user: user) } @@ -3768,7 +3973,7 @@ RSpec.describe User do end end - describe '#ci_owned_runners' do + shared_context '#ci_owned_runners' do let(:user) { create(:user) } shared_examples :nested_groups_owner do @@ -4075,6 +4280,16 @@ RSpec.describe User do end end + it_behaves_like '#ci_owned_runners' + + context 'when FF ci_owned_runners_cross_joins_fix is disabled' do + before do + stub_feature_flags(ci_owned_runners_cross_joins_fix: false) + end + + it_behaves_like '#ci_owned_runners' + end + describe '#projects_with_reporter_access_limited_to' do let(:project1) { create(:project) } let(:project2) { create(:project) } @@ -5606,6 +5821,48 @@ RSpec.describe User do end end + describe '#can_log_in_with_non_expired_password?' do + let(:user) { build(:user) } + + subject { user.can_log_in_with_non_expired_password? } + + context 'when user can log in' do + it 'returns true' do + is_expected.to be_truthy + end + + context 'when user with expired password' do + before do + user.password_expires_at = 2.minutes.ago + end + + it 'returns false' do + is_expected.to be_falsey + end + + context 'when password expiration is not applicable' do + context 'when ldap user' do + let(:user) { build(:omniauth_user, provider: 'ldap') } + + it 'returns true' do + is_expected.to be_truthy + end + end + end + end + end + + context 'when user cannot log in' do + context 'when user is blocked' do + let(:user) { build(:user, :blocked) } + + it 'returns false' do + is_expected.to be_falsey + end + end + end + end + describe '#read_only_attribute?' do context 'when synced attributes metadata is present' do it 'delegates to synced_attributes_metadata' do @@ -6303,13 +6560,43 @@ RSpec.describe User do specify { is_expected.to contain_exactly(developer_group2) } end - describe '.get_ids_by_username' do + describe '.get_ids_by_ids_or_usernames' do let(:user_name) { 'user_name' } let!(:user) { create(:user, username: user_name) } let(:user_id) { user.id } it 'returns the id of each record matching username' do - expect(described_class.get_ids_by_username([user_name])).to match_array([user_id]) + expect(described_class.get_ids_by_ids_or_usernames(nil, [user_name])).to match_array([user_id]) + end + + it 'returns the id of each record matching user id' do + expect(described_class.get_ids_by_ids_or_usernames([user_id], nil)).to match_array([user_id]) + end + + it 'return the id for all records matching either user id or user name' do + new_user_id = create(:user).id + + expect(described_class.get_ids_by_ids_or_usernames([new_user_id], [user_name])).to match_array([user_id, new_user_id]) + end + end + + describe '.by_ids_or_usernames' do + let(:user_name) { 'user_name' } + let!(:user) { create(:user, username: user_name) } + let(:user_id) { user.id } + + it 'returns matching records based on username' do + expect(described_class.by_ids_or_usernames(nil, [user_name])).to match_array([user]) + end + + it 'returns matching records based on id' do + expect(described_class.by_ids_or_usernames([user_id], nil)).to match_array([user]) + end + + it 'returns matching records based on both username and id' do + new_user = create(:user) + + expect(described_class.by_ids_or_usernames([new_user.id], [user_name])).to match_array([user, new_user]) end end |