From 36a59d088eca61b834191dacea009677a96c052f Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 19 May 2022 07:33:21 +0000 Subject: Add latest changes from gitlab-org/gitlab@15-0-stable-ee --- .../tokens/job_status_token_spec.js | 1 + spec/frontend/jobs/components/job_app_spec.js | 4 +- spec/frontend/jobs/components/stuck_block_spec.js | 6 +- .../components/table/cells/actions_cell_spec.js | 105 ++++++++++++++------- 4 files changed, 80 insertions(+), 36 deletions(-) (limited to 'spec/frontend/jobs/components') diff --git a/spec/frontend/jobs/components/filtered_search/tokens/job_status_token_spec.js b/spec/frontend/jobs/components/filtered_search/tokens/job_status_token_spec.js index ce8e482cc16..92ce3925a90 100644 --- a/spec/frontend/jobs/components/filtered_search/tokens/job_status_token_spec.js +++ b/spec/frontend/jobs/components/filtered_search/tokens/job_status_token_spec.js @@ -21,6 +21,7 @@ describe('Job Status Token', () => { value: { data: '', }, + cursorPosition: 'start', }; const createComponent = () => { diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js index 9abe66b4696..fc308766ab9 100644 --- a/spec/frontend/jobs/components/job_app_spec.js +++ b/spec/frontend/jobs/components/job_app_spec.js @@ -129,7 +129,9 @@ describe('Job App', () => { const aYearAgo = new Date(); aYearAgo.setFullYear(aYearAgo.getFullYear() - 1); - return setupAndMount({ jobData: { started: aYearAgo.toISOString() } }); + return setupAndMount({ + jobData: { started: aYearAgo.toISOString(), started_at: aYearAgo.toISOString() }, + }); }); it('should render provided job information', () => { diff --git a/spec/frontend/jobs/components/stuck_block_spec.js b/spec/frontend/jobs/components/stuck_block_spec.js index 4db73eaaaec..1580ed45e46 100644 --- a/spec/frontend/jobs/components/stuck_block_spec.js +++ b/spec/frontend/jobs/components/stuck_block_spec.js @@ -32,7 +32,7 @@ describe('Stuck Block Job component', () => { describe('with no runners for project', () => { beforeEach(() => { createWrapper({ - hasNoRunnersForProject: true, + hasOfflineRunnersForProject: true, runnersPath: '/root/project/runners#js-runners-settings', }); }); @@ -53,7 +53,7 @@ describe('Stuck Block Job component', () => { describe('with tags', () => { beforeEach(() => { createWrapper({ - hasNoRunnersForProject: false, + hasOfflineRunnersForProject: false, tags, runnersPath: '/root/project/runners#js-runners-settings', }); @@ -81,7 +81,7 @@ describe('Stuck Block Job component', () => { describe('without active runners', () => { beforeEach(() => { createWrapper({ - hasNoRunnersForProject: false, + hasOfflineRunnersForProject: false, runnersPath: '/root/project/runners#js-runners-settings', }); }); 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 263698e94e1..976b128532d 100644 --- a/spec/frontend/jobs/components/table/cells/actions_cell_spec.js +++ b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js @@ -1,8 +1,12 @@ import { GlModal } from '@gitlab/ui'; -import { nextTick } from 'vue'; +import Vue, { nextTick } from 'vue'; +import VueApollo from 'vue-apollo'; +import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { redirectTo } from '~/lib/utils/url_utility'; import ActionsCell from '~/jobs/components/table/cells/actions_cell.vue'; +import eventHub from '~/jobs/components/table/event_hub'; 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'; @@ -15,11 +19,18 @@ import { cannotRetryJob, cannotPlayJob, cannotPlayScheduledJob, + retryMutationResponse, + playMutationResponse, + cancelMutationResponse, + unscheduleMutationResponse, } from '../../../mock_data'; +jest.mock('~/lib/utils/url_utility'); + +Vue.use(VueApollo); + describe('Job actions cell', () => { let wrapper; - let mutate; const findRetryButton = () => wrapper.findByTestId('retry'); const findPlayButton = () => wrapper.findByTestId('play'); @@ -31,29 +42,27 @@ describe('Job actions cell', () => { const findModal = () => wrapper.findComponent(GlModal); - const MUTATION_SUCCESS = { data: { JobRetryMutation: { jobId: retryableJob.id } } }; - const MUTATION_SUCCESS_UNSCHEDULE = { - data: { JobUnscheduleMutation: { jobId: scheduledJob.id } }, - }; - const MUTATION_SUCCESS_PLAY = { data: { JobPlayMutation: { jobId: playableJob.id } } }; - const MUTATION_SUCCESS_CANCEL = { data: { JobCancelMutation: { jobId: cancelableJob.id } } }; + const playMutationHandler = jest.fn().mockResolvedValue(playMutationResponse); + const retryMutationHandler = jest.fn().mockResolvedValue(retryMutationResponse); + const unscheduleMutationHandler = jest.fn().mockResolvedValue(unscheduleMutationResponse); + const cancelMutationHandler = jest.fn().mockResolvedValue(cancelMutationResponse); const $toast = { show: jest.fn(), }; - const createComponent = (jobType, mutationType = MUTATION_SUCCESS, props = {}) => { - mutate = jest.fn().mockResolvedValue(mutationType); + const createMockApolloProvider = (requestHandlers) => { + return createMockApollo(requestHandlers); + }; + const createComponent = (jobType, requestHandlers, props = {}) => { wrapper = shallowMountExtended(ActionsCell, { propsData: { job: jobType, ...props, }, + apolloProvider: createMockApolloProvider(requestHandlers), mocks: { - $apollo: { - mutate, - }, $toast, }, }); @@ -101,23 +110,58 @@ describe('Job actions cell', () => { }); it.each` - 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); + button | action | jobType | mutationFile | handler | jobId + ${findPlayButton} | ${'play'} | ${playableJob} | ${JobPlayMutation} | ${playMutationHandler} | ${playableJob.id} + ${findRetryButton} | ${'retry'} | ${retryableJob} | ${JobRetryMutation} | ${retryMutationHandler} | ${retryableJob.id} + ${findCancelButton} | ${'cancel'} | ${cancelableJob} | ${JobCancelMutation} | ${cancelMutationHandler} | ${cancelableJob.id} + `('performs the $action mutation', async ({ button, jobType, mutationFile, handler, jobId }) => { + createComponent(jobType, [[mutationFile, handler]]); button().vm.$emit('click'); - expect(mutate).toHaveBeenCalledWith({ - mutation: mutationFile, - variables: { - id: jobType.id, - }, - }); + expect(handler).toHaveBeenCalledWith({ id: jobId }); }); + it.each` + button | action | jobType | mutationFile | handler + ${findUnscheduleButton} | ${'unschedule'} | ${scheduledJob} | ${JobUnscheduleMutation} | ${unscheduleMutationHandler} + ${findCancelButton} | ${'cancel'} | ${cancelableJob} | ${JobCancelMutation} | ${cancelMutationHandler} + `( + 'the mutation action $action emits the jobActionPerformed event', + async ({ button, jobType, mutationFile, handler }) => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + + createComponent(jobType, [[mutationFile, handler]]); + + button().vm.$emit('click'); + + await waitForPromises(); + + expect(eventHub.$emit).toHaveBeenCalledWith('jobActionPerformed'); + expect(redirectTo).not.toHaveBeenCalled(); + }, + ); + + it.each` + button | action | jobType | mutationFile | handler | redirectLink + ${findPlayButton} | ${'play'} | ${playableJob} | ${JobPlayMutation} | ${playMutationHandler} | ${'/root/project/-/jobs/1986'} + ${findRetryButton} | ${'retry'} | ${retryableJob} | ${JobRetryMutation} | ${retryMutationHandler} | ${'/root/project/-/jobs/1985'} + `( + 'the mutation action $action redirects to the job', + async ({ button, jobType, mutationFile, handler, redirectLink }) => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + + createComponent(jobType, [[mutationFile, handler]]); + + button().vm.$emit('click'); + + await waitForPromises(); + + expect(redirectTo).toHaveBeenCalledWith(redirectLink); + expect(eventHub.$emit).not.toHaveBeenCalled(); + }, + ); + it.each` button | action | jobType ${findPlayButton} | ${'play'} | ${playableJob} @@ -152,20 +196,17 @@ describe('Job actions cell', () => { }); it('unschedules a job', () => { - createComponent(scheduledJob, MUTATION_SUCCESS_UNSCHEDULE); + createComponent(scheduledJob, [[JobUnscheduleMutation, unscheduleMutationHandler]]); findUnscheduleButton().vm.$emit('click'); - expect(mutate).toHaveBeenCalledWith({ - mutation: JobUnscheduleMutation, - variables: { - id: scheduledJob.id, - }, + expect(unscheduleMutationHandler).toHaveBeenCalledWith({ + id: scheduledJob.id, }); }); it('shows the play job confirmation modal', async () => { - createComponent(scheduledJob, MUTATION_SUCCESS); + createComponent(scheduledJob); findPlayScheduledJobButton().vm.$emit('click'); -- cgit v1.2.3