diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 10:33:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-05-19 10:33:21 +0300 |
commit | 36a59d088eca61b834191dacea009677a96c052f (patch) | |
tree | e4f33972dab5d8ef79e3944a9f403035fceea43f /spec/frontend/jobs | |
parent | a1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff) |
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'spec/frontend/jobs')
6 files changed, 163 insertions, 45 deletions
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,24 +110,59 @@ 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} ${findRetryButton} | ${'retry'} | ${retryableJob} @@ -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'); diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js index 27b6c04eded..4676635cce0 100644 --- a/spec/frontend/jobs/mock_data.js +++ b/spec/frontend/jobs/mock_data.js @@ -1928,3 +1928,75 @@ export const CIJobConnectionExistingCache = { }; export const mockFailedSearchToken = { type: 'status', value: { data: 'FAILED', operator: '=' } }; + +export const retryMutationResponse = { + data: { + jobRetry: { + job: { + __typename: 'CiJob', + id: '"gid://gitlab/Ci::Build/1985"', + detailedStatus: { + detailsPath: '/root/project/-/jobs/1985', + id: 'pending-1985-1985', + __typename: 'DetailedStatus', + }, + }, + errors: [], + __typename: 'JobRetryPayload', + }, + }, +}; + +export const playMutationResponse = { + data: { + jobPlay: { + job: { + __typename: 'CiJob', + id: '"gid://gitlab/Ci::Build/1986"', + detailedStatus: { + detailsPath: '/root/project/-/jobs/1986', + id: 'pending-1986-1986', + __typename: 'DetailedStatus', + }, + }, + errors: [], + __typename: 'JobRetryPayload', + }, + }, +}; + +export const cancelMutationResponse = { + data: { + jobCancel: { + job: { + __typename: 'CiJob', + id: '"gid://gitlab/Ci::Build/1987"', + detailedStatus: { + detailsPath: '/root/project/-/jobs/1987', + id: 'pending-1987-1987', + __typename: 'DetailedStatus', + }, + }, + errors: [], + __typename: 'JobRetryPayload', + }, + }, +}; + +export const unscheduleMutationResponse = { + data: { + jobUnschedule: { + job: { + __typename: 'CiJob', + id: '"gid://gitlab/Ci::Build/1988"', + detailedStatus: { + detailsPath: '/root/project/-/jobs/1988', + id: 'pending-1988-1988', + __typename: 'DetailedStatus', + }, + }, + errors: [], + __typename: 'JobRetryPayload', + }, + }, +}; diff --git a/spec/frontend/jobs/store/getters_spec.js b/spec/frontend/jobs/store/getters_spec.js index f26c0cf00fd..c13b051c672 100644 --- a/spec/frontend/jobs/store/getters_spec.js +++ b/spec/frontend/jobs/store/getters_spec.js @@ -10,16 +10,18 @@ describe('Job Store Getters', () => { describe('headerTime', () => { describe('when the job has started key', () => { - it('returns started key', () => { + it('returns started_at value', () => { const started = '2018-08-31T16:20:49.023Z'; + const startedAt = '2018-08-31T16:20:49.023Z'; + localState.job.started_at = startedAt; localState.job.started = started; - expect(getters.headerTime(localState)).toEqual(started); + expect(getters.headerTime(localState)).toEqual(startedAt); }); }); describe('when the job does not have started key', () => { - it('returns created_at key', () => { + it('returns created_at value', () => { const created = '2018-08-31T16:20:49.023Z'; localState.job.created_at = created; @@ -58,7 +60,7 @@ describe('Job Store Getters', () => { describe('shouldRenderTriggeredLabel', () => { describe('when started equals null', () => { it('returns false', () => { - localState.job.started = null; + localState.job.started_at = null; expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(false); }); @@ -66,7 +68,7 @@ describe('Job Store Getters', () => { describe('when started equals string', () => { it('returns true', () => { - localState.job.started = '2018-08-31T16:20:49.023Z'; + localState.job.started_at = '2018-08-31T16:20:49.023Z'; expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(true); }); @@ -206,7 +208,7 @@ describe('Job Store Getters', () => { }); }); - describe('hasRunnersForProject', () => { + describe('hasOfflineRunnersForProject', () => { describe('with available and offline runners', () => { it('returns true', () => { localState.job.runners = { @@ -214,7 +216,7 @@ describe('Job Store Getters', () => { online: false, }; - expect(getters.hasRunnersForProject(localState)).toEqual(true); + expect(getters.hasOfflineRunnersForProject(localState)).toEqual(true); }); }); @@ -225,7 +227,7 @@ describe('Job Store Getters', () => { online: false, }; - expect(getters.hasRunnersForProject(localState)).toEqual(false); + expect(getters.hasOfflineRunnersForProject(localState)).toEqual(false); }); }); @@ -236,7 +238,7 @@ describe('Job Store Getters', () => { online: true, }; - expect(getters.hasRunnersForProject(localState)).toEqual(false); + expect(getters.hasOfflineRunnersForProject(localState)).toEqual(false); }); }); }); |