diff options
Diffstat (limited to 'spec/frontend/jobs')
9 files changed, 351 insertions, 110 deletions
diff --git a/spec/frontend/jobs/components/filtered_search/jobs_filtered_search_spec.js b/spec/frontend/jobs/components/filtered_search/jobs_filtered_search_spec.js new file mode 100644 index 00000000000..322cfa3ba1f --- /dev/null +++ b/spec/frontend/jobs/components/filtered_search/jobs_filtered_search_spec.js @@ -0,0 +1,49 @@ +import { GlFilteredSearch } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants'; +import JobsFilteredSearch from '~/jobs/components/filtered_search/jobs_filtered_search.vue'; +import { mockFailedSearchToken } from '../../mock_data'; + +describe('Jobs filtered search', () => { + let wrapper; + + const findFilteredSearch = () => wrapper.findComponent(GlFilteredSearch); + const getSearchToken = (type) => + findFilteredSearch() + .props('availableTokens') + .find((token) => token.type === type); + + const findStatusToken = () => getSearchToken('status'); + + const createComponent = () => { + wrapper = shallowMount(JobsFilteredSearch); + }; + + beforeEach(() => { + createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('displays filtered search', () => { + expect(findFilteredSearch().exists()).toBe(true); + }); + + it('displays status token', () => { + expect(findStatusToken()).toMatchObject({ + type: 'status', + icon: 'status', + title: 'Status', + unique: true, + operators: OPERATOR_IS_ONLY, + }); + }); + + it('emits filter token to parent component', () => { + findFilteredSearch().vm.$emit('submit', mockFailedSearchToken); + + expect(wrapper.emitted('filterJobsBySearch')).toEqual([[mockFailedSearchToken]]); + }); +}); 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 new file mode 100644 index 00000000000..ce8e482cc16 --- /dev/null +++ b/spec/frontend/jobs/components/filtered_search/tokens/job_status_token_spec.js @@ -0,0 +1,57 @@ +import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlIcon } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import { stubComponent } from 'helpers/stub_component'; +import JobStatusToken from '~/jobs/components/filtered_search/tokens/job_status_token.vue'; + +describe('Job Status Token', () => { + let wrapper; + + const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken); + const findAllFilteredSearchSuggestions = () => + wrapper.findAllComponents(GlFilteredSearchSuggestion); + const findAllGlIcons = () => wrapper.findAllComponents(GlIcon); + + const defaultProps = { + config: { + type: 'status', + icon: 'status', + title: 'Status', + unique: true, + }, + value: { + data: '', + }, + }; + + const createComponent = () => { + wrapper = shallowMount(JobStatusToken, { + propsData: { + ...defaultProps, + }, + stubs: { + GlFilteredSearchToken: stubComponent(GlFilteredSearchToken, { + template: `<div><slot name="suggestions"></slot></div>`, + }), + }, + }); + }; + + beforeEach(() => { + createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('passes config correctly', () => { + expect(findFilteredSearchToken().props('config')).toEqual(defaultProps.config); + }); + + it('renders all job statuses available', () => { + const expectedLength = 11; + + expect(findAllFilteredSearchSuggestions()).toHaveLength(expectedLength); + expect(findAllGlIcons()).toHaveLength(expectedLength); + }); +}); diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js index 06ebcd7f134..9abe66b4696 100644 --- a/spec/frontend/jobs/components/job_app_spec.js +++ b/spec/frontend/jobs/components/job_app_spec.js @@ -375,8 +375,8 @@ describe('Job App', () => { }); describe('sidebar', () => { - it('has no blank blocks', (done) => { - setupAndMount({ + it('has no blank blocks', async () => { + await setupAndMount({ jobData: { duration: null, finished_at: null, @@ -387,17 +387,14 @@ describe('Job App', () => { tags: [], cancel_path: null, }, - }) - .then(() => { - const blocks = wrapper.findAll('.blocks-container > *').wrappers; - expect(blocks.length).toBeGreaterThan(0); - - blocks.forEach((block) => { - expect(block.text().trim()).not.toBe(''); - }); - }) - .then(done) - .catch(done.fail); + }); + + const blocks = wrapper.findAll('.blocks-container > *').wrappers; + expect(blocks.length).toBeGreaterThan(0); + + blocks.forEach((block) => { + expect(block.text().trim()).not.toBe(''); + }); }); }); }); diff --git a/spec/frontend/jobs/components/table/graphql/cache_config_spec.js b/spec/frontend/jobs/components/table/graphql/cache_config_spec.js index ac79186cb46..88c97285b85 100644 --- a/spec/frontend/jobs/components/table/graphql/cache_config_spec.js +++ b/spec/frontend/jobs/components/table/graphql/cache_config_spec.js @@ -33,6 +33,26 @@ describe('jobs/components/table/graphql/cache_config', () => { ); }); + it('should not add to existing cache if the incoming elements are the same', () => { + // simulate that this is the last page + const finalExistingCache = { + ...CIJobConnectionExistingCache, + pageInfo: { + hasNextPage: false, + }, + }; + + const res = cacheConfig.typePolicies.CiJobConnection.merge( + CIJobConnectionExistingCache, + finalExistingCache, + { + args: firstLoadArgs, + }, + ); + + expect(res.nodes).toHaveLength(CIJobConnectionExistingCache.nodes.length); + }); + it('should contain the pageInfo key as part of the result', () => { const res = cacheConfig.typePolicies.CiJobConnection.merge({}, CIJobConnectionIncomingCache, { args: firstLoadArgs, 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 4d51624dfff..986fba21fb9 100644 --- a/spec/frontend/jobs/components/table/job_table_app_spec.js +++ b/spec/frontend/jobs/components/table/job_table_app_spec.js @@ -1,30 +1,48 @@ -import { GlSkeletonLoader, GlAlert, GlEmptyState, GlIntersectionObserver } from '@gitlab/ui'; +import { + GlSkeletonLoader, + GlAlert, + GlEmptyState, + GlIntersectionObserver, + GlLoadingIcon, +} from '@gitlab/ui'; import { mount, shallowMount } from '@vue/test-utils'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; +import { s__ } from '~/locale'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; +import createFlash from '~/flash'; import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query.graphql'; 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 JobsFilteredSearch from '~/jobs/components/filtered_search/jobs_filtered_search.vue'; +import { + mockJobsQueryResponse, + mockJobsQueryEmptyResponse, + mockFailedSearchToken, +} from '../../mock_data'; const projectPath = 'gitlab-org/gitlab'; Vue.use(VueApollo); +jest.mock('~/flash'); + describe('Job table app', () => { let wrapper; + let jobsTableVueSearch = true; const successHandler = jest.fn().mockResolvedValue(mockJobsQueryResponse); const failedHandler = jest.fn().mockRejectedValue(new Error('GraphQL error')); const emptyHandler = jest.fn().mockResolvedValue(mockJobsQueryEmptyResponse); const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader); + const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon); const findTable = () => wrapper.findComponent(JobsTable); const findTabs = () => wrapper.findComponent(JobsTableTabs); const findAlert = () => wrapper.findComponent(GlAlert); const findEmptyState = () => wrapper.findComponent(GlEmptyState); + const findFilteredSearch = () => wrapper.findComponent(JobsFilteredSearch); const triggerInfiniteScroll = () => wrapper.findComponent(GlIntersectionObserver).vm.$emit('appear'); @@ -48,6 +66,7 @@ describe('Job table app', () => { }, provide: { fullPath: projectPath, + glFeatures: { jobsTableVueSearch }, }, apolloProvider: createMockApolloProvider(handler), }); @@ -58,11 +77,21 @@ describe('Job table app', () => { }); describe('loading state', () => { - it('should display skeleton loader when loading', () => { + beforeEach(() => { createComponent(); + }); + it('should display skeleton loader when loading', () => { expect(findSkeletonLoader().exists()).toBe(true); expect(findTable().exists()).toBe(false); + expect(findLoadingSpinner().exists()).toBe(false); + }); + + it('when switching tabs only the skeleton loader should show', () => { + findTabs().vm.$emit('fetchJobsByStatus', null); + + expect(findSkeletonLoader().exists()).toBe(true); + expect(findLoadingSpinner().exists()).toBe(false); }); }); @@ -76,6 +105,7 @@ describe('Job table app', () => { it('should display the jobs table with data', () => { expect(findTable().exists()).toBe(true); expect(findSkeletonLoader().exists()).toBe(false); + expect(findLoadingSpinner().exists()).toBe(false); }); it('should refetch jobs query on fetchJobsByStatus event', async () => { @@ -98,8 +128,12 @@ describe('Job table app', () => { }); it('handles infinite scrolling by calling fetch more', async () => { + expect(findLoadingSpinner().exists()).toBe(true); + await waitForPromises(); + expect(findLoadingSpinner().exists()).toBe(false); + expect(successHandler).toHaveBeenCalledWith({ after: 'eyJpZCI6IjIzMTcifQ', fullPath: 'gitlab-org/gitlab', @@ -137,4 +171,69 @@ describe('Job table app', () => { expect(findTable().exists()).toBe(true); }); }); + + describe('filtered search', () => { + it('should display filtered search', () => { + createComponent(); + + expect(findFilteredSearch().exists()).toBe(true); + }); + + // this test should be updated once BE supports tab and filtered search filtering + // https://gitlab.com/gitlab-org/gitlab/-/issues/356210 + it.each` + scope | shouldDisplay + ${null} | ${true} + ${['FAILED', 'SUCCESS', 'CANCELED']} | ${false} + `( + 'with tab scope $scope the filtered search displays $shouldDisplay', + async ({ scope, shouldDisplay }) => { + createComponent(); + + await waitForPromises(); + + await findTabs().vm.$emit('fetchJobsByStatus', scope); + + expect(findFilteredSearch().exists()).toBe(shouldDisplay); + }, + ); + + it('refetches jobs query when filtering', async () => { + createComponent(); + + jest.spyOn(wrapper.vm.$apollo.queries.jobs, 'refetch').mockImplementation(jest.fn()); + + expect(wrapper.vm.$apollo.queries.jobs.refetch).toHaveBeenCalledTimes(0); + + await findFilteredSearch().vm.$emit('filterJobsBySearch', [mockFailedSearchToken]); + + expect(wrapper.vm.$apollo.queries.jobs.refetch).toHaveBeenCalledTimes(1); + }); + + it('shows raw text warning when user inputs raw text', async () => { + const expectedWarning = { + message: s__( + 'Jobs|Raw text search is not currently supported for the jobs filtered search feature. Please use the available search tokens.', + ), + type: 'warning', + }; + + createComponent(); + + jest.spyOn(wrapper.vm.$apollo.queries.jobs, 'refetch').mockImplementation(jest.fn()); + + await findFilteredSearch().vm.$emit('filterJobsBySearch', ['raw text']); + + expect(createFlash).toHaveBeenCalledWith(expectedWarning); + expect(wrapper.vm.$apollo.queries.jobs.refetch).toHaveBeenCalledTimes(0); + }); + + it('should not display filtered search', () => { + jobsTableVueSearch = false; + + createComponent(); + + expect(findFilteredSearch().exists()).toBe(false); + }); + }); }); diff --git a/spec/frontend/jobs/components/table/jobs_table_tabs_spec.js b/spec/frontend/jobs/components/table/jobs_table_tabs_spec.js index ac9b45be932..23632001060 100644 --- a/spec/frontend/jobs/components/table/jobs_table_tabs_spec.js +++ b/spec/frontend/jobs/components/table/jobs_table_tabs_spec.js @@ -1,3 +1,4 @@ +import { GlTab } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import { trimText } from 'helpers/text_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; @@ -7,16 +8,31 @@ describe('Jobs Table Tabs', () => { let wrapper; const defaultProps = { - jobCounts: { all: 848, pending: 0, running: 0, finished: 704 }, + allJobsCount: 286, + loading: false, }; - const findTab = (testId) => wrapper.findByTestId(testId); + const statuses = { + success: 'SUCCESS', + failed: 'FAILED', + canceled: 'CANCELED', + }; + + const findAllTab = () => wrapper.findByTestId('jobs-all-tab'); + const findFinishedTab = () => wrapper.findByTestId('jobs-finished-tab'); + + const triggerTabChange = (index) => wrapper.findAllComponents(GlTab).at(index).vm.$emit('click'); - const createComponent = () => { + const createComponent = (props = defaultProps) => { wrapper = extendedWrapper( mount(JobsTableTabs, { provide: { - ...defaultProps, + jobStatuses: { + ...statuses, + }, + }, + propsData: { + ...props, }, }), ); @@ -30,13 +46,21 @@ describe('Jobs Table Tabs', () => { wrapper.destroy(); }); + it('displays All tab with count', () => { + expect(trimText(findAllTab().text())).toBe(`All ${defaultProps.allJobsCount}`); + }); + + it('displays Finished tab with no count', () => { + expect(findFinishedTab().text()).toBe('Finished'); + }); + it.each` - tabId | text | count - ${'jobs-all-tab'} | ${'All'} | ${defaultProps.jobCounts.all} - ${'jobs-pending-tab'} | ${'Pending'} | ${defaultProps.jobCounts.pending} - ${'jobs-running-tab'} | ${'Running'} | ${defaultProps.jobCounts.running} - ${'jobs-finished-tab'} | ${'Finished'} | ${defaultProps.jobCounts.finished} - `('displays the right tab text and badge count', ({ tabId, text, count }) => { - expect(trimText(findTab(tabId).text())).toBe(`${text} ${count}`); + tabIndex | expectedScope + ${0} | ${null} + ${1} | ${[statuses.success, statuses.failed, statuses.canceled]} + `('emits fetchJobsByStatus with $expectedScope on tab change', ({ tabIndex, expectedScope }) => { + triggerTabChange(tabIndex); + + expect(wrapper.emitted()).toEqual({ fetchJobsByStatus: [[expectedScope]] }); }); }); diff --git a/spec/frontend/jobs/components/trigger_block_spec.js b/spec/frontend/jobs/components/trigger_block_spec.js index e0eb873dc2f..78596612d23 100644 --- a/spec/frontend/jobs/components/trigger_block_spec.js +++ b/spec/frontend/jobs/components/trigger_block_spec.js @@ -1,12 +1,12 @@ -import { GlButton, GlTable } from '@gitlab/ui'; +import { GlButton, GlTableLite } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import TriggerBlock from '~/jobs/components/trigger_block.vue'; describe('Trigger block', () => { let wrapper; - const findRevealButton = () => wrapper.find(GlButton); - const findVariableTable = () => wrapper.find(GlTable); + const findRevealButton = () => wrapper.findComponent(GlButton); + const findVariableTable = () => wrapper.findComponent(GlTableLite); const findShortToken = () => wrapper.find('[data-testid="trigger-short-token"]'); const findVariableValue = (index) => wrapper.findAll('[data-testid="trigger-build-value"]').at(index); @@ -22,7 +22,6 @@ describe('Trigger block', () => { afterEach(() => { wrapper.destroy(); - wrapper = null; }); describe('with short token and no variables', () => { diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js index 73b9df1853d..27b6c04eded 100644 --- a/spec/frontend/jobs/mock_data.js +++ b/spec/frontend/jobs/mock_data.js @@ -1481,6 +1481,7 @@ export const mockJobsQueryResponse = { project: { id: '1', jobs: { + count: 1, pageInfo: { endCursor: 'eyJpZCI6IjIzMTcifQ', hasNextPage: true, @@ -1911,10 +1912,19 @@ export const CIJobConnectionIncomingCacheRunningStatus = { }; export const CIJobConnectionExistingCache = { + pageInfo: { + __typename: 'PageInfo', + endCursor: 'eyJpZCI6IjIwNTEifQ', + hasNextPage: true, + hasPreviousPage: false, + startCursor: 'eyJpZCI6IjIxNzMifQ', + }, nodes: [ - { __ref: 'CiJob:gid://gitlab/Ci::Build/2057' }, - { __ref: 'CiJob:gid://gitlab/Ci::Build/2056' }, - { __ref: 'CiJob:gid://gitlab/Ci::Build/2051' }, + { __ref: 'CiJob:gid://gitlab/Ci::Build/2100' }, + { __ref: 'CiJob:gid://gitlab/Ci::Build/2101' }, + { __ref: 'CiJob:gid://gitlab/Ci::Build/2102' }, ], statuses: 'PENDING', }; + +export const mockFailedSearchToken = { type: 'status', value: { data: 'FAILED', operator: '=' } }; diff --git a/spec/frontend/jobs/store/actions_spec.js b/spec/frontend/jobs/store/actions_spec.js index 16448d6a3ca..b9f97a3c3ae 100644 --- a/spec/frontend/jobs/store/actions_spec.js +++ b/spec/frontend/jobs/store/actions_spec.js @@ -39,62 +39,60 @@ describe('Job State actions', () => { }); describe('setJobEndpoint', () => { - it('should commit SET_JOB_ENDPOINT mutation', (done) => { - testAction( + it('should commit SET_JOB_ENDPOINT mutation', () => { + return testAction( setJobEndpoint, 'job/872324.json', mockedState, [{ type: types.SET_JOB_ENDPOINT, payload: 'job/872324.json' }], [], - done, ); }); }); describe('setJobLogOptions', () => { - it('should commit SET_JOB_LOG_OPTIONS mutation', (done) => { - testAction( + it('should commit SET_JOB_LOG_OPTIONS mutation', () => { + return testAction( setJobLogOptions, { pagePath: 'job/872324/trace.json' }, mockedState, [{ type: types.SET_JOB_LOG_OPTIONS, payload: { pagePath: 'job/872324/trace.json' } }], [], - done, ); }); }); describe('hideSidebar', () => { - it('should commit HIDE_SIDEBAR mutation', (done) => { - testAction(hideSidebar, null, mockedState, [{ type: types.HIDE_SIDEBAR }], [], done); + it('should commit HIDE_SIDEBAR mutation', () => { + return testAction(hideSidebar, null, mockedState, [{ type: types.HIDE_SIDEBAR }], []); }); }); describe('showSidebar', () => { - it('should commit HIDE_SIDEBAR mutation', (done) => { - testAction(showSidebar, null, mockedState, [{ type: types.SHOW_SIDEBAR }], [], done); + it('should commit SHOW_SIDEBAR mutation', () => { + return testAction(showSidebar, null, mockedState, [{ type: types.SHOW_SIDEBAR }], []); }); }); describe('toggleSidebar', () => { describe('when isSidebarOpen is true', () => { - it('should dispatch hideSidebar', (done) => { - testAction(toggleSidebar, null, mockedState, [], [{ type: 'hideSidebar' }], done); + it('should dispatch hideSidebar', () => { + return testAction(toggleSidebar, null, mockedState, [], [{ type: 'hideSidebar' }]); }); }); describe('when isSidebarOpen is false', () => { - it('should dispatch showSidebar', (done) => { + it('should dispatch showSidebar', () => { mockedState.isSidebarOpen = false; - testAction(toggleSidebar, null, mockedState, [], [{ type: 'showSidebar' }], done); + return testAction(toggleSidebar, null, mockedState, [], [{ type: 'showSidebar' }]); }); }); }); describe('requestJob', () => { - it('should commit REQUEST_JOB mutation', (done) => { - testAction(requestJob, null, mockedState, [{ type: types.REQUEST_JOB }], [], done); + it('should commit REQUEST_JOB mutation', () => { + return testAction(requestJob, null, mockedState, [{ type: types.REQUEST_JOB }], []); }); }); @@ -113,10 +111,10 @@ describe('Job State actions', () => { }); describe('success', () => { - it('dispatches requestJob and receiveJobSuccess ', (done) => { + it('dispatches requestJob and receiveJobSuccess ', () => { mock.onGet(`${TEST_HOST}/endpoint.json`).replyOnce(200, { id: 121212, name: 'karma' }); - testAction( + return testAction( fetchJob, null, mockedState, @@ -130,7 +128,6 @@ describe('Job State actions', () => { type: 'receiveJobSuccess', }, ], - done, ); }); }); @@ -140,8 +137,8 @@ describe('Job State actions', () => { mock.onGet(`${TEST_HOST}/endpoint.json`).reply(500); }); - it('dispatches requestJob and receiveJobError ', (done) => { - testAction( + it('dispatches requestJob and receiveJobError ', () => { + return testAction( fetchJob, null, mockedState, @@ -154,46 +151,50 @@ describe('Job State actions', () => { type: 'receiveJobError', }, ], - done, ); }); }); }); describe('receiveJobSuccess', () => { - it('should commit RECEIVE_JOB_SUCCESS mutation', (done) => { - testAction( + it('should commit RECEIVE_JOB_SUCCESS mutation', () => { + return testAction( receiveJobSuccess, { id: 121232132 }, mockedState, [{ type: types.RECEIVE_JOB_SUCCESS, payload: { id: 121232132 } }], [], - done, ); }); }); describe('receiveJobError', () => { - it('should commit RECEIVE_JOB_ERROR mutation', (done) => { - testAction(receiveJobError, null, mockedState, [{ type: types.RECEIVE_JOB_ERROR }], [], done); + it('should commit RECEIVE_JOB_ERROR mutation', () => { + return testAction( + receiveJobError, + null, + mockedState, + [{ type: types.RECEIVE_JOB_ERROR }], + [], + ); }); }); describe('scrollTop', () => { - it('should dispatch toggleScrollButtons action', (done) => { - testAction(scrollTop, null, mockedState, [], [{ type: 'toggleScrollButtons' }], done); + it('should dispatch toggleScrollButtons action', () => { + return testAction(scrollTop, null, mockedState, [], [{ type: 'toggleScrollButtons' }]); }); }); describe('scrollBottom', () => { - it('should dispatch toggleScrollButtons action', (done) => { - testAction(scrollBottom, null, mockedState, [], [{ type: 'toggleScrollButtons' }], done); + it('should dispatch toggleScrollButtons action', () => { + return testAction(scrollBottom, null, mockedState, [], [{ type: 'toggleScrollButtons' }]); }); }); describe('requestJobLog', () => { - it('should commit REQUEST_JOB_LOG mutation', (done) => { - testAction(requestJobLog, null, mockedState, [{ type: types.REQUEST_JOB_LOG }], [], done); + it('should commit REQUEST_JOB_LOG mutation', () => { + return testAction(requestJobLog, null, mockedState, [{ type: types.REQUEST_JOB_LOG }], []); }); }); @@ -212,13 +213,13 @@ describe('Job State actions', () => { }); describe('success', () => { - it('dispatches requestJobLog, receiveJobLogSuccess and stopPollingJobLog when job is complete', (done) => { + it('dispatches requestJobLog, receiveJobLogSuccess and stopPollingJobLog when job is complete', () => { mock.onGet(`${TEST_HOST}/endpoint/trace.json`).replyOnce(200, { html: 'I, [2018-08-17T22:57:45.707325 #1841] INFO -- :', complete: true, }); - testAction( + return testAction( fetchJobLog, null, mockedState, @@ -239,7 +240,6 @@ describe('Job State actions', () => { type: 'stopPollingJobLog', }, ], - done, ); }); @@ -255,8 +255,8 @@ describe('Job State actions', () => { mock.onGet(`${TEST_HOST}/endpoint/trace.json`).replyOnce(200, jobLogPayload); }); - it('dispatches startPollingJobLog', (done) => { - testAction( + it('dispatches startPollingJobLog', () => { + return testAction( fetchJobLog, null, mockedState, @@ -266,14 +266,13 @@ describe('Job State actions', () => { { type: 'receiveJobLogSuccess', payload: jobLogPayload }, { type: 'startPollingJobLog' }, ], - done, ); }); - it('does not dispatch startPollingJobLog when timeout is non-empty', (done) => { + it('does not dispatch startPollingJobLog when timeout is non-empty', () => { mockedState.jobLogTimeout = 1; - testAction( + return testAction( fetchJobLog, null, mockedState, @@ -282,7 +281,6 @@ describe('Job State actions', () => { { type: 'toggleScrollisInBottom', payload: true }, { type: 'receiveJobLogSuccess', payload: jobLogPayload }, ], - done, ); }); }); @@ -293,8 +291,8 @@ describe('Job State actions', () => { mock.onGet(`${TEST_HOST}/endpoint/trace.json`).reply(500); }); - it('dispatches requestJobLog and receiveJobLogError ', (done) => { - testAction( + it('dispatches requestJobLog and receiveJobLogError ', () => { + return testAction( fetchJobLog, null, mockedState, @@ -304,7 +302,6 @@ describe('Job State actions', () => { type: 'receiveJobLogError', }, ], - done, ); }); }); @@ -358,65 +355,58 @@ describe('Job State actions', () => { window.clearTimeout = origTimeout; }); - it('should commit STOP_POLLING_JOB_LOG mutation ', (done) => { + it('should commit STOP_POLLING_JOB_LOG mutation ', async () => { const jobLogTimeout = 7; - testAction( + await testAction( stopPollingJobLog, null, { ...mockedState, jobLogTimeout }, [{ type: types.SET_JOB_LOG_TIMEOUT, payload: 0 }, { type: types.STOP_POLLING_JOB_LOG }], [], - ) - .then(() => { - expect(window.clearTimeout).toHaveBeenCalledWith(jobLogTimeout); - }) - .then(done) - .catch(done.fail); + ); + expect(window.clearTimeout).toHaveBeenCalledWith(jobLogTimeout); }); }); describe('receiveJobLogSuccess', () => { - it('should commit RECEIVE_JOB_LOG_SUCCESS mutation ', (done) => { - testAction( + it('should commit RECEIVE_JOB_LOG_SUCCESS mutation ', () => { + return testAction( receiveJobLogSuccess, 'hello world', mockedState, [{ type: types.RECEIVE_JOB_LOG_SUCCESS, payload: 'hello world' }], [], - done, ); }); }); describe('receiveJobLogError', () => { - it('should commit stop polling job log', (done) => { - testAction(receiveJobLogError, null, mockedState, [], [{ type: 'stopPollingJobLog' }], done); + it('should commit stop polling job log', () => { + return testAction(receiveJobLogError, null, mockedState, [], [{ type: 'stopPollingJobLog' }]); }); }); describe('toggleCollapsibleLine', () => { - it('should commit TOGGLE_COLLAPSIBLE_LINE mutation ', (done) => { - testAction( + it('should commit TOGGLE_COLLAPSIBLE_LINE mutation ', () => { + return testAction( toggleCollapsibleLine, { isClosed: true }, mockedState, [{ type: types.TOGGLE_COLLAPSIBLE_LINE, payload: { isClosed: true } }], [], - done, ); }); }); describe('requestJobsForStage', () => { - it('should commit REQUEST_JOBS_FOR_STAGE mutation ', (done) => { - testAction( + it('should commit REQUEST_JOBS_FOR_STAGE mutation ', () => { + return testAction( requestJobsForStage, { name: 'deploy' }, mockedState, [{ type: types.REQUEST_JOBS_FOR_STAGE, payload: { name: 'deploy' } }], [], - done, ); }); }); @@ -433,12 +423,12 @@ describe('Job State actions', () => { }); describe('success', () => { - it('dispatches requestJobsForStage and receiveJobsForStageSuccess ', (done) => { + it('dispatches requestJobsForStage and receiveJobsForStageSuccess ', () => { mock .onGet(`${TEST_HOST}/jobs.json`) .replyOnce(200, { latest_statuses: [{ id: 121212, name: 'build' }], retried: [] }); - testAction( + return testAction( fetchJobsForStage, { dropdown_path: `${TEST_HOST}/jobs.json` }, mockedState, @@ -453,7 +443,6 @@ describe('Job State actions', () => { type: 'receiveJobsForStageSuccess', }, ], - done, ); }); }); @@ -463,8 +452,8 @@ describe('Job State actions', () => { mock.onGet(`${TEST_HOST}/jobs.json`).reply(500); }); - it('dispatches requestJobsForStage and receiveJobsForStageError', (done) => { - testAction( + it('dispatches requestJobsForStage and receiveJobsForStageError', () => { + return testAction( fetchJobsForStage, { dropdown_path: `${TEST_HOST}/jobs.json` }, mockedState, @@ -478,34 +467,31 @@ describe('Job State actions', () => { type: 'receiveJobsForStageError', }, ], - done, ); }); }); }); describe('receiveJobsForStageSuccess', () => { - it('should commit RECEIVE_JOBS_FOR_STAGE_SUCCESS mutation ', (done) => { - testAction( + it('should commit RECEIVE_JOBS_FOR_STAGE_SUCCESS mutation ', () => { + return testAction( receiveJobsForStageSuccess, [{ id: 121212, name: 'karma' }], mockedState, [{ type: types.RECEIVE_JOBS_FOR_STAGE_SUCCESS, payload: [{ id: 121212, name: 'karma' }] }], [], - done, ); }); }); describe('receiveJobsForStageError', () => { - it('should commit RECEIVE_JOBS_FOR_STAGE_ERROR mutation ', (done) => { - testAction( + it('should commit RECEIVE_JOBS_FOR_STAGE_ERROR mutation ', () => { + return testAction( receiveJobsForStageError, null, mockedState, [{ type: types.RECEIVE_JOBS_FOR_STAGE_ERROR }], [], - done, ); }); }); |