diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-08 15:06:32 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-08 15:06:32 +0300 |
commit | 61f0c58946ebac453b55a657cd4be1ac50a01e11 (patch) | |
tree | 7b164c1cc9dc8ab1d100ca4fe90decf6d72e984b /spec | |
parent | d23b2a0871f3ca507aafa949e0314625f1f0c6a7 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r-- | spec/features/projects/labels/search_labels_spec.rb | 2 | ||||
-rw-r--r-- | spec/frontend/lib/utils/datetime_utility_spec.js | 8 | ||||
-rw-r--r-- | spec/frontend/releases/list/components/release_block_footer_spec.js | 163 | ||||
-rw-r--r-- | spec/frontend/releases/list/components/release_block_spec.js | 13 | ||||
-rw-r--r-- | spec/frontend/releases/mock_data.js | 2 | ||||
-rw-r--r-- | spec/helpers/users_helper_spec.rb | 4 | ||||
-rw-r--r-- | spec/javascripts/blob/viewer/index_spec.js | 25 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/job_spec.rb | 17 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/need_spec.rb | 36 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/needs_spec.rb | 84 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/normalizer_spec.rb | 104 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/yaml_processor_spec.rb | 35 | ||||
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 19 | ||||
-rw-r--r-- | spec/services/clusters/destroy_service_spec.rb | 56 |
14 files changed, 514 insertions, 54 deletions
diff --git a/spec/features/projects/labels/search_labels_spec.rb b/spec/features/projects/labels/search_labels_spec.rb index 2d5a138c3cc..e2eec7400ff 100644 --- a/spec/features/projects/labels/search_labels_spec.rb +++ b/spec/features/projects/labels/search_labels_spec.rb @@ -68,7 +68,7 @@ describe 'Search for labels', :js do find('#label-search').native.send_keys(:enter) page.within('.prioritized-labels') do - expect(page).to have_content('No prioritised labels with such name or description') + expect(page).to have_content('No prioritized labels with such name or description') end page.within('.other-labels') do diff --git a/spec/frontend/lib/utils/datetime_utility_spec.js b/spec/frontend/lib/utils/datetime_utility_spec.js index e4c97543b03..ee27789b6b9 100644 --- a/spec/frontend/lib/utils/datetime_utility_spec.js +++ b/spec/frontend/lib/utils/datetime_utility_spec.js @@ -474,3 +474,11 @@ describe('getDatesInRange', () => { }); }); }); + +describe('secondsToMilliseconds', () => { + it('converts seconds to milliseconds correctly', () => { + expect(datetimeUtility.secondsToMilliseconds(0)).toBe(0); + expect(datetimeUtility.secondsToMilliseconds(60)).toBe(60000); + expect(datetimeUtility.secondsToMilliseconds(123)).toBe(123000); + }); +}); diff --git a/spec/frontend/releases/list/components/release_block_footer_spec.js b/spec/frontend/releases/list/components/release_block_footer_spec.js new file mode 100644 index 00000000000..172147f1cc8 --- /dev/null +++ b/spec/frontend/releases/list/components/release_block_footer_spec.js @@ -0,0 +1,163 @@ +import { mount } from '@vue/test-utils'; +import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue'; +import Icon from '~/vue_shared/components/icon.vue'; +import { GlLink } from '@gitlab/ui'; +import { trimText } from 'helpers/text_helper'; +import { release } from '../../mock_data'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; + +jest.mock('~/vue_shared/mixins/timeago', () => ({ + methods: { + timeFormated() { + return '7 fortnightes ago'; + }, + tooltipTitle() { + return 'February 30, 2401'; + }, + }, +})); + +describe('Release block footer', () => { + let wrapper; + let releaseClone; + + const factory = (props = {}) => { + wrapper = mount(ReleaseBlockFooter, { + propsData: { + ...convertObjectPropsToCamelCase(releaseClone), + ...props, + }, + sync: false, + }); + + return wrapper.vm.$nextTick(); + }; + + beforeEach(() => { + releaseClone = JSON.parse(JSON.stringify(release)); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + const commitInfoSection = () => wrapper.find('.js-commit-info'); + const commitInfoSectionLink = () => commitInfoSection().find(GlLink); + const tagInfoSection = () => wrapper.find('.js-tag-info'); + const tagInfoSectionLink = () => tagInfoSection().find(GlLink); + const authorDateInfoSection = () => wrapper.find('.js-author-date-info'); + + describe('with all props provided', () => { + beforeEach(() => factory()); + + it('renders the commit icon', () => { + const commitIcon = commitInfoSection().find(Icon); + + expect(commitIcon.exists()).toBe(true); + expect(commitIcon.props('name')).toBe('commit'); + }); + + it('renders the commit SHA with a link', () => { + const commitLink = commitInfoSectionLink(); + + expect(commitLink.exists()).toBe(true); + expect(commitLink.text()).toBe(releaseClone.commit.short_id); + expect(commitLink.attributes('href')).toBe(releaseClone.commit_path); + }); + + it('renders the tag icon', () => { + const commitIcon = tagInfoSection().find(Icon); + + expect(commitIcon.exists()).toBe(true); + expect(commitIcon.props('name')).toBe('tag'); + }); + + it('renders the tag name with a link', () => { + const commitLink = tagInfoSection().find(GlLink); + + expect(commitLink.exists()).toBe(true); + expect(commitLink.text()).toBe(releaseClone.tag_name); + expect(commitLink.attributes('href')).toBe(releaseClone.tag_path); + }); + + it('renders the author and creation time info', () => { + expect(trimText(authorDateInfoSection().text())).toBe( + `Created 7 fortnightes ago by ${releaseClone.author.username}`, + ); + }); + + it("renders the author's avatar image", () => { + const avatarImg = authorDateInfoSection().find('img'); + + expect(avatarImg.exists()).toBe(true); + expect(avatarImg.attributes('src')).toBe(releaseClone.author.avatar_url); + }); + + it("renders a link to the author's profile", () => { + const authorLink = authorDateInfoSection().find(GlLink); + + expect(authorLink.exists()).toBe(true); + expect(authorLink.attributes('href')).toBe(releaseClone.author.web_url); + }); + }); + + describe('without any commit info', () => { + beforeEach(() => factory({ commit: undefined })); + + it('does not render any commit info', () => { + expect(commitInfoSection().exists()).toBe(false); + }); + }); + + describe('without a commit URL', () => { + beforeEach(() => factory({ commitPath: undefined })); + + it('renders the commit SHA as plain text (instead of a link)', () => { + expect(commitInfoSectionLink().exists()).toBe(false); + expect(commitInfoSection().text()).toBe(releaseClone.commit.short_id); + }); + }); + + describe('without a tag name', () => { + beforeEach(() => factory({ tagName: undefined })); + + it('does not render any tag info', () => { + expect(tagInfoSection().exists()).toBe(false); + }); + }); + + describe('without a tag URL', () => { + beforeEach(() => factory({ tagPath: undefined })); + + it('renders the tag name as plain text (instead of a link)', () => { + expect(tagInfoSectionLink().exists()).toBe(false); + expect(tagInfoSection().text()).toBe(releaseClone.tag_name); + }); + }); + + describe('without any author info', () => { + beforeEach(() => factory({ author: undefined })); + + it('renders the release date without the author name', () => { + expect(trimText(authorDateInfoSection().text())).toBe('Created 7 fortnightes ago'); + }); + }); + + describe('without a released at date', () => { + beforeEach(() => factory({ releasedAt: undefined })); + + it('renders the author name without the release date', () => { + expect(trimText(authorDateInfoSection().text())).toBe( + `Created by ${releaseClone.author.username}`, + ); + }); + }); + + describe('without a release date or author info', () => { + beforeEach(() => factory({ author: undefined, releasedAt: undefined })); + + it('does not render any author or release date info', () => { + expect(authorDateInfoSection().exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/releases/list/components/release_block_spec.js b/spec/frontend/releases/list/components/release_block_spec.js index 6601c4265f6..b63ef068d8e 100644 --- a/spec/frontend/releases/list/components/release_block_spec.js +++ b/spec/frontend/releases/list/components/release_block_spec.js @@ -1,5 +1,6 @@ import { mount } from '@vue/test-utils'; import ReleaseBlock from '~/releases/list/components/release_block.vue'; +import ReleaseBlockFooter from '~/releases/list/components/release_block_footer.vue'; import timeagoMixin from '~/vue_shared/mixins/timeago'; import { first } from 'underscore'; import { release } from '../../mock_data'; @@ -21,14 +22,16 @@ describe('Release block', () => { let wrapper; let releaseClone; - const factory = (releaseProp, releaseEditPageFeatureFlag = true) => { + const factory = (releaseProp, featureFlags = {}) => { wrapper = mount(ReleaseBlock, { propsData: { release: releaseProp, }, provide: { glFeatures: { - releaseEditPage: releaseEditPageFeatureFlag, + releaseEditPage: true, + releaseIssueSummary: true, + ...featureFlags, }, }, sync: false, @@ -142,6 +145,10 @@ describe('Release block', () => { expect(milestoneLink.attributes('data-original-title')).toBe(milestone.description); }); + + it('renders the footer', () => { + expect(wrapper.find(ReleaseBlockFooter).exists()).toBe(true); + }); }); it('renders commit sha', () => { @@ -173,7 +180,7 @@ describe('Release block', () => { }); it('does not render an edit button if the releaseEditPage feature flag is disabled', () => - factory(releaseClone, false).then(() => { + factory(releaseClone, { releaseEditPage: false }).then(() => { expect(editButton().exists()).toBe(false); })); diff --git a/spec/frontend/releases/mock_data.js b/spec/frontend/releases/mock_data.js index 32095fd4b78..61d95b86b1c 100644 --- a/spec/frontend/releases/mock_data.js +++ b/spec/frontend/releases/mock_data.js @@ -30,6 +30,7 @@ export const milestones = [ export const release = { name: 'New release', tag_name: 'v0.3', + tag_path: '/root/release-test/-/tags/v0.3', description: 'A super nice release!', description_html: '<p data-sourcepos="1:1-1:21" dir="auto">A super nice release!</p>', created_at: '2019-08-26T17:54:04.952Z', @@ -56,6 +57,7 @@ export const release = { committer_email: 'admin@example.com', committed_date: '2019-08-26T17:47:07.000Z', }, + commit_path: '/root/release-test/commit/c22b0728d1b465f82898c884d32b01aa642f96c1', upcoming_release: false, milestones, assets: { diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb index 59abe8c09e1..172ead158fb 100644 --- a/spec/helpers/users_helper_spec.rb +++ b/spec/helpers/users_helper_spec.rb @@ -76,6 +76,10 @@ describe UsersHelper do allow(helper).to receive(:can?).and_return(false) end + after do + expect(items).not_to include(:start_trial) + end + it 'includes all default items' do expect(items).to include(:help, :sign_out) end diff --git a/spec/javascripts/blob/viewer/index_spec.js b/spec/javascripts/blob/viewer/index_spec.js index bbc59632f3c..766c3378584 100644 --- a/spec/javascripts/blob/viewer/index_spec.js +++ b/spec/javascripts/blob/viewer/index_spec.js @@ -176,15 +176,13 @@ describe('Blob viewer', () => { }); }); - describe('a URL inside the blob content', () => { - beforeEach(() => { + describe('linkifyURLs', () => { + it('renders a plain url as a link in simple view', done => { mock.onGet('http://test.host/snippets/1.json?viewer=simple').reply(200, { html: '<div class="js-blob-content"><pre class="code"><code><span class="line" lang="yaml"><span class="c1">To install gitlab-shell you also need a Go compiler version 1.8 or newer. https://golang.org/dl/</span></span></code></pre></div>', }); - }); - it('is rendered as a link in simple view', done => { asyncClick() .then(() => { expect(document.querySelector('.blob-viewer[data-type="simple"]').innerHTML).toContain( @@ -197,5 +195,24 @@ describe('Blob viewer', () => { done(); }); }); + + it('leaves an unescaped url untouched', done => { + mock.onGet('http://test.host/snippets/1.json?viewer=simple').reply(200, { + html: + '<div class="js-blob-content"><pre class="code"><code><span class="line" lang="yaml"><a href="https://golang.org/dl/">golang</a></span></span></code></pre></div>', + }); + + asyncClick() + .then(() => { + expect(document.querySelector('.blob-viewer[data-type="simple"]').innerHTML).toContain( + '<a href="https://golang.org/dl/">golang</a>', + ); + done(); + }) + .catch(() => { + fail(); + done(); + }); + }); }); }); diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index d3eb5a9663f..9fe18caf689 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -23,7 +23,7 @@ describe Gitlab::Ci::Config::Entry::Job do let(:result) do %i[before_script script stage type after_script cache - image services only except rules variables artifacts + image services only except rules needs variables artifacts environment coverage retry] end @@ -384,21 +384,6 @@ describe Gitlab::Ci::Config::Entry::Job do end context 'when has needs' do - context 'that are not a array of strings' do - let(:config) do - { - stage: 'test', - script: 'echo', - needs: 'build-job' - } - end - - it 'returns error about invalid type' do - expect(entry).not_to be_valid - expect(entry.errors).to include 'job needs should be an array of strings' - end - end - context 'when have dependencies that are not subset of needs' do let(:config) do { diff --git a/spec/lib/gitlab/ci/config/entry/need_spec.rb b/spec/lib/gitlab/ci/config/entry/need_spec.rb new file mode 100644 index 00000000000..d119e604900 --- /dev/null +++ b/spec/lib/gitlab/ci/config/entry/need_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ::Gitlab::Ci::Config::Entry::Need do + subject(:need) { described_class.new(config) } + + context 'when job is specified' do + let(:config) { 'job_name' } + + describe '#valid?' do + it { is_expected.to be_valid } + end + + describe '#value' do + it 'returns job needs configuration' do + expect(need.value).to eq(name: 'job_name') + end + end + end + + context 'when need is empty' do + let(:config) { '' } + + describe '#valid?' do + it { is_expected.not_to be_valid } + end + + describe '#errors' do + it 'is returns an error about an empty config' do + expect(need.errors) + .to contain_exactly("job config can't be blank") + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/entry/needs_spec.rb b/spec/lib/gitlab/ci/config/entry/needs_spec.rb new file mode 100644 index 00000000000..f4a76b52d30 --- /dev/null +++ b/spec/lib/gitlab/ci/config/entry/needs_spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ::Gitlab::Ci::Config::Entry::Needs do + subject(:needs) { described_class.new(config) } + + before do + needs.metadata[:allowed_needs] = %i[job] + end + + describe 'validations' do + before do + needs.compose! + end + + context 'when entry config value is correct' do + let(:config) { ['job_name'] } + + describe '#valid?' do + it { is_expected.to be_valid } + end + end + + context 'when config value has wrong type' do + let(:config) { 123 } + + describe '#valid?' do + it { is_expected.not_to be_valid } + end + + describe '#errors' do + it 'returns error about incorrect type' do + expect(needs.errors) + .to include('needs config can only be a hash or an array') + end + end + end + + context 'when wrong needs type is used' do + let(:config) { [123] } + + describe '#valid?' do + it { is_expected.not_to be_valid } + end + + describe '#errors' do + it 'returns error about incorrect type' do + expect(needs.errors).to contain_exactly( + 'need has an unsupported type') + end + end + end + end + + describe '.compose!' do + context 'when valid job entries composed' do + let(:config) { %w[first_job_name second_job_name] } + + before do + needs.compose! + end + + describe '#value' do + it 'returns key value' do + expect(needs.value).to eq( + job: [ + { name: 'first_job_name' }, + { name: 'second_job_name' } + ] + ) + end + end + + describe '#descendants' do + it 'creates valid descendant nodes' do + expect(needs.descendants.count).to eq 2 + expect(needs.descendants) + .to all(be_an_instance_of(::Gitlab::Ci::Config::Entry::Need)) + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/normalizer_spec.rb b/spec/lib/gitlab/ci/config/normalizer_spec.rb index 6b766cc37bf..bf880478387 100644 --- a/spec/lib/gitlab/ci/config/normalizer_spec.rb +++ b/spec/lib/gitlab/ci/config/normalizer_spec.rb @@ -7,6 +7,16 @@ describe Gitlab::Ci::Config::Normalizer do let(:job_config) { { script: 'rspec', parallel: 5, name: 'rspec' } } let(:config) { { job_name => job_config } } + let(:expanded_job_names) do + [ + "rspec 1/5", + "rspec 2/5", + "rspec 3/5", + "rspec 4/5", + "rspec 5/5" + ] + end + describe '.normalize_jobs' do subject { described_class.new(config).normalize_jobs } @@ -15,9 +25,7 @@ describe Gitlab::Ci::Config::Normalizer do end it 'has parallelized jobs' do - job_names = [:"rspec 1/5", :"rspec 2/5", :"rspec 3/5", :"rspec 4/5", :"rspec 5/5"] - - is_expected.to include(*job_names) + is_expected.to include(*expanded_job_names.map(&:to_sym)) end it 'sets job instance in options' do @@ -43,49 +51,109 @@ describe Gitlab::Ci::Config::Normalizer do let(:job_name) { :"rspec 35/2" } it 'properly parallelizes job names' do - job_names = [:"rspec 35/2 1/5", :"rspec 35/2 2/5", :"rspec 35/2 3/5", :"rspec 35/2 4/5", :"rspec 35/2 5/5"] + job_names = [ + :"rspec 35/2 1/5", + :"rspec 35/2 2/5", + :"rspec 35/2 3/5", + :"rspec 35/2 4/5", + :"rspec 35/2 5/5" + ] is_expected.to include(*job_names) end end - %i[dependencies needs].each do |context| - context "when job has #{context} on parallelized jobs" do + context 'for dependencies' do + context "when job has dependencies on parallelized jobs" do let(:config) do { job_name => job_config, - other_job: { script: 'echo 1', context => [job_name.to_s] } + other_job: { script: 'echo 1', dependencies: [job_name.to_s] } } end - it "parallelizes #{context}" do - job_names = ["rspec 1/5", "rspec 2/5", "rspec 3/5", "rspec 4/5", "rspec 5/5"] - - expect(subject[:other_job][context]).to include(*job_names) + it "parallelizes dependencies" do + expect(subject[:other_job][:dependencies]).to eq(expanded_job_names) end it "does not include original job name in #{context}" do - expect(subject[:other_job][context]).not_to include(job_name) + expect(subject[:other_job][:dependencies]).not_to include(job_name) end end - context "when there are #{context} which are both parallelized and not" do + context "when there are dependencies which are both parallelized and not" do let(:config) do { job_name => job_config, other_job: { script: 'echo 1' }, - final_job: { script: 'echo 1', context => [job_name.to_s, "other_job"] } + final_job: { script: 'echo 1', dependencies: [job_name.to_s, "other_job"] } } end - it "parallelizes #{context}" do + it "parallelizes dependencies" do job_names = ["rspec 1/5", "rspec 2/5", "rspec 3/5", "rspec 4/5", "rspec 5/5"] - expect(subject[:final_job][context]).to include(*job_names) + expect(subject[:final_job][:dependencies]).to include(*job_names) + end + + it "includes the regular job in dependencies" do + expect(subject[:final_job][:dependencies]).to include('other_job') + end + end + end + + context 'for needs' do + let(:expanded_job_attributes) do + expanded_job_names.map do |job_name| + { name: job_name } + end + end + + context "when job has needs on parallelized jobs" do + let(:config) do + { + job_name => job_config, + other_job: { + script: 'echo 1', + needs: { + job: [ + { name: job_name.to_s } + ] + } + } + } + end + + it "parallelizes needs" do + expect(subject.dig(:other_job, :needs, :job)).to eq(expanded_job_attributes) + end + end + + context "when there are dependencies which are both parallelized and not" do + let(:config) do + { + job_name => job_config, + other_job: { + script: 'echo 1' + }, + final_job: { + script: 'echo 1', + needs: { + job: [ + { name: job_name.to_s }, + { name: "other_job" } + ] + } + } + } + end + + it "parallelizes dependencies" do + expect(subject.dig(:final_job, :needs, :job)).to include(*expanded_job_attributes) end - it "includes the regular job in #{context}" do - expect(subject[:final_job][context]).to include('other_job') + it "includes the regular job in dependencies" do + expect(subject.dig(:final_job, :needs, :job)).to include(name: 'other_job') end end end diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb index c747ea670bb..dc7bbc519ee 100644 --- a/spec/lib/gitlab/ci/yaml_processor_spec.rb +++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb @@ -1293,7 +1293,7 @@ module Gitlab end end - describe "Needs" do + describe "Job Needs" do let(:needs) { } let(:dependencies) { } @@ -1301,6 +1301,7 @@ module Gitlab { build1: { stage: 'build', script: 'test' }, build2: { stage: 'build', script: 'test' }, + parallel: { stage: 'build', script: 'test', parallel: 2 }, test1: { stage: 'test', script: 'test', needs: needs, dependencies: dependencies }, test2: { stage: 'test', script: 'test' }, deploy: { stage: 'test', script: 'test' } @@ -1317,7 +1318,7 @@ module Gitlab let(:needs) { %w(build1 build2) } it "does create jobs with valid specification" do - expect(subject.builds.size).to eq(5) + expect(subject.builds.size).to eq(7) expect(subject.builds[0]).to eq( stage: "build", stage_idx: 1, @@ -1329,16 +1330,11 @@ module Gitlab allow_failure: false, yaml_variables: [] ) - expect(subject.builds[2]).to eq( + expect(subject.builds[4]).to eq( stage: "test", stage_idx: 2, name: "test1", - options: { - script: ["test"], - # This does not make sense, there is a follow-up: - # https://gitlab.com/gitlab-org/gitlab-foss/issues/65569 - bridge_needs: %w[build1 build2] - }, + options: { script: ["test"] }, needs_attributes: [ { name: "build1" }, { name: "build2" } @@ -1350,10 +1346,25 @@ module Gitlab end end - context 'needs two builds defined as symbols' do - let(:needs) { [:build1, :build2] } + context 'needs parallel job' do + let(:needs) { %w(parallel) } - it { expect { subject }.not_to raise_error } + it "does create jobs with valid specification" do + expect(subject.builds.size).to eq(7) + expect(subject.builds[4]).to eq( + stage: "test", + stage_idx: 2, + name: "test1", + options: { script: ["test"] }, + needs_attributes: [ + { name: "parallel 1/2" }, + { name: "parallel 2/2" } + ], + when: "on_success", + allow_failure: false, + yaml_variables: [] + ) + end end context 'undefined need' do diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 5e5a94f8cda..9295bb993ce 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -2893,6 +2893,25 @@ describe Ci::Pipeline, :mailer do it 'contains yaml errors' do expect(pipeline).to have_yaml_errors + expect(pipeline.yaml_errors).to include('contains unknown keys') + end + end + + context 'when pipeline has undefined error' do + let(:pipeline) do + create(:ci_pipeline, config: {}) + end + + it 'contains yaml errors' do + expect(::Gitlab::Ci::YamlProcessor).to receive(:new) + .and_raise(RuntimeError, 'undefined failure') + + expect(Gitlab::Sentry).to receive(:track_acceptable_exception) + .with(be_a(RuntimeError), anything) + .and_call_original + + expect(pipeline).to have_yaml_errors + expect(pipeline.yaml_errors).to include('Undefined error') end end diff --git a/spec/services/clusters/destroy_service_spec.rb b/spec/services/clusters/destroy_service_spec.rb new file mode 100644 index 00000000000..c0fcc971500 --- /dev/null +++ b/spec/services/clusters/destroy_service_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Clusters::DestroyService do + describe '#execute' do + subject { described_class.new(cluster.user, params).execute(cluster) } + + let!(:cluster) { create(:cluster, :project, :provided_by_user) } + + context 'when correct params' do + shared_examples 'only removes cluster' do + it 'does not start cleanup' do + expect(cluster).not_to receive(:start_cleanup) + subject + end + + it 'destroys the cluster' do + subject + expect { cluster.reload }.to raise_error ActiveRecord::RecordNotFound + end + end + + context 'when params are empty' do + let(:params) { {} } + + it_behaves_like 'only removes cluster' + end + + context 'when cleanup param is false' do + let(:params) { { cleanup: 'false' } } + + it_behaves_like 'only removes cluster' + end + + context 'when cleanup param is true' do + let(:params) { { cleanup: 'true' } } + + before do + allow(Clusters::Cleanup::AppWorker).to receive(:perform_async) + end + + it 'does not destroy cluster' do + subject + expect(Clusters::Cluster.where(id: cluster.id).exists?).not_to be_falsey + end + + it 'transition cluster#cleanup_status from cleanup_not_started to uninstalling_applications' do + expect { subject }.to change { cluster.cleanup_status_name } + .from(:cleanup_not_started) + .to(:cleanup_uninstalling_applications) + end + end + end + end +end |