diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-17 10:07:47 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-06-17 10:07:47 +0000 |
commit | d670c3006e6e44901bce0d53cc4768d1d80ffa92 (patch) | |
tree | 8f65743c232e5b76850c4cc264ba15e1185815ff /spec/models | |
parent | a5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 (diff) | |
download | gitlab-ce-d670c3006e6e44901bce0d53cc4768d1d80ffa92.tar.gz |
Add latest changes from gitlab-org/gitlab@14-0-stable-ee
Diffstat (limited to 'spec/models')
-rw-r--r-- | spec/models/ability_spec.rb | 41 | ||||
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 24 | ||||
-rw-r--r-- | spec/models/clusters/platforms/kubernetes_spec.rb | 10 | ||||
-rw-r--r-- | spec/models/container_expiration_policy_spec.rb | 16 | ||||
-rw-r--r-- | spec/models/integrations/emails_on_push_spec.rb | 8 | ||||
-rw-r--r-- | spec/models/integrations/flowdock_spec.rb | 20 | ||||
-rw-r--r-- | spec/models/merge_request_spec.rb | 11 | ||||
-rw-r--r-- | spec/models/packages/package_spec.rb | 20 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 51 | ||||
-rw-r--r-- | spec/models/remote_mirror_spec.rb | 41 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 64 |
11 files changed, 255 insertions, 51 deletions
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 3418d7d39ad..4bfa953df40 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -342,4 +342,45 @@ RSpec.describe Ability do end end end + + describe 'forgetting', :request_store do + it 'allows us to discard specific values from the DeclarativePolicy cache' do + user_a = build_stubbed(:user) + user_b = build_stubbed(:user) + + # expect these keys to remain + Gitlab::SafeRequestStore[:administrator] = :wibble + Gitlab::SafeRequestStore['admin'] = :wobble + described_class.allowed?(user_b, :read_all_resources) + # expect the DeclarativePolicy cache keys added by this action not to remain + described_class.forgetting(/admin/) do + described_class.allowed?(user_a, :read_all_resources) + end + + keys = Gitlab::SafeRequestStore.storage.keys + + expect(keys).to include( + :administrator, + 'admin', + "/dp/condition/BasePolicy/admin/#{user_b.id}" + ) + expect(keys).not_to include("/dp/condition/BasePolicy/admin/#{user_a.id}") + end + + # regression spec for re-entrant admin condition checks + # See: https://gitlab.com/gitlab-org/gitlab/-/issues/332983 + context 'when bypassing the session' do + let(:user) { build_stubbed(:admin) } + let(:ability) { :admin_all_resources } # any admin-only ability is fine here. + + def check_ability + described_class.forgetting(/admin/) { described_class.allowed?(user, ability) } + end + + it 'allows us to have re-entrant evaluation of admin-only permissions' do + expect { Gitlab::Auth::CurrentUserMode.bypass_session!(user.id) } + .to change { check_ability }.from(false).to(true) + end + end + end end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 72af40e31e0..26fc4b140c1 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -4625,8 +4625,11 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do end describe '#build_matchers' do - let_it_be(:pipeline) { create(:ci_pipeline) } - let_it_be(:builds) { create_list(:ci_build, 2, pipeline: pipeline, project: pipeline.project) } + let_it_be(:user) { create(:user) } + let_it_be(:pipeline) { create(:ci_pipeline, user: user) } + let_it_be(:builds) { create_list(:ci_build, 2, pipeline: pipeline, project: pipeline.project, user: user) } + + let(:project) { pipeline.project } subject(:matchers) { pipeline.build_matchers } @@ -4635,5 +4638,22 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do expect(matchers).to all be_a(Gitlab::Ci::Matching::BuildMatcher) expect(matchers.first.build_ids).to match_array(builds.map(&:id)) end + + context 'with retried builds' do + let(:retried_build) { builds.first } + + before do + stub_not_protect_default_branch + project.add_developer(user) + + retried_build.cancel! + ::Ci::Build.retry(retried_build, user) + end + + it 'does not include retried builds' do + expect(matchers.size).to eq(1) + expect(matchers.first.build_ids).not_to include(retried_build.id) + end + end end end diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index 07e64889b93..a4cae93ff84 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -439,16 +439,6 @@ RSpec.describe Clusters::Platforms::Kubernetes do include_examples 'successful deployment request' end - - context 'when canary_ingress_weight_control feature flag is disabled' do - before do - stub_feature_flags(canary_ingress_weight_control: false) - end - - it 'does not fetch ingress data from kubernetes' do - expect(subject[:ingresses]).to be_empty - end - end end context 'when the kubernetes integration is disabled' do diff --git a/spec/models/container_expiration_policy_spec.rb b/spec/models/container_expiration_policy_spec.rb index 32ec5ed161a..191913ed454 100644 --- a/spec/models/container_expiration_policy_spec.rb +++ b/spec/models/container_expiration_policy_spec.rb @@ -139,15 +139,23 @@ RSpec.describe ContainerExpirationPolicy, type: :model do end end - describe '.with_container_repositories' do - subject { described_class.with_container_repositories } - + context 'policies with container repositories' do let_it_be(:policy1) { create(:container_expiration_policy) } let_it_be(:container_repository1) { create(:container_repository, project: policy1.project) } let_it_be(:policy2) { create(:container_expiration_policy) } let_it_be(:container_repository2) { create(:container_repository, project: policy2.project) } let_it_be(:policy3) { create(:container_expiration_policy) } - it { is_expected.to contain_exactly(policy1, policy2) } + describe '.with_container_repositories' do + subject { described_class.with_container_repositories } + + it { is_expected.to contain_exactly(policy1, policy2) } + end + + describe '.without_container_repositories' do + subject { described_class.without_container_repositories } + + it { is_expected.to contain_exactly(policy3) } + end end end diff --git a/spec/models/integrations/emails_on_push_spec.rb b/spec/models/integrations/emails_on_push_spec.rb index ca060f4155e..c82d4bdff9b 100644 --- a/spec/models/integrations/emails_on_push_spec.rb +++ b/spec/models/integrations/emails_on_push_spec.rb @@ -88,7 +88,7 @@ RSpec.describe Integrations::EmailsOnPush do describe '#execute' do let(:push_data) { { object_kind: 'push' } } let(:project) { create(:project, :repository) } - let(:service) { create(:emails_on_push_service, project: project) } + let(:integration) { create(:emails_on_push_integration, project: project) } let(:recipients) { 'test@gitlab.com' } before do @@ -105,7 +105,7 @@ RSpec.describe Integrations::EmailsOnPush do it 'sends email' do expect(EmailsOnPushWorker).not_to receive(:perform_async) - service.execute(push_data) + integration.execute(push_data) end end @@ -119,7 +119,7 @@ RSpec.describe Integrations::EmailsOnPush do it 'does not send email' do expect(EmailsOnPushWorker).not_to receive(:perform_async) - service.execute(push_data) + integration.execute(push_data) end end @@ -128,7 +128,7 @@ RSpec.describe Integrations::EmailsOnPush do expect(project).to receive(:emails_disabled?).and_return(true) expect(EmailsOnPushWorker).not_to receive(:perform_async) - service.execute(push_data) + integration.execute(push_data) end end diff --git a/spec/models/integrations/flowdock_spec.rb b/spec/models/integrations/flowdock_spec.rb index 2de6f7dd2f1..189831fa32d 100644 --- a/spec/models/integrations/flowdock_spec.rb +++ b/spec/models/integrations/flowdock_spec.rb @@ -29,27 +29,29 @@ RSpec.describe Integrations::Flowdock do describe "Execute" do let(:user) { create(:user) } let(:project) { create(:project, :repository) } + let(:sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) } + let(:api_url) { 'https://api.flowdock.com/v1/messages' } + + subject(:flowdock_integration) { described_class.new } before do - @flowdock_service = described_class.new - allow(@flowdock_service).to receive_messages( + allow(flowdock_integration).to receive_messages( project_id: project.id, project: project, service_hook: true, token: 'verySecret' ) - @sample_data = Gitlab::DataBuilder::Push.build_sample(project, user) - @api_url = 'https://api.flowdock.com/v1/messages' - WebMock.stub_request(:post, @api_url) + WebMock.stub_request(:post, api_url) end it "calls FlowDock API" do - @flowdock_service.execute(@sample_data) - @sample_data[:commits].each do |commit| + flowdock_integration.execute(sample_data) + + sample_data[:commits].each do |commit| # One request to Flowdock per new commit - next if commit[:id] == @sample_data[:before] + next if commit[:id] == sample_data[:before] - expect(WebMock).to have_requested(:post, @api_url).with( + expect(WebMock).to have_requested(:post, api_url).with( body: /#{commit[:id]}.*#{project.path}/ ).once end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 94b4c1901b8..73b1cb13f19 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -4951,4 +4951,15 @@ RSpec.describe MergeRequest, factory_default: :keep do it { is_expected.to eq(true) } end end + + describe '.from_fork' do + let!(:project) { create(:project, :repository) } + let!(:forked_project) { fork_project(project) } + let!(:fork_mr) { create(:merge_request, source_project: forked_project, target_project: project) } + let!(:regular_mr) { create(:merge_request, source_project: project) } + + it 'returns merge requests from forks only' do + expect(described_class.from_fork).to eq([fork_mr]) + end + end end diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb index 1e44327c089..b2c1d51e4af 100644 --- a/spec/models/packages/package_spec.rb +++ b/spec/models/packages/package_spec.rb @@ -1019,10 +1019,24 @@ RSpec.describe Packages::Package, type: :model do package.composer_metadatum.reload end - it 'schedule the update job' do - expect(::Packages::Composer::CacheUpdateWorker).to receive(:perform_async).with(project.id, package_name, package.composer_metadatum.version_cache_sha) + context 'with feature flag disabled' do + before do + stub_feature_flags(disable_composer_callback: false) + end + + it 'schedule the update job' do + expect(::Packages::Composer::CacheUpdateWorker).to receive(:perform_async).with(project.id, package_name, package.composer_metadatum.version_cache_sha) + + package.destroy! + end + end - package.destroy! + context 'with feature flag enabled' do + it 'does nothing' do + expect(::Packages::Composer::CacheUpdateWorker).not_to receive(:perform_async) + + package.destroy! + end end end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 78e32571d7d..7eb02749f72 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -38,7 +38,7 @@ RSpec.describe Project, factory_default: :keep do it { is_expected.to have_one(:slack_service) } it { is_expected.to have_one(:microsoft_teams_service) } it { is_expected.to have_one(:mattermost_service) } - it { is_expected.to have_one(:hangouts_chat_service) } + it { is_expected.to have_one(:hangouts_chat_integration) } it { is_expected.to have_one(:unify_circuit_service) } it { is_expected.to have_one(:webex_teams_service) } it { is_expected.to have_one(:packagist_service) } @@ -49,11 +49,11 @@ RSpec.describe Project, factory_default: :keep do it { is_expected.to have_one(:datadog_integration) } it { is_expected.to have_one(:discord_integration) } it { is_expected.to have_one(:drone_ci_integration) } - it { is_expected.to have_one(:emails_on_push_service) } + it { is_expected.to have_one(:emails_on_push_integration) } it { is_expected.to have_one(:pipelines_email_service) } - it { is_expected.to have_one(:irker_service) } + it { is_expected.to have_one(:irker_integration) } it { is_expected.to have_one(:pivotaltracker_service) } - it { is_expected.to have_one(:flowdock_service) } + it { is_expected.to have_one(:flowdock_integration) } it { is_expected.to have_one(:assembla_integration) } it { is_expected.to have_one(:slack_slash_commands_service) } it { is_expected.to have_one(:mattermost_slash_commands_service) } @@ -65,8 +65,8 @@ RSpec.describe Project, factory_default: :keep do it { is_expected.to have_one(:youtrack_service) } it { is_expected.to have_one(:custom_issue_tracker_integration) } it { is_expected.to have_one(:bugzilla_integration) } - it { is_expected.to have_one(:ewm_service) } - it { is_expected.to have_one(:external_wiki_service) } + it { is_expected.to have_one(:ewm_integration) } + it { is_expected.to have_one(:external_wiki_integration) } it { is_expected.to have_one(:confluence_integration) } it { is_expected.to have_one(:project_feature) } it { is_expected.to have_one(:project_repository) } @@ -1661,6 +1661,45 @@ RSpec.describe Project, factory_default: :keep do end end + describe '.find_by_url' do + subject { described_class.find_by_url(url) } + + let_it_be(:project) { create(:project) } + + before do + stub_config_setting(host: 'gitlab.com') + end + + context 'url is internal' do + let(:url) { "https://#{Gitlab.config.gitlab.host}/#{path}" } + + context 'path is recognised as a project path' do + let(:path) { project.full_path } + + it { is_expected.to eq(project) } + + it 'returns nil if the path detection throws an error' do + expect(Rails.application.routes).to receive(:recognize_path).with(url) { raise ActionController::RoutingError, 'test' } + + expect { subject }.not_to raise_error(ActionController::RoutingError) + expect(subject).to be_nil + end + end + + context 'path is not a project path' do + let(:path) { 'probably/missing.git' } + + it { is_expected.to be_nil } + end + end + + context 'url is external' do + let(:url) { "https://foo.com/bar/baz.git" } + + it { is_expected.to be_nil } + end + end + context 'repository storage by default' do let(:project) { build(:project) } diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb index d6951b5926e..a64b01967ef 100644 --- a/spec/models/remote_mirror_spec.rb +++ b/spec/models/remote_mirror_spec.rb @@ -157,19 +157,34 @@ RSpec.describe RemoteMirror, :mailer do end describe '#update_repository' do - it 'performs update including options' do - git_remote_mirror = stub_const('Gitlab::Git::RemoteMirror', spy) - mirror = build(:remote_mirror) - - expect(mirror).to receive(:options_for_update).and_return(keep_divergent_refs: true) - mirror.update_repository - - expect(git_remote_mirror).to have_received(:new).with( - mirror.project.repository.raw, - mirror.remote_name, - keep_divergent_refs: true - ) - expect(git_remote_mirror).to have_received(:update) + shared_examples 'an update' do + it 'performs update including options' do + git_remote_mirror = stub_const('Gitlab::Git::RemoteMirror', spy) + mirror = build(:remote_mirror) + + expect(mirror).to receive(:options_for_update).and_return(keep_divergent_refs: true) + mirror.update_repository(inmemory_remote: inmemory) + + expect(git_remote_mirror).to have_received(:new).with( + mirror.project.repository.raw, + mirror.remote_name, + inmemory ? mirror.url : nil, + keep_divergent_refs: true + ) + expect(git_remote_mirror).to have_received(:update) + end + end + + context 'with inmemory remote' do + let(:inmemory) { true } + + it_behaves_like 'an update' + end + + context 'with on-disk remote' do + let(:inmemory) { false } + + it_behaves_like 'an update' end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f1c30a646f5..e5c86e69ffc 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -5224,6 +5224,70 @@ RSpec.describe User do end end + describe '#password_expired_if_applicable?' do + let(:user) { build(:user, password_expires_at: password_expires_at) } + + subject { user.password_expired_if_applicable? } + + context 'when user is not ldap user' do + context 'when password_expires_at is not set' do + let(:password_expires_at) {} + + it 'returns false' do + is_expected.to be_falsey + end + end + + context 'when password_expires_at is in the past' do + let(:password_expires_at) { 1.minute.ago } + + it 'returns true' do + is_expected.to be_truthy + end + end + + context 'when password_expires_at is in the future' do + let(:password_expires_at) { 1.minute.from_now } + + it 'returns false' do + is_expected.to be_falsey + end + end + end + + context 'when user is ldap user' do + let(:user) { build(:user, password_expires_at: password_expires_at) } + + before do + allow(user).to receive(:ldap_user?).and_return(true) + end + + context 'when password_expires_at is not set' do + let(:password_expires_at) {} + + it 'returns false' do + is_expected.to be_falsey + end + end + + context 'when password_expires_at is in the past' do + let(:password_expires_at) { 1.minute.ago } + + it 'returns false' do + is_expected.to be_falsey + end + end + + context 'when password_expires_at is in the future' do + let(:password_expires_at) { 1.minute.from_now } + + 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 |