diff options
Diffstat (limited to 'spec/frontend/jobs/components')
10 files changed, 73 insertions, 78 deletions
diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js index 07e6ee46c41..d4e1e711777 100644 --- a/spec/frontend/jobs/components/job_app_spec.js +++ b/spec/frontend/jobs/components/job_app_spec.js @@ -1,5 +1,6 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue, { nextTick } from 'vue'; import MockAdapter from 'axios-mock-adapter'; import Vuex from 'vuex'; import delayedJobFixture from 'test_fixtures/jobs/delayed.json'; @@ -16,8 +17,7 @@ import axios from '~/lib/utils/axios_utils'; import job from '../mock_data'; describe('Job App', () => { - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); let store; let wrapper; @@ -45,7 +45,7 @@ describe('Job App', () => { wrapper = mount(JobApp, { propsData: { ...props }, store }); }; - const setupAndMount = ({ jobData = {}, jobLogData = {} } = {}) => { + const setupAndMount = async ({ jobData = {}, jobLogData = {} } = {}) => { mock.onGet(initSettings.endpoint).replyOnce(200, { ...job, ...jobData }); mock.onGet(`${initSettings.pagePath}/trace.json`).reply(200, jobLogData); @@ -53,12 +53,10 @@ describe('Job App', () => { createComponent(); - return asyncInit - .then(() => { - jest.runOnlyPendingTimers(); - }) - .then(() => axios.waitForAll()) - .then(() => wrapper.vm.$nextTick()); + await asyncInit; + jest.runOnlyPendingTimers(); + await axios.waitForAll(); + await nextTick(); }; const findLoadingComponent = () => wrapper.find(GlLoadingIcon); diff --git a/spec/frontend/jobs/components/job_container_item_spec.js b/spec/frontend/jobs/components/job_container_item_spec.js index 6b488821bc1..eb2b0184e5f 100644 --- a/spec/frontend/jobs/components/job_container_item_spec.js +++ b/spec/frontend/jobs/components/job_container_item_spec.js @@ -1,5 +1,6 @@ import { GlIcon, GlLink } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import delayedJobFixture from 'test_fixtures/jobs/delayed.json'; import JobContainerItem from '~/jobs/components/job_container_item.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; @@ -87,7 +88,7 @@ describe('JobContainerItem', () => { }); it('displays remaining time in tooltip', async () => { - await wrapper.vm.$nextTick(); + await nextTick(); const link = wrapper.findComponent(GlLink); diff --git a/spec/frontend/jobs/components/job_log_controllers_spec.js b/spec/frontend/jobs/components/job_log_controllers_spec.js index 0ba07522243..226322a2951 100644 --- a/spec/frontend/jobs/components/job_log_controllers_spec.js +++ b/spec/frontend/jobs/components/job_log_controllers_spec.js @@ -1,4 +1,5 @@ import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import JobLogControllers from '~/jobs/components/job_log_controllers.vue'; describe('Job log controllers', () => { @@ -111,7 +112,7 @@ describe('Job log controllers', () => { it('emits scrollJobLogTop event on click', async () => { findScrollTop().trigger('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.emitted().scrollJobLogTop).toHaveLength(1); }); @@ -133,7 +134,7 @@ describe('Job log controllers', () => { it('does not emit scrollJobLogTop event on click', async () => { findScrollTop().trigger('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.emitted().scrollJobLogTop).toBeUndefined(); }); @@ -149,7 +150,7 @@ describe('Job log controllers', () => { it('emits scrollJobLogBottom event on click', async () => { findScrollBottom().trigger('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.emitted().scrollJobLogBottom).toHaveLength(1); }); @@ -171,7 +172,7 @@ describe('Job log controllers', () => { it('does not emit scrollJobLogBottom event on click', async () => { findScrollBottom().trigger('click'); - await wrapper.vm.$nextTick(); + await nextTick(); expect(wrapper.emitted().scrollJobLogBottom).toBeUndefined(); }); diff --git a/spec/frontend/jobs/components/log/collapsible_section_spec.js b/spec/frontend/jobs/components/log/collapsible_section_spec.js index 96bdf03796b..22ddc8b1c2d 100644 --- a/spec/frontend/jobs/components/log/collapsible_section_spec.js +++ b/spec/frontend/jobs/components/log/collapsible_section_spec.js @@ -1,4 +1,5 @@ import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import CollapsibleSection from '~/jobs/components/log/collapsible_section.vue'; import { collapsibleSectionClosed, collapsibleSectionOpened } from './mock_data'; @@ -69,7 +70,7 @@ describe('Job Log Collapsible Section', () => { }); }); - it('emits onClickCollapsibleLine on click', () => { + it('emits onClickCollapsibleLine on click', async () => { createComponent({ section: collapsibleSectionOpened, jobLogEndpoint, @@ -77,8 +78,7 @@ describe('Job Log Collapsible Section', () => { findCollapsibleLine().trigger('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted('onClickCollapsibleLine').length).toBe(1); - }); + await nextTick(); + expect(wrapper.emitted('onClickCollapsibleLine').length).toBe(1); }); }); diff --git a/spec/frontend/jobs/components/log/line_header_spec.js b/spec/frontend/jobs/components/log/line_header_spec.js index 9763e2f437b..8055fe64d95 100644 --- a/spec/frontend/jobs/components/log/line_header_spec.js +++ b/spec/frontend/jobs/components/log/line_header_spec.js @@ -1,4 +1,5 @@ import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import DurationBadge from '~/jobs/components/log/duration_badge.vue'; import LineHeader from '~/jobs/components/log/line_header.vue'; import LineNumber from '~/jobs/components/log/line_number.vue'; @@ -75,12 +76,11 @@ describe('Job Log Header Line', () => { createComponent(data); }); - it('emits toggleLine event', () => { + it('emits toggleLine event', async () => { wrapper.trigger('click'); - return wrapper.vm.$nextTick().then(() => { - expect(wrapper.emitted().toggleLine.length).toBe(1); - }); + await nextTick(); + expect(wrapper.emitted().toggleLine.length).toBe(1); }); }); diff --git a/spec/frontend/jobs/components/log/log_spec.js b/spec/frontend/jobs/components/log/log_spec.js index 9a5522ab4cd..7e11738f82e 100644 --- a/spec/frontend/jobs/components/log/log_spec.js +++ b/spec/frontend/jobs/components/log/log_spec.js @@ -1,4 +1,5 @@ -import { mount, createLocalVue } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; +import Vue from 'vue'; import Vuex from 'vuex'; import Log from '~/jobs/components/log/log.vue'; import { logLinesParserLegacy, logLinesParser } from '~/jobs/store/utils'; @@ -11,12 +12,10 @@ describe('Job Log', () => { let store; let origGon; - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); const createComponent = () => { wrapper = mount(Log, { - localVue, store, }); }; @@ -91,12 +90,10 @@ describe('Job Log, infinitelyCollapsibleSections feature flag enabled', () => { let store; let origGon; - const localVue = createLocalVue(); - localVue.use(Vuex); + Vue.use(Vuex); const createComponent = () => { wrapper = mount(Log, { - localVue, store, }); }; diff --git a/spec/frontend/jobs/components/manual_variables_form_spec.js b/spec/frontend/jobs/components/manual_variables_form_spec.js index a5278af8e33..6faab3ddf31 100644 --- a/spec/frontend/jobs/components/manual_variables_form_spec.js +++ b/spec/frontend/jobs/components/manual_variables_form_spec.js @@ -1,12 +1,10 @@ import { GlSprintf, GlLink } from '@gitlab/ui'; -import { createLocalVue, mount } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import ManualVariablesForm from '~/jobs/components/manual_variables_form.vue'; -const localVue = createLocalVue(); - Vue.use(Vuex); describe('Manual Variables Form', () => { @@ -29,9 +27,8 @@ describe('Manual Variables Form', () => { }); wrapper = extendedWrapper( - mount(localVue.extend(ManualVariablesForm), { + mount(ManualVariablesForm, { propsData: { ...requiredProps, ...props }, - localVue, store, stubs: { GlSprintf, diff --git a/spec/frontend/jobs/components/sidebar_spec.js b/spec/frontend/jobs/components/sidebar_spec.js index 500a1b48950..6e327725627 100644 --- a/spec/frontend/jobs/components/sidebar_spec.js +++ b/spec/frontend/jobs/components/sidebar_spec.js @@ -1,4 +1,5 @@ import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import ArtifactsBlock from '~/jobs/components/artifacts_block.vue'; import JobRetryForwardDeploymentModal from '~/jobs/components/job_retry_forward_deployment_modal.vue'; @@ -189,7 +190,7 @@ describe('Sidebar details block', () => { locked: false, }; - await wrapper.vm.$nextTick(); + await nextTick(); expect(findArtifactsBlock().exists()).toBe(true); }); diff --git a/spec/frontend/jobs/components/table/cells/actions_cell_spec.js b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js index 6caf36e1461..263698e94e1 100644 --- a/spec/frontend/jobs/components/table/cells/actions_cell_spec.js +++ b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js @@ -1,13 +1,16 @@ import { GlModal } from '@gitlab/ui'; import { nextTick } from 'vue'; +import waitForPromises from 'helpers/wait_for_promises'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import ActionsCell from '~/jobs/components/table/cells/actions_cell.vue'; import JobPlayMutation from '~/jobs/components/table/graphql/mutations/job_play.mutation.graphql'; import JobRetryMutation from '~/jobs/components/table/graphql/mutations/job_retry.mutation.graphql'; import JobUnscheduleMutation from '~/jobs/components/table/graphql/mutations/job_unschedule.mutation.graphql'; +import JobCancelMutation from '~/jobs/components/table/graphql/mutations/job_cancel.mutation.graphql'; import { playableJob, retryableJob, + cancelableJob, scheduledJob, cannotRetryJob, cannotPlayJob, @@ -20,6 +23,7 @@ describe('Job actions cell', () => { const findRetryButton = () => wrapper.findByTestId('retry'); const findPlayButton = () => wrapper.findByTestId('play'); + const findCancelButton = () => wrapper.findByTestId('cancel-button'); const findDownloadArtifactsButton = () => wrapper.findByTestId('download-artifacts'); const findCountdownButton = () => wrapper.findByTestId('countdown'); const findPlayScheduledJobButton = () => wrapper.findByTestId('play-scheduled'); @@ -32,6 +36,7 @@ describe('Job actions cell', () => { data: { JobUnscheduleMutation: { jobId: scheduledJob.id } }, }; const MUTATION_SUCCESS_PLAY = { data: { JobPlayMutation: { jobId: playableJob.id } } }; + const MUTATION_SUCCESS_CANCEL = { data: { JobCancelMutation: { jobId: cancelableJob.id } } }; const $toast = { show: jest.fn(), @@ -88,6 +93,7 @@ describe('Job actions cell', () => { ${findPlayButton} | ${'play'} | ${playableJob} ${findRetryButton} | ${'retry'} | ${retryableJob} ${findDownloadArtifactsButton} | ${'download artifacts'} | ${playableJob} + ${findCancelButton} | ${'cancel'} | ${cancelableJob} `('displays the $action button', ({ button, jobType }) => { createComponent(jobType); @@ -95,9 +101,10 @@ describe('Job actions cell', () => { }); it.each` - button | mutationResult | action | jobType | mutationFile - ${findPlayButton} | ${MUTATION_SUCCESS_PLAY} | ${'play'} | ${playableJob} | ${JobPlayMutation} - ${findRetryButton} | ${MUTATION_SUCCESS} | ${'retry'} | ${retryableJob} | ${JobRetryMutation} + button | mutationResult | action | jobType | mutationFile + ${findPlayButton} | ${MUTATION_SUCCESS_PLAY} | ${'play'} | ${playableJob} | ${JobPlayMutation} + ${findRetryButton} | ${MUTATION_SUCCESS} | ${'retry'} | ${retryableJob} | ${JobRetryMutation} + ${findCancelButton} | ${MUTATION_SUCCESS_CANCEL} | ${'cancel'} | ${cancelableJob} | ${JobCancelMutation} `('performs the $action mutation', ({ button, mutationResult, jobType, mutationFile }) => { createComponent(jobType, mutationResult); @@ -111,6 +118,24 @@ describe('Job actions cell', () => { }); }); + it.each` + button | action | jobType + ${findPlayButton} | ${'play'} | ${playableJob} + ${findRetryButton} | ${'retry'} | ${retryableJob} + ${findCancelButton} | ${'cancel'} | ${cancelableJob} + ${findUnscheduleButton} | ${'unschedule'} | ${scheduledJob} + `('disables the $action button after first request', async ({ button, jobType }) => { + createComponent(jobType); + + expect(button().props('disabled')).toBe(false); + + button().vm.$emit('click'); + + await waitForPromises(); + + expect(button().props('disabled')).toBe(true); + }); + describe('Scheduled Jobs', () => { const today = () => new Date('2021-08-31'); diff --git a/spec/frontend/jobs/components/table/job_table_app_spec.js b/spec/frontend/jobs/components/table/job_table_app_spec.js index 05988eecb10..5ccd38af735 100644 --- a/spec/frontend/jobs/components/table/job_table_app_spec.js +++ b/spec/frontend/jobs/components/table/job_table_app_spec.js @@ -1,5 +1,6 @@ import { GlSkeletonLoader, GlAlert, GlEmptyState, GlPagination } from '@gitlab/ui'; -import { createLocalVue, mount, shallowMount } from '@vue/test-utils'; +import { mount, shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; @@ -7,11 +8,15 @@ import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query import JobsTable from '~/jobs/components/table/jobs_table.vue'; import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue'; import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue'; -import { mockJobsQueryResponse, mockJobsQueryEmptyResponse } from '../../mock_data'; +import { + mockJobsQueryResponse, + mockJobsQueryEmptyResponse, + mockJobsQueryResponseLastPage, + mockJobsQueryResponseFirstPage, +} from '../../mock_data'; const projectPath = 'gitlab-org/gitlab'; -const localVue = createLocalVue(); -localVue.use(VueApollo); +Vue.use(VueApollo); describe('Job table app', () => { let wrapper; @@ -50,7 +55,6 @@ describe('Job table app', () => { provide: { projectPath, }, - localVue, apolloProvider: createMockApolloProvider(handler), }); }; @@ -96,35 +100,14 @@ describe('Job table app', () => { describe('pagination', () => { it('should disable the next page button on the last page', async () => { createComponent({ - handler: successHandler, + handler: jest.fn().mockResolvedValue(mockJobsQueryResponseLastPage), mountFn: mount, data: { - pagination: { - currentPage: 3, - }, - jobs: { - pageInfo: { - hasPreviousPage: true, - startCursor: 'abc', - endCursor: 'bcd', - }, - }, + pagination: { currentPage: 3 }, }, }); - await wrapper.vm.$nextTick(); - - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ - jobs: { - pageInfo: { - hasNextPage: false, - }, - }, - }); - - await wrapper.vm.$nextTick(); + await waitForPromises(); expect(findPrevious().exists()).toBe(true); expect(findNext().exists()).toBe(true); @@ -133,24 +116,16 @@ describe('Job table app', () => { it('should disable the previous page button on the first page', async () => { createComponent({ - handler: successHandler, + handler: jest.fn().mockResolvedValue(mockJobsQueryResponseFirstPage), mountFn: mount, data: { pagination: { currentPage: 1, }, - jobs: { - pageInfo: { - hasNextPage: true, - hasPreviousPage: false, - startCursor: 'abc', - endCursor: 'bcd', - }, - }, }, }); - await wrapper.vm.$nextTick(); + await waitForPromises(); expect(findPrevious().exists()).toBe(true); expect(findPrevious().classes('disabled')).toBe(true); |