diff options
Diffstat (limited to 'spec/models')
-rw-r--r-- | spec/models/application_record_spec.rb | 19 | ||||
-rw-r--r-- | spec/models/ci/bridge_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/ci/build_spec.rb | 18 | ||||
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 48 | ||||
-rw-r--r-- | spec/models/clusters/applications/cert_manager_spec.rb | 6 | ||||
-rw-r--r-- | spec/models/clusters/applications/helm_spec.rb | 8 | ||||
-rw-r--r-- | spec/models/clusters/applications/ingress_spec.rb | 6 | ||||
-rw-r--r-- | spec/models/clusters/applications/jupyter_spec.rb | 9 | ||||
-rw-r--r-- | spec/models/clusters/applications/knative_spec.rb | 6 | ||||
-rw-r--r-- | spec/models/clusters/applications/prometheus_spec.rb | 53 | ||||
-rw-r--r-- | spec/models/clusters/applications/runner_spec.rb | 8 | ||||
-rw-r--r-- | spec/models/deployment_spec.rb | 6 | ||||
-rw-r--r-- | spec/models/merge_request_spec.rb | 44 | ||||
-rw-r--r-- | spec/models/notification_recipient_spec.rb | 40 | ||||
-rw-r--r-- | spec/models/pages_domain_spec.rb | 28 | ||||
-rw-r--r-- | spec/models/project_services/hipchat_service_spec.rb | 11 | ||||
-rw-r--r-- | spec/models/repository_spec.rb | 65 |
17 files changed, 366 insertions, 11 deletions
diff --git a/spec/models/application_record_spec.rb b/spec/models/application_record_spec.rb index fd25132ed3a..cc90a998d3f 100644 --- a/spec/models/application_record_spec.rb +++ b/spec/models/application_record_spec.rb @@ -11,6 +11,25 @@ describe ApplicationRecord do end end + describe '.safe_ensure_unique' do + let(:model) { build(:suggestion) } + let(:klass) { model.class } + + before do + allow(model).to receive(:save).and_raise(ActiveRecord::RecordNotUnique) + end + + it 'returns false when ActiveRecord::RecordNotUnique is raised' do + expect(model).to receive(:save).once + expect(klass.safe_ensure_unique { model.save }).to be_falsey + end + + it 'retries based on retry count specified' do + expect(model).to receive(:save).exactly(3).times + expect(klass.safe_ensure_unique(retries: 2) { model.save }).to be_falsey + end + end + describe '.safe_find_or_create_by' do it 'creates the user avoiding race conditions' do expect(Suggestion).to receive(:find_or_create_by).and_raise(ActiveRecord::RecordNotUnique) diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb index 44b5af5e5aa..eb32198265b 100644 --- a/spec/models/ci/bridge_spec.rb +++ b/spec/models/ci/bridge_spec.rb @@ -10,6 +10,8 @@ describe Ci::Bridge do create(:ci_bridge, pipeline: pipeline) end + it { is_expected.to include_module(Ci::PipelineDelegator) } + describe '#tags' do it 'only has a bridge tag' do expect(bridge.tags).to eq [:bridge] diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 339483d4f7d..59ec7310391 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -28,6 +28,7 @@ describe Ci::Build do it { is_expected.to delegate_method(:merge_request_event?).to(:pipeline) } it { is_expected.to delegate_method(:merge_request_ref?).to(:pipeline) } it { is_expected.to delegate_method(:legacy_detached_merge_request_pipeline?).to(:pipeline) } + it { is_expected.to include_module(Ci::PipelineDelegator) } it { is_expected.to be_a(ArtifactMigratable) } @@ -2273,6 +2274,19 @@ describe Ci::Build do it { user_variables.each { |v| is_expected.to include(v) } } end + context 'when build belongs to a pipeline for merge request' do + let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline, source_branch: 'improve/awesome') } + let(:pipeline) { merge_request.all_pipelines.first } + let(:build) { create(:ci_build, ref: pipeline.ref, pipeline: pipeline) } + + it 'returns values based on source ref' do + is_expected.to include( + { key: 'CI_COMMIT_REF_NAME', value: 'improve/awesome', public: true, masked: false }, + { key: 'CI_COMMIT_REF_SLUG', value: 'improve-awesome', public: true, masked: false } + ) + end + end + context 'when build has an environment' do let(:environment_variables) do [ @@ -2664,6 +2678,8 @@ describe Ci::Build do ) end + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'feature') } + it 'returns static predefined variables' do expect(build.variables.size).to be >= 28 expect(build.variables) @@ -2713,6 +2729,8 @@ describe Ci::Build do ) end + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'feature') } + it 'does not persist the build' do expect(build).to be_valid expect(build).not_to be_persisted diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 3c823b78be7..9d0cd654f13 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -382,6 +382,54 @@ describe Ci::Pipeline, :mailer do end end + describe '#source_ref' do + subject { pipeline.source_ref } + + let(:pipeline) { create(:ci_pipeline, ref: 'feature') } + + it 'returns source ref' do + is_expected.to eq('feature') + end + + context 'when the pipeline is a detached merge request pipeline' do + let(:merge_request) { create(:merge_request) } + + let(:pipeline) do + create(:ci_pipeline, source: :merge_request_event, merge_request: merge_request, ref: merge_request.ref_path) + end + + it 'returns source ref' do + is_expected.to eq(merge_request.source_branch) + end + end + end + + describe '#source_ref_slug' do + subject { pipeline.source_ref_slug } + + let(:pipeline) { create(:ci_pipeline, ref: 'feature') } + + it 'slugifies with the source ref' do + expect(Gitlab::Utils).to receive(:slugify).with('feature') + + subject + end + + context 'when the pipeline is a detached merge request pipeline' do + let(:merge_request) { create(:merge_request) } + + let(:pipeline) do + create(:ci_pipeline, source: :merge_request_event, merge_request: merge_request, ref: merge_request.ref_path) + end + + it 'slugifies with the source ref of the merge request' do + expect(Gitlab::Utils).to receive(:slugify).with(merge_request.source_branch) + + subject + end + end + end + describe '.triggered_for_branch' do subject { described_class.triggered_for_branch(ref) } diff --git a/spec/models/clusters/applications/cert_manager_spec.rb b/spec/models/clusters/applications/cert_manager_spec.rb index 5cd80edb3a1..8d853a04e33 100644 --- a/spec/models/clusters/applications/cert_manager_spec.rb +++ b/spec/models/clusters/applications/cert_manager_spec.rb @@ -10,6 +10,12 @@ describe Clusters::Applications::CertManager do include_examples 'cluster application version specs', :clusters_applications_cert_managers include_examples 'cluster application initial status specs' + describe '#can_uninstall?' do + subject { cert_manager.can_uninstall? } + + it { is_expected.to be_falsey } + end + describe '#install_command' do let(:cert_email) { 'admin@example.com' } diff --git a/spec/models/clusters/applications/helm_spec.rb b/spec/models/clusters/applications/helm_spec.rb index f177d493a2e..6ea6c110d62 100644 --- a/spec/models/clusters/applications/helm_spec.rb +++ b/spec/models/clusters/applications/helm_spec.rb @@ -18,6 +18,14 @@ describe Clusters::Applications::Helm do it { is_expected.to contain_exactly(installed_cluster, updated_cluster) } end + describe '#can_uninstall?' do + let(:helm) { create(:clusters_applications_helm) } + + subject { helm.can_uninstall? } + + it { is_expected.to be_falsey } + end + describe '#issue_client_cert' do let(:application) { create(:clusters_applications_helm) } subject { application.issue_client_cert } diff --git a/spec/models/clusters/applications/ingress_spec.rb b/spec/models/clusters/applications/ingress_spec.rb index 113d29b5551..292ddabd2d8 100644 --- a/spec/models/clusters/applications/ingress_spec.rb +++ b/spec/models/clusters/applications/ingress_spec.rb @@ -18,6 +18,12 @@ describe Clusters::Applications::Ingress do allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async) end + describe '#can_uninstall?' do + subject { ingress.can_uninstall? } + + it { is_expected.to be_falsey } + end + describe '#make_installed!' do before do application.make_installed! diff --git a/spec/models/clusters/applications/jupyter_spec.rb b/spec/models/clusters/applications/jupyter_spec.rb index 1a7363b64f9..fc9ebed863e 100644 --- a/spec/models/clusters/applications/jupyter_spec.rb +++ b/spec/models/clusters/applications/jupyter_spec.rb @@ -10,6 +10,15 @@ describe Clusters::Applications::Jupyter do it { is_expected.to belong_to(:oauth_application) } + describe '#can_uninstall?' do + let(:ingress) { create(:clusters_applications_ingress, :installed, external_hostname: 'localhost.localdomain') } + let(:jupyter) { create(:clusters_applications_jupyter, cluster: ingress.cluster) } + + subject { jupyter.can_uninstall? } + + it { is_expected.to be_falsey } + end + describe '#set_initial_status' do before do jupyter.set_initial_status diff --git a/spec/models/clusters/applications/knative_spec.rb b/spec/models/clusters/applications/knative_spec.rb index 405b5ad691c..d5974f47190 100644 --- a/spec/models/clusters/applications/knative_spec.rb +++ b/spec/models/clusters/applications/knative_spec.rb @@ -39,6 +39,12 @@ describe Clusters::Applications::Knative do end end + describe '#can_uninstall?' do + subject { knative.can_uninstall? } + + it { is_expected.to be_falsey } + end + describe '#schedule_status_update with external_ip' do let(:application) { create(:clusters_applications_knative, :installed) } diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb index e8ba9737c23..26267c64112 100644 --- a/spec/models/clusters/applications/prometheus_spec.rb +++ b/spec/models/clusters/applications/prometheus_spec.rb @@ -11,6 +11,21 @@ describe Clusters::Applications::Prometheus do include_examples 'cluster application helm specs', :clusters_applications_prometheus include_examples 'cluster application initial status specs' + describe 'after_destroy' do + let(:project) { create(:project) } + let(:cluster) { create(:cluster, :with_installed_helm, projects: [project]) } + let!(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) } + let!(:prometheus_service) { project.create_prometheus_service(active: true) } + + it 'deactivates prometheus_service after destroy' do + expect do + application.destroy! + + prometheus_service.reload + end.to change(prometheus_service, :active).from(true).to(false) + end + end + describe 'transition to installed' do let(:project) { create(:project) } let(:cluster) { create(:cluster, :with_installed_helm, projects: [project]) } @@ -23,12 +38,20 @@ describe Clusters::Applications::Prometheus do end it 'ensures Prometheus service is activated' do - expect(prometheus_service).to receive(:update).with(active: true) + expect(prometheus_service).to receive(:update!).with(active: true) subject.make_installed end end + describe '#can_uninstall?' do + let(:prometheus) { create(:clusters_applications_prometheus) } + + subject { prometheus.can_uninstall? } + + it { is_expected.to be_truthy } + end + describe '#prometheus_client' do context 'cluster is nil' do it 'returns nil' do @@ -134,6 +157,34 @@ describe Clusters::Applications::Prometheus do end end + describe '#uninstall_command' do + let(:prometheus) { create(:clusters_applications_prometheus) } + + subject { prometheus.uninstall_command } + + it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) } + + it 'has the application name' do + expect(subject.name).to eq('prometheus') + end + + it 'has files' do + expect(subject.files).to eq(prometheus.files) + end + + it 'is rbac' do + expect(subject).to be_rbac + end + + context 'on a non rbac enabled cluster' do + before do + prometheus.cluster.platform_kubernetes.abac! + end + + it { is_expected.not_to be_rbac } + end + end + describe '#upgrade_command' do let(:prometheus) { build(:clusters_applications_prometheus) } let(:values) { prometheus.values } diff --git a/spec/models/clusters/applications/runner_spec.rb b/spec/models/clusters/applications/runner_spec.rb index b66acf13135..bdc0cb8ed86 100644 --- a/spec/models/clusters/applications/runner_spec.rb +++ b/spec/models/clusters/applications/runner_spec.rb @@ -13,6 +13,14 @@ describe Clusters::Applications::Runner do it { is_expected.to belong_to(:runner) } + describe '#can_uninstall?' do + let(:gitlab_runner) { create(:clusters_applications_runner, runner: ci_runner) } + + subject { gitlab_runner.can_uninstall? } + + it { is_expected.to be_falsey } + end + describe '#install_command' do let(:kubeclient) { double('kubernetes client') } let(:gitlab_runner) { create(:clusters_applications_runner, runner: ci_runner) } diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index 0ca758429b8..f51322e1404 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -400,6 +400,12 @@ describe Deployment do it { is_expected.to be_nil } end + context 'project uses the kubernetes service for deployments' do + let!(:service) { create(:kubernetes_service, project: project) } + + it { is_expected.to be_nil } + end + context 'project has a deployment platform' do let!(:cluster) { create(:cluster, projects: [project]) } let!(:platform) { create(:cluster_platform_kubernetes, cluster: cluster) } diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index f61857ea5ff..fb7f43b25cf 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -2262,6 +2262,50 @@ describe MergeRequest do end end + describe "#environments" do + subject { merge_request.environments } + + let(:merge_request) { create(:merge_request, source_branch: 'feature', target_branch: 'master') } + let(:project) { merge_request.project } + + let(:pipeline) do + create(:ci_pipeline, + source: :merge_request_event, + merge_request: merge_request, project: project, + sha: merge_request.diff_head_sha, + merge_requests_as_head_pipeline: [merge_request]) + end + + let!(:job) { create(:ci_build, :start_review_app, pipeline: pipeline, project: project) } + + it 'returns environments' do + is_expected.to eq(pipeline.environments) + expect(subject.count).to be(1) + end + + context 'when pipeline is not associated with environments' do + let!(:job) { create(:ci_build, pipeline: pipeline, project: project) } + + it 'returns empty array' do + is_expected.to be_empty + end + end + + context 'when pipeline is not a pipeline for merge request' do + let(:pipeline) do + create(:ci_pipeline, + project: project, + ref: 'feature', + sha: merge_request.diff_head_sha, + merge_requests_as_head_pipeline: [merge_request]) + end + + it 'returns empty relation' do + is_expected.to be_empty + end + end + end + describe "#reload_diff" do it 'calls MergeRequests::ReloadDiffsService#execute with correct params' do user = create(:user) diff --git a/spec/models/notification_recipient_spec.rb b/spec/models/notification_recipient_spec.rb index 3710f2be287..1b1ede6b14c 100644 --- a/spec/models/notification_recipient_spec.rb +++ b/spec/models/notification_recipient_spec.rb @@ -9,11 +9,43 @@ describe NotificationRecipient do subject(:recipient) { described_class.new(user, :watch, target: target, project: project) } - it 'denies access to a target when cross project access is denied' do - allow(Ability).to receive(:allowed?).and_call_original - expect(Ability).to receive(:allowed?).with(user, :read_cross_project, :global).and_return(false) + describe '#has_access?' do + before do + allow(user).to receive(:can?).and_call_original + end + + context 'user cannot read cross project' do + it 'returns false' do + expect(user).to receive(:can?).with(:read_cross_project).and_return(false) + expect(recipient.has_access?).to eq false + end + end + + context 'user cannot read build' do + let(:target) { build(:ci_pipeline) } + + it 'returns false' do + expect(user).to receive(:can?).with(:read_build, target).and_return(false) + expect(recipient.has_access?).to eq false + end + end - expect(recipient.has_access?).to be_falsy + context 'user cannot read commit' do + let(:target) { build(:commit) } + + it 'returns false' do + expect(user).to receive(:can?).with(:read_commit, target).and_return(false) + expect(recipient.has_access?).to eq false + end + end + + context 'target has no policy' do + let(:target) { double.as_null_object } + + it 'returns true' do + expect(recipient.has_access?).to eq true + end + end end context '#notification_setting' do diff --git a/spec/models/pages_domain_spec.rb b/spec/models/pages_domain_spec.rb index 142ddebbbf8..ec4d4517f82 100644 --- a/spec/models/pages_domain_spec.rb +++ b/spec/models/pages_domain_spec.rb @@ -344,4 +344,32 @@ describe PagesDomain do end end end + + describe '.for_removal' do + subject { described_class.for_removal } + + context 'when domain is not schedule for removal' do + let!(:domain) { create :pages_domain } + + it 'does not return domain' do + is_expected.to be_empty + end + end + + context 'when domain is scheduled for removal yesterday' do + let!(:domain) { create :pages_domain, remove_at: 1.day.ago } + + it 'returns domain' do + is_expected.to eq([domain]) + end + end + + context 'when domain is scheduled for removal tomorrow' do + let!(:domain) { create :pages_domain, remove_at: 1.day.from_now } + + it 'does not return domain' do + is_expected.to be_empty + end + end + end end diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb index fd9e33c1781..a04b984c1f6 100644 --- a/spec/models/project_services/hipchat_service_spec.rb +++ b/spec/models/project_services/hipchat_service_spec.rb @@ -98,12 +98,11 @@ describe HipchatService do context 'tag_push events' do let(:push_sample_data) do Gitlab::DataBuilder::Push.build( - project, - user, - Gitlab::Git::BLANK_SHA, - '1' * 40, - 'refs/tags/test', - []) + project: project, + user: user, + oldrev: Gitlab::Git::BLANK_SHA, + newrev: '1' * 40, + ref: 'refs/tags/test') end it "calls Hipchat API for tag push events" do diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 4c354593b57..43ec1125087 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -2487,4 +2487,69 @@ describe Repository do repository.merge_base('master', 'fix') end end + + describe '#create_if_not_exists' do + let(:project) { create(:project) } + let(:repository) { project.repository } + + it 'creates the repository if it did not exist' do + expect { repository.create_if_not_exists }.to change { repository.exists? }.from(false).to(true) + end + + it 'calls out to the repository client to create a repo' do + expect(repository.raw.gitaly_repository_client).to receive(:create_repository) + + repository.create_if_not_exists + end + + context 'it does nothing if the repository already existed' do + let(:project) { create(:project, :repository) } + + it 'does nothing if the repository already existed' do + expect(repository.raw.gitaly_repository_client).not_to receive(:create_repository) + + repository.create_if_not_exists + end + end + + context 'when the repository exists but the cache is not up to date' do + let(:project) { create(:project, :repository) } + + it 'does not raise errors' do + allow(repository).to receive(:exists?).and_return(false) + expect(repository.raw).to receive(:create_repository).and_call_original + + expect { repository.create_if_not_exists }.not_to raise_error + end + end + end + + describe "#blobs_metadata" do + set(:project) { create(:project, :repository) } + let(:repository) { project.repository } + + def expect_metadata_blob(thing) + expect(thing).to be_a(Blob) + expect(thing.data).to be_empty + end + + it "returns blob metadata in batch for HEAD" do + result = repository.blobs_metadata(["bar/branch-test.txt", "README.md", "does/not/exist"]) + + expect_metadata_blob(result.first) + expect_metadata_blob(result.second) + expect(result.size).to eq(2) + end + + it "returns blob metadata for a specified ref" do + result = repository.blobs_metadata(["files/ruby/feature.rb"], "feature") + + expect_metadata_blob(result.first) + end + + it "performs a single gitaly call", :request_store do + expect { repository.blobs_metadata(["bar/branch-test.txt", "readme.txt", "does/not/exist"]) } + .to change { Gitlab::GitalyClient.get_request_count }.by(1) + end + end end |