diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-08 15:07:59 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-01-08 15:07:59 +0300 |
commit | e3e300557f5def9bf2271735c8a620e6820dfada (patch) | |
tree | 8d0d4590518ee17eb32956e35637e11a2b8ca561 /spec | |
parent | a821bd6ad17e304ca93838a411410a44ee9cff9f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
29 files changed, 170 insertions, 340 deletions
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 902a84a843b..4cc5b3cba7c 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -740,4 +740,51 @@ describe Projects::PipelinesController do expect(response).to have_gitlab_http_status(404) end end + + describe 'DELETE #destroy' do + let!(:project) { create(:project, :private, :repository) } + let!(:pipeline) { create(:ci_pipeline, :failed, project: project) } + let!(:build) { create(:ci_build, :failed, pipeline: pipeline) } + + context 'when user has ability to delete pipeline' do + before do + sign_in(project.owner) + end + + it 'deletes pipeline and redirects' do + delete_pipeline + + expect(response).to have_gitlab_http_status(303) + + expect(Ci::Build.exists?(build.id)).to be_falsy + expect(Ci::Pipeline.exists?(pipeline.id)).to be_falsy + end + + context 'and builds are disabled' do + let(:feature) { ProjectFeature::DISABLED } + + it 'fails to delete pipeline' do + delete_pipeline + + expect(response).to have_gitlab_http_status(404) + end + end + end + + context 'when user has no privileges' do + it 'fails to delete pipeline' do + delete_pipeline + + expect(response).to have_gitlab_http_status(403) + end + end + + def delete_pipeline + delete :destroy, params: { + namespace_id: project.namespace, + project_id: project, + id: pipeline.id + } + end + end end diff --git a/spec/features/import/manifest_import_spec.rb b/spec/features/import/manifest_import_spec.rb index 89bf69dea7d..36478128dd1 100644 --- a/spec/features/import/manifest_import_spec.rb +++ b/spec/features/import/manifest_import_spec.rb @@ -24,17 +24,17 @@ describe 'Import multiple repositories by uploading a manifest file', :js do expect(page).to have_content('https://android-review.googlesource.com/platform/build/blueprint') end - it 'imports successfully imports a project', :sidekiq_might_not_need_inline do + it 'imports successfully imports a project', :sidekiq_inline do visit new_import_manifest_path attach_file('manifest', Rails.root.join('spec/fixtures/aosp_manifest.xml')) click_on 'List available repositories' - page.within(first_row) do + page.within(second_row) do click_on 'Import' expect(page).to have_content 'Done' - expect(page).to have_content("#{group.full_path}/build/make") + expect(page).to have_content("#{group.full_path}/build/blueprint") end end @@ -47,7 +47,7 @@ describe 'Import multiple repositories by uploading a manifest file', :js do expect(page).to have_content 'The uploaded file is not a valid XML file.' end - def first_row - page.all('table.import-jobs tbody tr')[0] + def second_row + page.all('table.import-jobs tbody tr')[1] end end diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 4b97c58d920..198af65c361 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -59,7 +59,8 @@ describe 'Pipeline', :js do describe 'GET /:project/pipelines/:id' do include_context 'pipeline builds' - let(:project) { create(:project, :repository) } + let(:group) { create(:group) } + let(:project) { create(:project, :repository, group: group) } let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id, user: user) } subject(:visit_pipeline) { visit project_pipeline_path(project, pipeline) } @@ -329,6 +330,32 @@ describe 'Pipeline', :js do end end + context 'deleting pipeline' do + context 'when user can not delete' do + before do + visit_pipeline + end + + it { expect(page).not_to have_button('Delete') } + end + + context 'when deleting' do + before do + group.add_owner(user) + + visit_pipeline + + click_button 'Delete' + click_button 'Delete pipeline' + end + + it 'redirects to pipeline overview page', :sidekiq_might_not_need_inline do + expect(page).to have_content('The pipeline has been deleted') + expect(current_path).to eq(project_pipelines_path(project)) + end + end + end + context 'when pipeline ref does not exist in repository anymore' do let(:pipeline) do create(:ci_empty_pipeline, project: project, diff --git a/spec/finders/pipelines_finder_spec.rb b/spec/finders/pipelines_finder_spec.rb index 1dbf9491118..c8a4ea799c3 100644 --- a/spec/finders/pipelines_finder_spec.rb +++ b/spec/finders/pipelines_finder_spec.rb @@ -64,19 +64,6 @@ describe PipelinesFinder do end end - context 'when project has child pipelines' do - let!(:parent_pipeline) { create(:ci_pipeline, project: project) } - let!(:child_pipeline) { create(:ci_pipeline, project: project, source: :parent_pipeline) } - - let!(:pipeline_source) do - create(:ci_sources_pipeline, pipeline: child_pipeline, source_pipeline: parent_pipeline) - end - - it 'filters out child pipelines and show only the parents' do - is_expected.to eq([parent_pipeline]) - end - end - HasStatus::AVAILABLE_STATUSES.each do |target| context "when status is #{target}" do let(:params) { { status: target } } diff --git a/spec/frontend/confidential_merge_request/components/project_form_group_spec.js b/spec/frontend/confidential_merge_request/components/project_form_group_spec.js index 3001363f7b9..975701ebd96 100644 --- a/spec/frontend/confidential_merge_request/components/project_form_group_spec.js +++ b/spec/frontend/confidential_merge_request/components/project_form_group_spec.js @@ -1,9 +1,8 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import axios from '~/lib/utils/axios_utils'; import ProjectFormGroup from '~/confidential_merge_request/components/project_form_group.vue'; -const localVue = createLocalVue(); const mockData = [ { id: 1, @@ -30,7 +29,6 @@ function factory(projects = mockData) { mock.onGet(/api\/(.*)\/projects\/gitlab-org%2Fgitlab-ce\/forks/).reply(200, projects); vm = shallowMount(ProjectFormGroup, { - localVue, propsData: { namespacePath: 'gitlab-org', projectPath: 'gitlab-org/gitlab-ce', @@ -49,7 +47,7 @@ describe('Confidential merge request project form group component', () => { it('renders fork dropdown', () => { factory(); - return localVue.nextTick(() => { + return vm.vm.$nextTick(() => { expect(vm.element).toMatchSnapshot(); }); }); @@ -57,7 +55,7 @@ describe('Confidential merge request project form group component', () => { it('sets selected project as first fork', () => { factory(); - return localVue.nextTick(() => { + return vm.vm.$nextTick(() => { expect(vm.vm.selectedProject).toEqual({ id: 1, name: 'root / gitlab-ce', @@ -70,7 +68,7 @@ describe('Confidential merge request project form group component', () => { it('renders empty state when response is empty', () => { factory([]); - return localVue.nextTick(() => { + return vm.vm.$nextTick(() => { expect(vm.element).toMatchSnapshot(); }); }); diff --git a/spec/frontend/contributors/component/contributors_spec.js b/spec/frontend/contributors/component/contributors_spec.js index 1d5605ef516..3e4924ed906 100644 --- a/spec/frontend/contributors/component/contributors_spec.js +++ b/spec/frontend/contributors/component/contributors_spec.js @@ -1,11 +1,10 @@ import Vue from 'vue'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import MockAdapter from 'axios-mock-adapter'; import { createStore } from '~/contributors/stores'; import axios from '~/lib/utils/axios_utils'; import ContributorsCharts from '~/contributors/components/contributors.vue'; -const localVue = createLocalVue(); let wrapper; let mock; let store; @@ -52,7 +51,7 @@ describe('Contributors charts', () => { it('should display loader whiled loading data', () => { wrapper.vm.$store.state.loading = true; - return localVue.nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.find('.contributors-loader').exists()).toBe(true); }); }); @@ -60,7 +59,7 @@ describe('Contributors charts', () => { it('should render charts when loading completed and there is chart data', () => { wrapper.vm.$store.state.loading = false; wrapper.vm.$store.state.chartData = chartData; - return localVue.nextTick(() => { + return wrapper.vm.$nextTick(() => { expect(wrapper.find('.contributors-loader').exists()).toBe(false); expect(wrapper.find('.contributors-charts').exists()).toBe(true); expect(wrapper.element).toMatchSnapshot(); diff --git a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js index eb9effea736..6ad33c36b30 100644 --- a/spec/frontend/diffs/components/diff_gutter_avatars_spec.js +++ b/spec/frontend/diffs/components/diff_gutter_avatars_spec.js @@ -1,8 +1,7 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import DiffGutterAvatars from '~/diffs/components/diff_gutter_avatars.vue'; import discussionsMockData from '../mock_data/diff_discussions'; -const localVue = createLocalVue(); const getDiscussionsMockData = () => [Object.assign({}, discussionsMockData)]; describe('DiffGutterAvatars', () => { @@ -14,7 +13,6 @@ describe('DiffGutterAvatars', () => { const createComponent = (props = {}) => { wrapper = shallowMount(DiffGutterAvatars, { - localVue, propsData: { ...props, }, diff --git a/spec/frontend/diffs/components/edit_button_spec.js b/spec/frontend/diffs/components/edit_button_spec.js index fc53f26bd42..9bcb23f3cbf 100644 --- a/spec/frontend/diffs/components/edit_button_spec.js +++ b/spec/frontend/diffs/components/edit_button_spec.js @@ -1,7 +1,6 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import EditButton from '~/diffs/components/edit_button.vue'; -const localVue = createLocalVue(); const editPath = 'test-path'; describe('EditButton', () => { @@ -9,7 +8,6 @@ describe('EditButton', () => { const createComponent = (props = {}) => { wrapper = shallowMount(EditButton, { - localVue, propsData: { ...props }, sync: false, attachToDocument: true, diff --git a/spec/frontend/diffs/components/hidden_files_warning_spec.js b/spec/frontend/diffs/components/hidden_files_warning_spec.js index 5bf5ddd27bd..164ff95de6d 100644 --- a/spec/frontend/diffs/components/hidden_files_warning_spec.js +++ b/spec/frontend/diffs/components/hidden_files_warning_spec.js @@ -1,7 +1,6 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import HiddenFilesWarning from '~/diffs/components/hidden_files_warning.vue'; -const localVue = createLocalVue(); const propsData = { total: '10', visible: 5, @@ -14,7 +13,6 @@ describe('HiddenFilesWarning', () => { const createComponent = () => { wrapper = shallowMount(HiddenFilesWarning, { - localVue, sync: false, propsData, }); diff --git a/spec/frontend/diffs/components/no_changes_spec.js b/spec/frontend/diffs/components/no_changes_spec.js index e45d34bf9d5..245651af61c 100644 --- a/spec/frontend/diffs/components/no_changes_spec.js +++ b/spec/frontend/diffs/components/no_changes_spec.js @@ -13,7 +13,7 @@ describe('Diff no changes empty state', () => { const store = createStore(); extendStore(store); - vm = shallowMount(localVue.extend(NoChanges), { + vm = shallowMount(NoChanges, { localVue, store, propsData: { diff --git a/spec/frontend/ide/components/ide_status_list_spec.js b/spec/frontend/ide/components/ide_status_list_spec.js index 4e0e8a9f0e3..e0574450101 100644 --- a/spec/frontend/ide/components/ide_status_list_spec.js +++ b/spec/frontend/ide/components/ide_status_list_spec.js @@ -25,7 +25,7 @@ describe('ide/components/ide_status_list', () => { }, }); - wrapper = shallowMount(localVue.extend(IdeStatusList), { + wrapper = shallowMount(IdeStatusList, { localVue, sync: false, store, diff --git a/spec/frontend/issuables_list/components/issuables_list_app_spec.js b/spec/frontend/issuables_list/components/issuables_list_app_spec.js index 621e8b8aa54..4a2768b9389 100644 --- a/spec/frontend/issuables_list/components/issuables_list_app_spec.js +++ b/spec/frontend/issuables_list/components/issuables_list_app_spec.js @@ -1,6 +1,6 @@ import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { GlEmptyState, GlPagination, GlSkeletonLoading } from '@gitlab/ui'; import waitForPromises from 'helpers/wait_for_promises'; import { TEST_HOST } from 'helpers/test_constants'; @@ -18,8 +18,6 @@ const TEST_ENDPOINT = '/issues'; const TEST_CREATE_ISSUES_PATH = '/createIssue'; const TEST_EMPTY_SVG_PATH = '/emptySvg'; -const localVue = createLocalVue(); - const MOCK_ISSUES = Array(PAGE_SIZE_MANUAL) .fill(0) .map((_, i) => ({ @@ -40,14 +38,13 @@ describe('Issuables list component', () => { }; const factory = (props = { sortKey: 'priority' }) => { - wrapper = shallowMount(localVue.extend(IssuablesListApp), { + wrapper = shallowMount(IssuablesListApp, { propsData: { endpoint: TEST_ENDPOINT, createIssuePath: TEST_CREATE_ISSUES_PATH, emptySvgPath: TEST_EMPTY_SVG_PATH, ...props, }, - localVue, sync: false, attachToDocument: true, }); diff --git a/spec/frontend/issue_show/components/pinned_links_spec.js b/spec/frontend/issue_show/components/pinned_links_spec.js index 77da3390918..bcc131d54c2 100644 --- a/spec/frontend/issue_show/components/pinned_links_spec.js +++ b/spec/frontend/issue_show/components/pinned_links_spec.js @@ -1,9 +1,7 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { GlLink } from '@gitlab/ui'; import PinnedLinks from '~/issue_show/components/pinned_links.vue'; -const localVue = createLocalVue(); - const plainZoomUrl = 'https://zoom.us/j/123456789'; describe('PinnedLinks', () => { @@ -19,8 +17,7 @@ describe('PinnedLinks', () => { }; const createComponent = props => { - wrapper = shallowMount(localVue.extend(PinnedLinks), { - localVue, + wrapper = shallowMount(PinnedLinks, { sync: false, propsData: { zoomMeetingUrl: null, diff --git a/spec/frontend/monitoring/components/charts/column_spec.js b/spec/frontend/monitoring/components/charts/column_spec.js index b4539801e0f..2f43c442600 100644 --- a/spec/frontend/monitoring/components/charts/column_spec.js +++ b/spec/frontend/monitoring/components/charts/column_spec.js @@ -1,9 +1,7 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import { GlColumnChart } from '@gitlab/ui/dist/charts'; import ColumnChart from '~/monitoring/components/charts/column.vue'; -const localVue = createLocalVue(); - jest.mock('~/lib/utils/icon_utils', () => ({ getSvgIconPathContent: jest.fn().mockResolvedValue('mockSvgPathContent'), })); @@ -12,7 +10,7 @@ describe('Column component', () => { let columnChart; beforeEach(() => { - columnChart = shallowMount(localVue.extend(ColumnChart), { + columnChart = shallowMount(ColumnChart, { propsData: { graphData: { metrics: [ @@ -35,7 +33,6 @@ describe('Column component', () => { containerWidth: 100, }, sync: false, - localVue, }); }); diff --git a/spec/frontend/monitoring/components/charts/empty_chart_spec.js b/spec/frontend/monitoring/components/charts/empty_chart_spec.js index 06822126b59..c7f0627f151 100644 --- a/spec/frontend/monitoring/components/charts/empty_chart_spec.js +++ b/spec/frontend/monitoring/components/charts/empty_chart_spec.js @@ -1,19 +1,16 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import EmptyChart from '~/monitoring/components/charts/empty_chart.vue'; -const localVue = createLocalVue(); - describe('Empty Chart component', () => { let emptyChart; const graphTitle = 'Memory Usage'; beforeEach(() => { - emptyChart = shallowMount(localVue.extend(EmptyChart), { + emptyChart = shallowMount(EmptyChart, { propsData: { graphTitle, }, sync: false, - localVue, }); }); diff --git a/spec/frontend/monitoring/components/charts/single_stat_spec.js b/spec/frontend/monitoring/components/charts/single_stat_spec.js index 78bcc400787..dfea4eb41b1 100644 --- a/spec/frontend/monitoring/components/charts/single_stat_spec.js +++ b/spec/frontend/monitoring/components/charts/single_stat_spec.js @@ -1,19 +1,16 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import SingleStatChart from '~/monitoring/components/charts/single_stat.vue'; import { graphDataPrometheusQuery } from '../../mock_data'; -const localVue = createLocalVue(); - describe('Single Stat Chart component', () => { let singleStatChart; beforeEach(() => { - singleStatChart = shallowMount(localVue.extend(SingleStatChart), { + singleStatChart = shallowMount(SingleStatChart, { propsData: { graphData: graphDataPrometheusQuery, }, sync: false, - localVue, }); }); diff --git a/spec/frontend/operation_settings/components/external_dashboard_spec.js b/spec/frontend/operation_settings/components/external_dashboard_spec.js index bb6e029c808..89db03378db 100644 --- a/spec/frontend/operation_settings/components/external_dashboard_spec.js +++ b/spec/frontend/operation_settings/components/external_dashboard_spec.js @@ -1,4 +1,4 @@ -import { mount, shallowMount, createLocalVue } from '@vue/test-utils'; +import { mount, shallowMount } from '@vue/test-utils'; import { GlButton, GlLink, GlFormGroup, GlFormInput } from '@gitlab/ui'; import { TEST_HOST } from 'helpers/test_constants'; import ExternalDashboard from '~/operation_settings/components/external_dashboard.vue'; @@ -15,12 +15,10 @@ describe('operation settings external dashboard component', () => { const operationsSettingsEndpoint = `${TEST_HOST}/mock/ops/settings/endpoint`; const externalDashboardUrl = `http://mock-external-domain.com/external/dashboard/url`; const externalDashboardHelpPagePath = `${TEST_HOST}/help/page/path`; - const localVue = createLocalVue(); const mountComponent = (shallow = true) => { const config = [ ExternalDashboard, { - localVue, store: store({ operationsSettingsEndpoint, externalDashboardUrl, diff --git a/spec/frontend/registry/list/components/app_spec.js b/spec/frontend/registry/list/components/app_spec.js index 5072a285f83..ac95c4dddcf 100644 --- a/spec/frontend/registry/list/components/app_spec.js +++ b/spec/frontend/registry/list/components/app_spec.js @@ -1,4 +1,3 @@ -import Vue from 'vue'; import { mount } from '@vue/test-utils'; import { TEST_HOST } from 'helpers/test_constants'; import registry from '~/registry/list/components/app.vue'; @@ -35,12 +34,8 @@ describe('Registry List', () => { }; beforeEach(() => { - // This is needed due to console.error called by vue to emit a warning that stop the tests. - // See https://github.com/vuejs/vue-test-utils/issues/532. - Vue.config.silent = true; wrapper = mount(registry, { attachToDocument: true, - sync: false, propsData, computed: { repos() { @@ -52,7 +47,6 @@ describe('Registry List', () => { }); afterEach(() => { - Vue.config.silent = false; wrapper.destroy(); }); @@ -138,7 +132,7 @@ describe('Registry List', () => { wrapper = mount(registry, { propsData: { ...propsData, - endpoint: null, + endpoint: '', isGroupPage, }, methods, @@ -146,7 +140,7 @@ describe('Registry List', () => { }); it('call the right vuex setters', () => { - expect(methods.setMainEndpoint).toHaveBeenLastCalledWith(null); + expect(methods.setMainEndpoint).toHaveBeenLastCalledWith(''); expect(methods.setIsDeleteDisabled).toHaveBeenLastCalledWith(true); }); diff --git a/spec/frontend/registry/list/components/collapsible_container_spec.js b/spec/frontend/registry/list/components/collapsible_container_spec.js index c7cf36fe151..1768df89432 100644 --- a/spec/frontend/registry/list/components/collapsible_container_spec.js +++ b/spec/frontend/registry/list/components/collapsible_container_spec.js @@ -1,4 +1,3 @@ -import Vue from 'vue'; import Vuex from 'vuex'; import { mount, createLocalVue } from '@vue/test-utils'; import createFlash from '~/flash'; @@ -28,14 +27,10 @@ describe('collapsible registry container', () => { store, localVue, attachToDocument: true, - sync: false, }); beforeEach(() => { createFlash.mockClear(); - // This is needed due to console.error called by vue to emit a warning that stop the tests - // see https://github.com/vuejs/vue-test-utils/issues/532 - Vue.config.silent = true; store = new Vuex.Store({ state: { isDeleteDisabled: false, @@ -51,7 +46,6 @@ describe('collapsible registry container', () => { }); afterEach(() => { - Vue.config.silent = false; wrapper.destroy(); }); @@ -72,25 +66,23 @@ describe('collapsible registry container', () => { expectIsClosed(); }); - it('should be open when user clicks on closed repo', done => { + it('should be open when user clicks on closed repo', () => { const toggleRepos = findToggleRepos(); toggleRepos.at(0).trigger('click'); - Vue.nextTick(() => { + return wrapper.vm.$nextTick().then(() => { const container = findContainerImageTags(); expect(container.exists()).toBe(true); expect(wrapper.vm.fetchList).toHaveBeenCalled(); - done(); }); }); - it('should be closed when the user clicks on an opened repo', done => { + it('should be closed when the user clicks on an opened repo', () => { const toggleRepos = findToggleRepos(); toggleRepos.at(0).trigger('click'); - Vue.nextTick(() => { + return wrapper.vm.$nextTick().then(() => { toggleRepos.at(0).trigger('click'); - Vue.nextTick(() => { + wrapper.vm.$nextTick(() => { expectIsClosed(); - done(); }); }); }); diff --git a/spec/frontend/registry/list/components/table_registry_spec.js b/spec/frontend/registry/list/components/table_registry_spec.js index 1b545eea034..935f93db883 100644 --- a/spec/frontend/registry/list/components/table_registry_spec.js +++ b/spec/frontend/registry/list/components/table_registry_spec.js @@ -1,4 +1,3 @@ -import Vue from 'vue'; import Vuex from 'vuex'; import { mount, createLocalVue } from '@vue/test-utils'; import createFlash from '~/flash'; @@ -29,13 +28,9 @@ describe('table registry', () => { const bulkDeletePath = 'path'; const mountWithStore = config => - mount(tableRegistry, { ...config, store, localVue, attachToDocument: true, sync: false }); + mount(tableRegistry, { ...config, store, localVue, attachToDocument: true }); beforeEach(() => { - // This is needed due to console.error called by vue to emit a warning that stop the tests - // see https://github.com/vuejs/vue-test-utils/issues/532 - Vue.config.silent = true; - store = new Vuex.Store({ state: { isDeleteDisabled: false, @@ -52,7 +47,6 @@ describe('table registry', () => { }); afterEach(() => { - Vue.config.silent = false; wrapper.destroy(); }); @@ -82,53 +76,53 @@ describe('table registry', () => { }); describe('multi select', () => { - it('selecting a row should enable delete button', done => { + it('selecting a row should enable delete button', () => { const deleteBtn = findDeleteButton(); const checkboxes = findSelectCheckboxes(); expect(deleteBtn.attributes('disabled')).toBe('disabled'); checkboxes.at(0).trigger('click'); - Vue.nextTick(() => { + return wrapper.vm.$nextTick().then(() => { expect(deleteBtn.attributes('disabled')).toEqual(undefined); - done(); }); }); - it('selecting all checkbox should select all rows and enable delete button', done => { + it('selecting all checkbox should select all rows and enable delete button', () => { const selectAll = findSelectAllCheckbox(); selectAll.trigger('click'); - Vue.nextTick(() => { + return wrapper.vm.$nextTick().then(() => { const checkboxes = findSelectCheckboxes(); const checked = checkboxes.filter(w => w.element.checked); expect(checked.length).toBe(checkboxes.length); - done(); }); }); - it('deselecting select all checkbox should deselect all rows and disable delete button', done => { + it('deselecting select all checkbox should deselect all rows and disable delete button', () => { const checkboxes = findSelectCheckboxes(); const selectAll = findSelectAllCheckbox(); selectAll.trigger('click'); selectAll.trigger('click'); - Vue.nextTick(() => { + return wrapper.vm.$nextTick().then(() => { const checked = checkboxes.filter(w => !w.element.checked); expect(checked.length).toBe(checkboxes.length); - done(); }); }); - it('should delete multiple items when multiple items are selected', done => { + it('should delete multiple items when multiple items are selected', () => { const multiDeleteItems = jest.fn().mockResolvedValue(); wrapper.setMethods({ multiDeleteItems }); - Vue.nextTick(() => { - const selectAll = findSelectAllCheckbox(); - selectAll.trigger('click'); - - Vue.nextTick(() => { + return wrapper.vm + .$nextTick() + .then(() => { + const selectAll = findSelectAllCheckbox(); + selectAll.trigger('click'); + return wrapper.vm.$nextTick(); + }) + .then(() => { const deleteBtn = findDeleteButton(); expect(wrapper.vm.selectedItems).toEqual([0, 1]); expect(deleteBtn.attributes('disabled')).toEqual(undefined); @@ -140,9 +134,7 @@ describe('table registry', () => { path: bulkDeletePath, items: [firstImage.tag, secondImage.tag], }); - done(); }); - }); }); it('should show an error message if bulkDeletePath is not set', () => { diff --git a/spec/frontend/releases/list/components/evidence_block_spec.js b/spec/frontend/releases/list/components/evidence_block_spec.js index 1be6083f4ab..39f3975f665 100644 --- a/spec/frontend/releases/list/components/evidence_block_spec.js +++ b/spec/frontend/releases/list/components/evidence_block_spec.js @@ -1,4 +1,4 @@ -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; import { GlLink } from '@gitlab/ui'; import { truncateSha } from '~/lib/utils/text_utility'; import Icon from '~/vue_shared/components/icon.vue'; @@ -10,10 +10,7 @@ describe('Evidence Block', () => { let wrapper; const factory = (options = {}) => { - const localVue = createLocalVue(); - - wrapper = mount(localVue.extend(EvidenceBlock), { - localVue, + wrapper = mount(EvidenceBlock, { ...options, }); }; diff --git a/spec/frontend/serverless/components/environment_row_spec.js b/spec/frontend/serverless/components/environment_row_spec.js index 866b2165917..21637473e42 100644 --- a/spec/frontend/serverless/components/environment_row_spec.js +++ b/spec/frontend/serverless/components/environment_row_spec.js @@ -1,20 +1,18 @@ -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import environmentRowComponent from '~/serverless/components/environment_row.vue'; import { mockServerlessFunctions, mockServerlessFunctionsDiffEnv } from '../mock_data'; import { translate } from '~/serverless/utils'; -const createComponent = (localVue, env, envName) => - shallowMount(environmentRowComponent, { localVue, propsData: { env, envName }, sync: false }).vm; +const createComponent = (env, envName) => + shallowMount(environmentRowComponent, { propsData: { env, envName }, sync: false }).vm; describe('environment row component', () => { describe('default global cluster case', () => { - let localVue; let vm; beforeEach(() => { - localVue = createLocalVue(); - vm = createComponent(localVue, translate(mockServerlessFunctions.functions)['*'], '*'); + vm = createComponent(translate(mockServerlessFunctions.functions)['*'], '*'); }); afterEach(() => vm.$destroy()); @@ -44,15 +42,9 @@ describe('environment row component', () => { describe('default named cluster case', () => { let vm; - let localVue; beforeEach(() => { - localVue = createLocalVue(); - vm = createComponent( - localVue, - translate(mockServerlessFunctionsDiffEnv.functions).test, - 'test', - ); + vm = createComponent(translate(mockServerlessFunctionsDiffEnv.functions).test, 'test'); }); afterEach(() => vm.$destroy()); diff --git a/spec/javascripts/pipelines/header_component_spec.js b/spec/javascripts/pipelines/header_component_spec.js index 556a0976b29..8c033447ce4 100644 --- a/spec/javascripts/pipelines/header_component_spec.js +++ b/spec/javascripts/pipelines/header_component_spec.js @@ -34,6 +34,7 @@ describe('Pipeline details header', () => { avatar_url: 'link', }, retry_path: 'path', + delete_path: 'path', }, isLoading: false, }; @@ -55,12 +56,22 @@ describe('Pipeline details header', () => { }); describe('action buttons', () => { - it('should call postAction when button action is clicked', () => { + it('should call postAction when retry button action is clicked', done => { eventHub.$on('headerPostAction', action => { expect(action.path).toEqual('path'); + done(); }); - vm.$el.querySelector('button').click(); + vm.$el.querySelector('.js-retry-button').click(); + }); + + it('should fire modal event when delete button action is clicked', done => { + vm.$root.$on('bv::modal::show', action => { + expect(action.componentId).toEqual('pipeline-delete-modal'); + done(); + }); + + vm.$el.querySelector('.js-btn-delete-pipeline').click(); }); }); }); diff --git a/spec/javascripts/vue_shared/components/header_ci_component_spec.js b/spec/javascripts/vue_shared/components/header_ci_component_spec.js index 7bd5e5a64b1..ea2eed2886a 100644 --- a/spec/javascripts/vue_shared/components/header_ci_component_spec.js +++ b/spec/javascripts/vue_shared/components/header_ci_component_spec.js @@ -31,17 +31,9 @@ describe('Header CI Component', () => { { label: 'Retry', path: 'path', - type: 'button', cssClass: 'btn', isLoading: false, }, - { - label: 'Go', - path: 'path', - type: 'link', - cssClass: 'link', - isLoading: false, - }, ], hasSidebarButton: true, }; @@ -77,11 +69,10 @@ describe('Header CI Component', () => { }); it('should render provided actions', () => { - expect(vm.$el.querySelector('.btn').tagName).toEqual('BUTTON'); - expect(vm.$el.querySelector('.btn').textContent.trim()).toEqual(props.actions[0].label); - expect(vm.$el.querySelector('.link').tagName).toEqual('A'); - expect(vm.$el.querySelector('.link').textContent.trim()).toEqual(props.actions[1].label); - expect(vm.$el.querySelector('.link').getAttribute('href')).toEqual(props.actions[0].path); + const btn = vm.$el.querySelector('.btn'); + + expect(btn.tagName).toEqual('BUTTON'); + expect(btn.textContent.trim()).toEqual(props.actions[0].label); }); it('should show loading icon', done => { diff --git a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb index 4c4359ad5d2..aaea044595f 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb @@ -15,42 +15,6 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do stub_feature_flags(ci_root_config_content: false) end - context 'when bridge job is passed in as parameter' do - let(:ci_config_path) { nil } - let(:bridge) { create(:ci_bridge) } - - before do - command.bridge = bridge - end - - context 'when bridge job has downstream yaml' do - before do - allow(bridge).to receive(:yaml_for_downstream).and_return('the-yaml') - end - - it 'returns the content already available in command' do - subject.perform! - - expect(pipeline.config_source).to eq 'bridge_source' - expect(command.config_content).to eq 'the-yaml' - end - end - - context 'when bridge job does not have downstream yaml' do - before do - allow(bridge).to receive(:yaml_for_downstream).and_return(nil) - end - - it 'returns the next available source' do - subject.perform! - - expect(pipeline.config_source).to eq 'auto_devops_source' - template = Gitlab::Template::GitlabCiYmlTemplate.find('Beta/Auto-DevOps') - expect(command.config_content).to eq(template.content) - end - end - end - context 'when config is defined in a custom path in the repository' do let(:ci_config_path) { 'path/to/config.yml' } @@ -171,23 +135,6 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do end end - context 'when bridge job is passed in as parameter' do - let(:ci_config_path) { nil } - let(:bridge) { create(:ci_bridge) } - - before do - command.bridge = bridge - allow(bridge).to receive(:yaml_for_downstream).and_return('the-yaml') - end - - it 'returns the content already available in command' do - subject.perform! - - expect(pipeline.config_source).to eq 'bridge_source' - expect(command.config_content).to eq 'the-yaml' - end - end - context 'when config is defined in a custom path in the repository' do let(:ci_config_path) { 'path/to/config.yml' } let(:config_content_result) do diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 07439880beb..a45ad514da2 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -201,8 +201,6 @@ ci_pipelines: - sourced_pipelines - triggered_by_pipeline - triggered_pipelines -- child_pipelines -- parent_pipeline - downstream_bridges - job_artifacts - vulnerabilities_occurrence_pipelines diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index ce01765bb8c..b30e88532e1 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -2716,114 +2716,4 @@ describe Ci::Pipeline, :mailer do end end end - - describe '#parent_pipeline' do - let(:project) { create(:project) } - let(:pipeline) { create(:ci_pipeline, project: project) } - - context 'when pipeline is triggered by a pipeline from the same project' do - let(:upstream_pipeline) { create(:ci_pipeline, project: pipeline.project) } - - before do - create(:ci_sources_pipeline, - source_pipeline: upstream_pipeline, - source_project: project, - pipeline: pipeline, - project: project) - end - - it 'returns the parent pipeline' do - expect(pipeline.parent_pipeline).to eq(upstream_pipeline) - end - - it 'is child' do - expect(pipeline).to be_child - end - end - - context 'when pipeline is triggered by a pipeline from another project' do - let(:upstream_pipeline) { create(:ci_pipeline) } - - before do - create(:ci_sources_pipeline, - source_pipeline: upstream_pipeline, - source_project: upstream_pipeline.project, - pipeline: pipeline, - project: project) - end - - it 'returns nil' do - expect(pipeline.parent_pipeline).to be_nil - end - - it 'is not child' do - expect(pipeline).not_to be_child - end - end - - context 'when pipeline is not triggered by a pipeline' do - it 'returns nil' do - expect(pipeline.parent_pipeline).to be_nil - end - - it 'is not child' do - expect(pipeline).not_to be_child - end - end - end - - describe '#child_pipelines' do - let(:project) { create(:project) } - let(:pipeline) { create(:ci_pipeline, project: project) } - - context 'when pipeline triggered other pipelines on same project' do - let(:downstream_pipeline) { create(:ci_pipeline, project: pipeline.project) } - - before do - create(:ci_sources_pipeline, - source_pipeline: pipeline, - source_project: pipeline.project, - pipeline: downstream_pipeline, - project: pipeline.project) - end - - it 'returns the child pipelines' do - expect(pipeline.child_pipelines).to eq [downstream_pipeline] - end - - it 'is parent' do - expect(pipeline).to be_parent - end - end - - context 'when pipeline triggered other pipelines on another project' do - let(:downstream_pipeline) { create(:ci_pipeline) } - - before do - create(:ci_sources_pipeline, - source_pipeline: pipeline, - source_project: pipeline.project, - pipeline: downstream_pipeline, - project: downstream_pipeline.project) - end - - it 'returns empty array' do - expect(pipeline.child_pipelines).to be_empty - end - - it 'is not parent' do - expect(pipeline).not_to be_parent - end - end - - context 'when pipeline did not trigger any pipelines' do - it 'returns empty array' do - expect(pipeline.child_pipelines).to be_empty - end - - it 'is not parent' do - expect(pipeline).not_to be_parent - end - end - end end diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb index d95aaf3d104..75f3bdfcc9e 100644 --- a/spec/serializers/pipeline_entity_spec.rb +++ b/spec/serializers/pipeline_entity_spec.rb @@ -123,6 +123,26 @@ describe PipelineEntity do end end + context 'delete path' do + context 'user has ability to delete pipeline' do + let(:project) { create(:project, namespace: user.namespace) } + let(:pipeline) { create(:ci_pipeline, project: project) } + + it 'contains delete path' do + expect(subject[:delete_path]).to be_present + end + end + + context 'user does not have ability to delete pipeline' do + let(:project) { create(:project) } + let(:pipeline) { create(:ci_pipeline, project: project) } + + it 'does not contain delete path' do + expect(subject).not_to have_key(:delete_path) + end + end + end + context 'when pipeline ref is empty' do let(:pipeline) { create(:ci_empty_pipeline) } diff --git a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb b/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb deleted file mode 100644 index 33cd6e164b0..00000000000 --- a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true -require 'spec_helper' - -describe Ci::CreatePipelineService do - let_it_be(:project) { create(:project, :repository) } - let_it_be(:user) { create(:admin) } - let(:ref) { 'refs/heads/master' } - let(:service) { described_class.new(project, user, { ref: ref }) } - - context 'custom config content' do - let(:bridge) do - double(:bridge, yaml_for_downstream: <<~YML - rspec: - script: rspec - custom: - script: custom - YML - ) - end - - subject { service.execute(:push, bridge: bridge) } - - it 'creates a pipeline using the content passed in as param' do - expect(subject).to be_persisted - expect(subject.builds.map(&:name)).to eq %w[rspec custom] - expect(subject.config_source).to eq 'bridge_source' - end - end -end |