Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /spec/frontend/jobs/components
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'spec/frontend/jobs/components')
-rw-r--r--spec/frontend/jobs/components/job_app_spec.js7
-rw-r--r--spec/frontend/jobs/components/job_log_controllers_spec.js61
-rw-r--r--spec/frontend/jobs/components/job_sidebar_details_container_spec.js4
-rw-r--r--spec/frontend/jobs/components/jobs_container_spec.js2
-rw-r--r--spec/frontend/jobs/components/log/collapsible_section_spec.js9
-rw-r--r--spec/frontend/jobs/components/log/line_spec.js42
-rw-r--r--spec/frontend/jobs/components/log/log_spec.js91
-rw-r--r--spec/frontend/jobs/components/log/mock_data.js74
-rw-r--r--spec/frontend/jobs/components/table/cells/actions_cell_spec.js41
-rw-r--r--spec/frontend/jobs/components/table/cells/job_cell_spec.js32
-rw-r--r--spec/frontend/jobs/components/table/job_table_app_spec.js43
-rw-r--r--spec/frontend/jobs/components/table/jobs_table_spec.js10
12 files changed, 176 insertions, 240 deletions
diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js
index fc308766ab9..b4b5bc4669d 100644
--- a/spec/frontend/jobs/components/job_app_spec.js
+++ b/spec/frontend/jobs/components/job_app_spec.js
@@ -22,7 +22,6 @@ describe('Job App', () => {
let store;
let wrapper;
let mock;
- let origGon;
const initSettings = {
endpoint: `${TEST_HOST}jobs/123.json`,
@@ -80,17 +79,11 @@ describe('Job App', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
store = createStore();
-
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: false } }; // NOTE: All of this passes with the feature flag
});
afterEach(() => {
wrapper.destroy();
mock.restore();
-
- window.gon = origGon;
});
describe('while loading', () => {
diff --git a/spec/frontend/jobs/components/job_log_controllers_spec.js b/spec/frontend/jobs/components/job_log_controllers_spec.js
index cd3ee734466..cc97d111c06 100644
--- a/spec/frontend/jobs/components/job_log_controllers_spec.js
+++ b/spec/frontend/jobs/components/job_log_controllers_spec.js
@@ -1,6 +1,11 @@
+import { GlSearchBoxByClick } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import JobLogControllers from '~/jobs/components/job_log_controllers.vue';
+import HelpPopover from '~/vue_shared/components/help_popover.vue';
+import { mockJobLog } from '../mock_data';
+
+const mockToastShow = jest.fn();
describe('Job log controllers', () => {
let wrapper;
@@ -19,14 +24,30 @@ describe('Job log controllers', () => {
isScrollBottomDisabled: false,
isScrollingDown: true,
isJobLogSizeVisible: true,
+ jobLog: mockJobLog,
};
- const createWrapper = (props) => {
+ const createWrapper = (props, jobLogSearch = false) => {
wrapper = mount(JobLogControllers, {
propsData: {
...defaultProps,
...props,
},
+ provide: {
+ glFeatures: {
+ jobLogSearch,
+ },
+ },
+ data() {
+ return {
+ searchTerm: '82',
+ };
+ },
+ mocks: {
+ $toast: {
+ show: mockToastShow,
+ },
+ },
});
};
@@ -35,6 +56,8 @@ describe('Job log controllers', () => {
const findRawLinkController = () => wrapper.find('[data-testid="job-raw-link-controller"]');
const findScrollTop = () => wrapper.find('[data-testid="job-controller-scroll-top"]');
const findScrollBottom = () => wrapper.find('[data-testid="job-controller-scroll-bottom"]');
+ const findJobLogSearch = () => wrapper.findComponent(GlSearchBoxByClick);
+ const findSearchHelp = () => wrapper.findComponent(HelpPopover);
describe('Truncate information', () => {
describe('with isJobLogSizeVisible', () => {
@@ -179,4 +202,40 @@ describe('Job log controllers', () => {
});
});
});
+
+ describe('Job log search', () => {
+ describe('with feature flag off', () => {
+ it('does not display job log search', () => {
+ createWrapper();
+
+ expect(findJobLogSearch().exists()).toBe(false);
+ expect(findSearchHelp().exists()).toBe(false);
+ });
+ });
+
+ describe('with feature flag on', () => {
+ beforeEach(() => {
+ createWrapper({}, { jobLogSearch: true });
+ });
+
+ it('displays job log search', () => {
+ expect(findJobLogSearch().exists()).toBe(true);
+ expect(findSearchHelp().exists()).toBe(true);
+ });
+
+ it('emits search results', () => {
+ const expectedSearchResults = [[[mockJobLog[6].lines[1], mockJobLog[6].lines[2]]]];
+
+ findJobLogSearch().vm.$emit('submit');
+
+ expect(wrapper.emitted('searchResults')).toEqual(expectedSearchResults);
+ });
+
+ it('clears search results', () => {
+ findJobLogSearch().vm.$emit('clear');
+
+ expect(wrapper.emitted('searchResults')).toEqual([[[]]]);
+ });
+ });
+ });
});
diff --git a/spec/frontend/jobs/components/job_sidebar_details_container_spec.js b/spec/frontend/jobs/components/job_sidebar_details_container_spec.js
index cc9a5e4ee25..4046f0269dd 100644
--- a/spec/frontend/jobs/components/job_sidebar_details_container_spec.js
+++ b/spec/frontend/jobs/components/job_sidebar_details_container_spec.js
@@ -42,7 +42,7 @@ describe('Job Sidebar Details Container', () => {
expect(wrapper.html()).toBe('');
});
- it.each(['duration', 'erased_at', 'finished_at', 'queued', 'runner', 'coverage'])(
+ it.each(['duration', 'erased_at', 'finished_at', 'queued_at', 'runner', 'coverage'])(
'should not render %s details when missing',
async (detail) => {
await store.dispatch('receiveJobSuccess', { [detail]: undefined });
@@ -59,7 +59,7 @@ describe('Job Sidebar Details Container', () => {
['duration', 'Elapsed time: 6 seconds'],
['erased_at', 'Erased: 3 weeks ago'],
['finished_at', 'Finished: 3 weeks ago'],
- ['queued', 'Queued: 9 seconds'],
+ ['queued_duration', 'Queued: 9 seconds'],
['runner', 'Runner: #1 (ABCDEFGH) local ci runner'],
['coverage', 'Coverage: 20%'],
])('uses %s to render job-%s', async (detail, value) => {
diff --git a/spec/frontend/jobs/components/jobs_container_spec.js b/spec/frontend/jobs/components/jobs_container_spec.js
index 1cde72682a2..127570b8184 100644
--- a/spec/frontend/jobs/components/jobs_container_spec.js
+++ b/spec/frontend/jobs/components/jobs_container_spec.js
@@ -106,7 +106,7 @@ describe('Jobs List block', () => {
});
expect(findJob().text()).toBe(job.name);
- expect(findJob().text()).not.toContain(job.id);
+ expect(findJob().text()).not.toContain(job.id.toString());
});
it('renders job id when job name is not available', () => {
diff --git a/spec/frontend/jobs/components/log/collapsible_section_spec.js b/spec/frontend/jobs/components/log/collapsible_section_spec.js
index 2ab7f5fe22d..646935568b1 100644
--- a/spec/frontend/jobs/components/log/collapsible_section_spec.js
+++ b/spec/frontend/jobs/components/log/collapsible_section_spec.js
@@ -5,7 +5,6 @@ import { collapsibleSectionClosed, collapsibleSectionOpened } from './mock_data'
describe('Job Log Collapsible Section', () => {
let wrapper;
- let origGon;
const jobLogEndpoint = 'jobs/335';
@@ -20,16 +19,8 @@ describe('Job Log Collapsible Section', () => {
});
};
- beforeEach(() => {
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: false } }; // NOTE: This also works with true
- });
-
afterEach(() => {
wrapper.destroy();
-
- window.gon = origGon;
});
describe('with closed section', () => {
diff --git a/spec/frontend/jobs/components/log/line_spec.js b/spec/frontend/jobs/components/log/line_spec.js
index d184696cd1f..bf80d90e299 100644
--- a/spec/frontend/jobs/components/log/line_spec.js
+++ b/spec/frontend/jobs/components/log/line_spec.js
@@ -179,4 +179,46 @@ describe('Job Log Line', () => {
expect(findLink().exists()).toBe(false);
});
});
+
+ describe('job log search', () => {
+ const mockSearchResults = [
+ {
+ offset: 1533,
+ content: [{ text: '$ echo "82.71"', style: 'term-fg-l-green term-bold' }],
+ section: 'step-script',
+ lineNumber: 20,
+ },
+ { offset: 1560, content: [{ text: '82.71' }], section: 'step-script', lineNumber: 21 },
+ ];
+
+ it('applies highlight class to search result elements', () => {
+ createComponent({
+ line: {
+ offset: 1560,
+ content: [{ text: '82.71' }],
+ section: 'step-script',
+ lineNumber: 21,
+ },
+ path: '/root/ci-project/-/jobs/1089',
+ searchResults: mockSearchResults,
+ });
+
+ expect(wrapper.classes()).toContain('gl-bg-gray-500');
+ });
+
+ it('does not apply highlight class to search result elements', () => {
+ createComponent({
+ line: {
+ offset: 1560,
+ content: [{ text: 'docker' }],
+ section: 'step-script',
+ lineNumber: 29,
+ },
+ path: '/root/ci-project/-/jobs/1089',
+ searchResults: mockSearchResults,
+ });
+
+ expect(wrapper.classes()).not.toContain('gl-bg-gray-500');
+ });
+ });
});
diff --git a/spec/frontend/jobs/components/log/log_spec.js b/spec/frontend/jobs/components/log/log_spec.js
index 9cc56cce9b3..c933ed5c3e1 100644
--- a/spec/frontend/jobs/components/log/log_spec.js
+++ b/spec/frontend/jobs/components/log/log_spec.js
@@ -2,7 +2,7 @@ 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';
+import { logLinesParser } from '~/jobs/store/utils';
import { jobLog } from './mock_data';
describe('Job Log', () => {
@@ -10,7 +10,6 @@ describe('Job Log', () => {
let actions;
let state;
let store;
- let origGon;
Vue.use(Vuex);
@@ -25,12 +24,8 @@ describe('Job Log', () => {
toggleCollapsibleLine: () => {},
};
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: false } };
-
state = {
- jobLog: logLinesParserLegacy(jobLog),
+ jobLog: logLinesParser(jobLog),
jobLogEndpoint: 'jobs/id',
};
@@ -44,88 +39,6 @@ describe('Job Log', () => {
afterEach(() => {
wrapper.destroy();
-
- window.gon = origGon;
- });
-
- const findCollapsibleLine = () => wrapper.find('.collapsible-line');
-
- describe('line numbers', () => {
- it('renders a line number for each open line', () => {
- expect(wrapper.find('#L1').text()).toBe('1');
- expect(wrapper.find('#L2').text()).toBe('2');
- expect(wrapper.find('#L3').text()).toBe('3');
- });
-
- it('links to the provided path and correct line number', () => {
- expect(wrapper.find('#L1').attributes('href')).toBe(`${state.jobLogEndpoint}#L1`);
- });
- });
-
- describe('collapsible sections', () => {
- it('renders a clickable header section', () => {
- expect(findCollapsibleLine().attributes('role')).toBe('button');
- });
-
- it('renders an icon with the open state', () => {
- expect(findCollapsibleLine().find('[data-testid="chevron-lg-down-icon"]').exists()).toBe(
- true,
- );
- });
-
- describe('on click header section', () => {
- it('calls toggleCollapsibleLine', () => {
- jest.spyOn(wrapper.vm, 'toggleCollapsibleLine');
-
- findCollapsibleLine().trigger('click');
-
- expect(wrapper.vm.toggleCollapsibleLine).toHaveBeenCalled();
- });
- });
- });
-});
-
-describe('Job Log, infinitelyCollapsibleSections feature flag enabled', () => {
- let wrapper;
- let actions;
- let state;
- let store;
- let origGon;
-
- Vue.use(Vuex);
-
- const createComponent = () => {
- wrapper = mount(Log, {
- store,
- });
- };
-
- beforeEach(() => {
- actions = {
- toggleCollapsibleLine: () => {},
- };
-
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: true } };
-
- state = {
- jobLog: logLinesParser(jobLog).parsedLines,
- jobLogEndpoint: 'jobs/id',
- };
-
- store = new Vuex.Store({
- actions,
- state,
- });
-
- createComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
-
- window.gon = origGon;
});
const findCollapsibleLine = () => wrapper.find('.collapsible-line');
diff --git a/spec/frontend/jobs/components/log/mock_data.js b/spec/frontend/jobs/components/log/mock_data.js
index 3ff0bd73581..eb8c4fe8bc9 100644
--- a/spec/frontend/jobs/components/log/mock_data.js
+++ b/spec/frontend/jobs/components/log/mock_data.js
@@ -58,80 +58,6 @@ export const utilsMockData = [
},
];
-export const multipleCollapsibleSectionsMockData = [
- {
- offset: 1001,
- content: [{ text: ' on docker-auto-scale-com 8a6210b8' }],
- },
- {
- offset: 1002,
- content: [
- {
- text: 'Executing "step_script" stage of the job script',
- },
- ],
- section: 'step-script',
- section_header: true,
- },
- {
- offset: 1003,
- content: [{ text: 'sleep 60' }],
- section: 'step-script',
- },
- {
- offset: 1004,
- content: [
- {
- text:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lorem dolor, congue ac condimentum vitae',
- },
- ],
- section: 'step-script',
- },
- {
- offset: 1005,
- content: [{ text: 'executing...' }],
- section: 'step-script',
- },
- {
- offset: 1006,
- content: [{ text: '1st collapsible section' }],
- section: 'collapsible-1',
- section_header: true,
- },
- {
- offset: 1007,
- content: [
- {
- text:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lorem dolor, congue ac condimentum vitae',
- },
- ],
- section: 'collapsible-1',
- },
- {
- offset: 1008,
- content: [],
- section: 'collapsible-1',
- section_duration: '01:00',
- },
- {
- offset: 1009,
- content: [],
- section: 'step-script',
- section_duration: '10:00',
- },
-];
-
-export const backwardsCompatibilityTrace = [
- {
- offset: 2365,
- content: [],
- section: 'download-artifacts',
- section_duration: '00:01',
- },
-];
-
export const originalTrace = [
{
offset: 1,
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 976b128532d..7cc008f332d 100644
--- a/spec/frontend/jobs/components/table/cells/actions_cell_spec.js
+++ b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js
@@ -12,17 +12,12 @@ import JobRetryMutation from '~/jobs/components/table/graphql/mutations/job_retr
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,
- cannotPlayScheduledJob,
- retryMutationResponse,
+ mockJobsNodes,
+ mockJobsNodesAsGuest,
playMutationResponse,
- cancelMutationResponse,
+ retryMutationResponse,
unscheduleMutationResponse,
+ cancelMutationResponse,
} from '../../../mock_data';
jest.mock('~/lib/utils/url_utility');
@@ -32,6 +27,22 @@ Vue.use(VueApollo);
describe('Job actions cell', () => {
let wrapper;
+ const findMockJob = (jobName, nodes = mockJobsNodes) => {
+ const job = nodes.find(({ name }) => name === jobName);
+ expect(job).toBeDefined(); // ensure job is present
+ return job;
+ };
+
+ const mockJob = findMockJob('build');
+ const cancelableJob = findMockJob('cancelable');
+ const playableJob = findMockJob('playable');
+ const retryableJob = findMockJob('retryable');
+ const scheduledJob = findMockJob('scheduled');
+ const jobWithArtifact = findMockJob('with_artifact');
+ const cannotPlayJob = findMockJob('playable', mockJobsNodesAsGuest);
+ const cannotRetryJob = findMockJob('retryable', mockJobsNodesAsGuest);
+ const cannotPlayScheduledJob = findMockJob('scheduled', mockJobsNodesAsGuest);
+
const findRetryButton = () => wrapper.findByTestId('retry');
const findPlayButton = () => wrapper.findByTestId('play');
const findCancelButton = () => wrapper.findByTestId('cancel-button');
@@ -55,10 +66,10 @@ describe('Job actions cell', () => {
return createMockApollo(requestHandlers);
};
- const createComponent = (jobType, requestHandlers, props = {}) => {
+ const createComponent = (job, requestHandlers, props = {}) => {
wrapper = shallowMountExtended(ActionsCell, {
propsData: {
- job: jobType,
+ job,
...props,
},
apolloProvider: createMockApolloProvider(requestHandlers),
@@ -73,15 +84,15 @@ describe('Job actions cell', () => {
});
it('displays the artifacts download button with correct link', () => {
- createComponent(playableJob);
+ createComponent(jobWithArtifact);
expect(findDownloadArtifactsButton().attributes('href')).toBe(
- playableJob.artifacts.nodes[0].downloadPath,
+ jobWithArtifact.artifacts.nodes[0].downloadPath,
);
});
it('does not display an artifacts download button', () => {
- createComponent(retryableJob);
+ createComponent(mockJob);
expect(findDownloadArtifactsButton().exists()).toBe(false);
});
@@ -101,7 +112,7 @@ describe('Job actions cell', () => {
button | action | jobType
${findPlayButton} | ${'play'} | ${playableJob}
${findRetryButton} | ${'retry'} | ${retryableJob}
- ${findDownloadArtifactsButton} | ${'download artifacts'} | ${playableJob}
+ ${findDownloadArtifactsButton} | ${'download artifacts'} | ${jobWithArtifact}
${findCancelButton} | ${'cancel'} | ${cancelableJob}
`('displays the $action button', ({ button, jobType }) => {
createComponent(jobType);
diff --git a/spec/frontend/jobs/components/table/cells/job_cell_spec.js b/spec/frontend/jobs/components/table/cells/job_cell_spec.js
index fc4e5586349..ddc196129a7 100644
--- a/spec/frontend/jobs/components/table/cells/job_cell_spec.js
+++ b/spec/frontend/jobs/components/table/cells/job_cell_spec.js
@@ -2,16 +2,22 @@ import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import JobCell from '~/jobs/components/table/cells/job_cell.vue';
-import { mockJobsInTable } from '../../../mock_data';
-
-const mockJob = mockJobsInTable[0];
-const mockJobCreatedByTag = mockJobsInTable[1];
-const mockJobLimitedAccess = mockJobsInTable[2];
-const mockStuckJob = mockJobsInTable[3];
+import { mockJobsNodes, mockJobsNodesAsGuest } from '../../../mock_data';
describe('Job Cell', () => {
let wrapper;
+ const findMockJob = (jobName, nodes = mockJobsNodes) => {
+ const job = nodes.find(({ name }) => name === jobName);
+ expect(job).toBeDefined(); // ensure job is present
+ return job;
+ };
+
+ const mockJob = findMockJob('build');
+ const jobCreatedByTag = findMockJob('created_by_tag');
+ const pendingJob = findMockJob('pending');
+ const jobAsGuest = findMockJob('build', mockJobsNodesAsGuest);
+
const findJobIdLink = () => wrapper.findByTestId('job-id-link');
const findJobIdNoLink = () => wrapper.findByTestId('job-id-limited-access');
const findJobRef = () => wrapper.findByTestId('job-ref');
@@ -23,11 +29,11 @@ describe('Job Cell', () => {
const findBadgeById = (id) => wrapper.findByTestId(id);
- const createComponent = (jobData = mockJob) => {
+ const createComponent = (job = mockJob) => {
wrapper = extendedWrapper(
shallowMount(JobCell, {
propsData: {
- job: jobData,
+ job,
},
}),
);
@@ -49,9 +55,9 @@ describe('Job Cell', () => {
});
it('display the job id with no link', () => {
- createComponent(mockJobLimitedAccess);
+ createComponent(jobAsGuest);
- const expectedJobId = `#${getIdFromGraphQLId(mockJobLimitedAccess.id)}`;
+ const expectedJobId = `#${getIdFromGraphQLId(jobAsGuest.id)}`;
expect(findJobIdNoLink().text()).toBe(expectedJobId);
expect(findJobIdNoLink().exists()).toBe(true);
@@ -75,7 +81,7 @@ describe('Job Cell', () => {
});
it('displays label icon when job is created by a tag', () => {
- createComponent(mockJobCreatedByTag);
+ createComponent(jobCreatedByTag);
expect(findLabelIcon().exists()).toBe(true);
expect(findForkIcon().exists()).toBe(false);
@@ -130,8 +136,8 @@ describe('Job Cell', () => {
expect(findStuckIcon().exists()).toBe(false);
});
- it('stuck icon is shown if job is stuck', () => {
- createComponent(mockStuckJob);
+ it('stuck icon is shown if job is pending', () => {
+ createComponent(pendingJob);
expect(findStuckIcon().exists()).toBe(true);
expect(findStuckIcon().attributes('name')).toBe('warning');
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 986fba21fb9..374768c3ee4 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -6,7 +6,7 @@ import {
GlLoadingIcon,
} from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { s__ } from '~/locale';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -18,8 +18,8 @@ import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue';
import JobsFilteredSearch from '~/jobs/components/filtered_search/jobs_filtered_search.vue';
import {
- mockJobsQueryResponse,
- mockJobsQueryEmptyResponse,
+ mockJobsResponsePaginated,
+ mockJobsResponseEmpty,
mockFailedSearchToken,
} from '../../mock_data';
@@ -30,11 +30,10 @@ jest.mock('~/flash');
describe('Job table app', () => {
let wrapper;
- let jobsTableVueSearch = true;
- const successHandler = jest.fn().mockResolvedValue(mockJobsQueryResponse);
+ const successHandler = jest.fn().mockResolvedValue(mockJobsResponsePaginated);
const failedHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
- const emptyHandler = jest.fn().mockResolvedValue(mockJobsQueryEmptyResponse);
+ const emptyHandler = jest.fn().mockResolvedValue(mockJobsResponseEmpty);
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon);
@@ -66,7 +65,6 @@ describe('Job table app', () => {
},
provide: {
fullPath: projectPath,
- glFeatures: { jobsTableVueSearch },
},
apolloProvider: createMockApolloProvider(handler),
});
@@ -77,17 +75,17 @@ describe('Job table app', () => {
});
describe('loading state', () => {
- beforeEach(() => {
+ it('should display skeleton loader when loading', () => {
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', () => {
+ createComponent();
+
findTabs().vm.$emit('fetchJobsByStatus', null);
expect(findSkeletonLoader().exists()).toBe(true);
@@ -119,24 +117,29 @@ describe('Job table app', () => {
});
describe('when infinite scrolling is triggered', () => {
- beforeEach(() => {
+ it('does not display a skeleton loader', () => {
triggerInfiniteScroll();
- });
- it('does not display a skeleton loader', () => {
expect(findSkeletonLoader().exists()).toBe(false);
});
it('handles infinite scrolling by calling fetch more', async () => {
+ triggerInfiniteScroll();
+
+ await nextTick();
+
+ const pageSize = 30;
+
expect(findLoadingSpinner().exists()).toBe(true);
await waitForPromises();
expect(findLoadingSpinner().exists()).toBe(false);
- expect(successHandler).toHaveBeenCalledWith({
- after: 'eyJpZCI6IjIzMTcifQ',
- fullPath: 'gitlab-org/gitlab',
+ expect(successHandler).toHaveBeenLastCalledWith({
+ first: pageSize,
+ fullPath: projectPath,
+ after: mockJobsResponsePaginated.data.project.jobs.pageInfo.endCursor,
});
});
});
@@ -227,13 +230,5 @@ describe('Job table app', () => {
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_spec.js b/spec/frontend/jobs/components/table/jobs_table_spec.js
index ac8bef675f8..803df3df37f 100644
--- a/spec/frontend/jobs/components/table/jobs_table_spec.js
+++ b/spec/frontend/jobs/components/table/jobs_table_spec.js
@@ -3,7 +3,7 @@ import { mount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import JobsTable from '~/jobs/components/table/jobs_table.vue';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
-import { mockJobsInTable } from '../../mock_data';
+import { mockJobsNodes } from '../../mock_data';
describe('Jobs Table', () => {
let wrapper;
@@ -19,7 +19,7 @@ describe('Jobs Table', () => {
wrapper = extendedWrapper(
mount(JobsTable, {
propsData: {
- jobs: mockJobsInTable,
+ jobs: mockJobsNodes,
...props,
},
}),
@@ -39,7 +39,7 @@ describe('Jobs Table', () => {
});
it('displays correct number of job rows', () => {
- expect(findTableRows()).toHaveLength(mockJobsInTable.length);
+ expect(findTableRows()).toHaveLength(mockJobsNodes.length);
});
it('displays job status', () => {
@@ -47,14 +47,14 @@ describe('Jobs Table', () => {
});
it('displays the job stage and name', () => {
- const firstJob = mockJobsInTable[0];
+ const firstJob = mockJobsNodes[0];
expect(findJobStage().text()).toBe(firstJob.stage.name);
expect(findJobName().text()).toBe(firstJob.name);
});
it('displays the coverage for only jobs that have coverage', () => {
- const jobsThatHaveCoverage = mockJobsInTable.filter((job) => job.coverage !== null);
+ const jobsThatHaveCoverage = mockJobsNodes.filter((job) => job.coverage !== null);
jobsThatHaveCoverage.forEach((job, index) => {
expect(findAllCoverageJobs().at(index).text()).toBe(`${job.coverage}%`);