summaryrefslogtreecommitdiff
path: root/spec/frontend/pipelines
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/pipelines')
-rw-r--r--spec/frontend/pipelines/__snapshots__/utils_spec.js.snap47
-rw-r--r--spec/frontend/pipelines/components/jobs/jobs_app_spec.js106
-rw-r--r--spec/frontend/pipelines/graph/graph_component_wrapper_spec.js44
-rw-r--r--spec/frontend/pipelines/graph/graph_view_selector_spec.js36
-rw-r--r--spec/frontend/pipelines/graph/mock_data.js81
-rw-r--r--spec/frontend/pipelines/mock_data.js141
6 files changed, 424 insertions, 31 deletions
diff --git a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
index 60625d301c0..99de0d2a3ef 100644
--- a/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
+++ b/spec/frontend/pipelines/__snapshots__/utils_spec.js.snap
@@ -6,9 +6,11 @@ Array [
"groups": Array [
Object {
"__typename": "CiGroup",
+ "id": "4",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "6",
"name": "build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl",
"needs": Array [],
"scheduledAt": null,
@@ -18,6 +20,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "8",
"path": "/root/abcd-dag/-/jobs/1482/retry",
"title": "Retry",
},
@@ -25,6 +28,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "7",
"tooltip": "passed",
},
},
@@ -36,14 +40,17 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "5",
"label": "passed",
},
},
Object {
"__typename": "CiGroup",
+ "id": "9",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "11",
"name": "build_b",
"needs": Array [],
"scheduledAt": null,
@@ -53,6 +60,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "13",
"path": "/root/abcd-dag/-/jobs/1515/retry",
"title": "Retry",
},
@@ -60,6 +68,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "12",
"tooltip": "passed",
},
},
@@ -71,14 +80,17 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "10",
"label": "passed",
},
},
Object {
"__typename": "CiGroup",
+ "id": "14",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "16",
"name": "build_c",
"needs": Array [],
"scheduledAt": null,
@@ -88,6 +100,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "18",
"path": "/root/abcd-dag/-/jobs/1484/retry",
"title": "Retry",
},
@@ -95,6 +108,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "17",
"tooltip": "passed",
},
},
@@ -106,14 +120,17 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "15",
"label": "passed",
},
},
Object {
"__typename": "CiGroup",
+ "id": "19",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "21",
"name": "build_d 1/3",
"needs": Array [],
"scheduledAt": null,
@@ -123,6 +140,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "23",
"path": "/root/abcd-dag/-/jobs/1485/retry",
"title": "Retry",
},
@@ -130,11 +148,13 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "22",
"tooltip": "passed",
},
},
Object {
"__typename": "CiJob",
+ "id": "24",
"name": "build_d 2/3",
"needs": Array [],
"scheduledAt": null,
@@ -144,6 +164,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "26",
"path": "/root/abcd-dag/-/jobs/1486/retry",
"title": "Retry",
},
@@ -151,11 +172,13 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "25",
"tooltip": "passed",
},
},
Object {
"__typename": "CiJob",
+ "id": "27",
"name": "build_d 3/3",
"needs": Array [],
"scheduledAt": null,
@@ -165,6 +188,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "29",
"path": "/root/abcd-dag/-/jobs/1487/retry",
"title": "Retry",
},
@@ -172,6 +196,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "28",
"tooltip": "passed",
},
},
@@ -183,14 +208,17 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "20",
"label": "passed",
},
},
Object {
"__typename": "CiGroup",
+ "id": "57",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "59",
"name": "test_c",
"needs": Array [],
"scheduledAt": null,
@@ -201,6 +229,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "60",
"tooltip": null,
},
},
@@ -212,6 +241,7 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "58",
"label": null,
},
},
@@ -226,9 +256,11 @@ Array [
"groups": Array [
Object {
"__typename": "CiGroup",
+ "id": "32",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "34",
"name": "test_a",
"needs": Array [
"build_c",
@@ -242,6 +274,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "36",
"path": "/root/abcd-dag/-/jobs/1514/retry",
"title": "Retry",
},
@@ -249,6 +282,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "35",
"tooltip": "passed",
},
},
@@ -260,14 +294,17 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "33",
"label": "passed",
},
},
Object {
"__typename": "CiGroup",
+ "id": "40",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "42",
"name": "test_b 1/2",
"needs": Array [
"build_d 3/3",
@@ -283,6 +320,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "44",
"path": "/root/abcd-dag/-/jobs/1489/retry",
"title": "Retry",
},
@@ -290,11 +328,13 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "43",
"tooltip": "passed",
},
},
Object {
"__typename": "CiJob",
+ "id": "67",
"name": "test_b 2/2",
"needs": Array [
"build_d 3/3",
@@ -310,6 +350,7 @@ Array [
"__typename": "StatusAction",
"buttonTitle": "Retry this job",
"icon": "retry",
+ "id": "51",
"path": "/root/abcd-dag/-/jobs/1490/retry",
"title": "Retry",
},
@@ -317,6 +358,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "50",
"tooltip": "passed",
},
},
@@ -328,14 +370,17 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "41",
"label": "passed",
},
},
Object {
"__typename": "CiGroup",
+ "id": "61",
"jobs": Array [
Object {
"__typename": "CiJob",
+ "id": "53",
"name": "test_d",
"needs": Array [
"build_b",
@@ -348,6 +393,7 @@ Array [
"group": "success",
"hasDetails": true,
"icon": "status_success",
+ "id": "64",
"tooltip": null,
},
},
@@ -359,6 +405,7 @@ Array [
"__typename": "DetailedStatus",
"group": "success",
"icon": "status_success",
+ "id": "62",
"label": null,
},
},
diff --git a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
new file mode 100644
index 00000000000..1ea6096c922
--- /dev/null
+++ b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
@@ -0,0 +1,106 @@
+import { GlIntersectionObserver, GlSkeletonLoader } from '@gitlab/ui';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
+import JobsApp from '~/pipelines/components/jobs/jobs_app.vue';
+import JobsTable from '~/jobs/components/table/jobs_table.vue';
+import getPipelineJobsQuery from '~/pipelines/graphql/queries/get_pipeline_jobs.query.graphql';
+import { mockPipelineJobsQueryResponse } from '../../mock_data';
+
+const localVue = createLocalVue();
+localVue.use(VueApollo);
+
+jest.mock('~/flash');
+
+describe('Jobs app', () => {
+ let wrapper;
+ let resolverSpy;
+
+ const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
+ const findJobsTable = () => wrapper.findComponent(JobsTable);
+
+ const triggerInfiniteScroll = () =>
+ wrapper.findComponent(GlIntersectionObserver).vm.$emit('appear');
+
+ const createMockApolloProvider = (resolver) => {
+ const requestHandlers = [[getPipelineJobsQuery, resolver]];
+
+ return createMockApollo(requestHandlers);
+ };
+
+ const createComponent = (resolver) => {
+ wrapper = shallowMount(JobsApp, {
+ provide: {
+ fullPath: 'root/ci-project',
+ pipelineIid: 1,
+ },
+ localVue,
+ apolloProvider: createMockApolloProvider(resolver),
+ });
+ };
+
+ beforeEach(() => {
+ resolverSpy = jest.fn().mockResolvedValue(mockPipelineJobsQueryResponse);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('displays the loading state', () => {
+ createComponent(resolverSpy);
+
+ expect(findSkeletonLoader().exists()).toBe(true);
+ expect(findJobsTable().exists()).toBe(false);
+ });
+
+ it('displays the jobs table', async () => {
+ createComponent(resolverSpy);
+
+ await waitForPromises();
+
+ expect(findJobsTable().exists()).toBe(true);
+ expect(findSkeletonLoader().exists()).toBe(false);
+ expect(createFlash).not.toHaveBeenCalled();
+ });
+
+ it('handles job fetch error correctly', async () => {
+ resolverSpy = jest.fn().mockRejectedValue(new Error('GraphQL error'));
+
+ createComponent(resolverSpy);
+
+ await waitForPromises();
+
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'An error occured while fetching the pipelines jobs.',
+ });
+ });
+
+ it('handles infinite scrolling by calling fetchMore', async () => {
+ createComponent(resolverSpy);
+
+ await waitForPromises();
+
+ triggerInfiniteScroll();
+
+ expect(resolverSpy).toHaveBeenCalledWith({
+ after: 'eyJpZCI6Ijg0NyJ9',
+ fullPath: 'root/ci-project',
+ iid: 1,
+ });
+ });
+
+ it('does not display main loading state again after fetchMore', async () => {
+ createComponent(resolverSpy);
+
+ expect(findSkeletonLoader().exists()).toBe(true);
+
+ await waitForPromises();
+
+ triggerInfiniteScroll();
+
+ expect(findSkeletonLoader().exists()).toBe(false);
+ });
+});
diff --git a/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js b/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js
index db4de6deeb7..04e004dc6c1 100644
--- a/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js
+++ b/spec/frontend/pipelines/graph/graph_component_wrapper_spec.js
@@ -1,7 +1,7 @@
-import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
+import { GlAlert, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -98,7 +98,6 @@ describe('Pipeline graph wrapper', () => {
afterEach(() => {
wrapper.destroy();
- wrapper = null;
});
beforeAll(() => {
@@ -136,7 +135,7 @@ describe('Pipeline graph wrapper', () => {
beforeEach(async () => {
createComponentWithApollo();
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('does not display the loading icon', () => {
@@ -165,7 +164,7 @@ describe('Pipeline graph wrapper', () => {
getPipelineDetailsHandler: jest.fn().mockRejectedValue(new Error('GraphQL error')),
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('does not display the loading icon', () => {
@@ -189,7 +188,7 @@ describe('Pipeline graph wrapper', () => {
},
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('does not display the loading icon', () => {
@@ -211,7 +210,7 @@ describe('Pipeline graph wrapper', () => {
createComponentWithApollo();
jest.spyOn(wrapper.vm.$apollo.queries.headerPipeline, 'refetch');
jest.spyOn(wrapper.vm.$apollo.queries.pipeline, 'refetch');
- await wrapper.vm.$nextTick();
+ await nextTick();
getGraph().vm.$emit('refreshPipelineGraph');
});
@@ -225,8 +224,8 @@ describe('Pipeline graph wrapper', () => {
describe('when query times out', () => {
const advanceApolloTimers = async () => {
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
- await wrapper.vm.$nextTick();
+ await nextTick();
+ await nextTick();
};
beforeEach(async () => {
@@ -246,7 +245,7 @@ describe('Pipeline graph wrapper', () => {
.mockResolvedValueOnce(errorData);
createComponentWithApollo({ getPipelineDetailsHandler: failSucceedFail });
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows correct errors and does not overwrite populated data when data is empty', async () => {
@@ -276,7 +275,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('appears when pipeline uses needs', () => {
@@ -319,7 +318,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('sets showLinks to true', async () => {
@@ -329,7 +328,7 @@ describe('Pipeline graph wrapper', () => {
expect(getViewSelector().props('type')).toBe(LAYER_VIEW);
await getDependenciesToggle().vm.$emit('change', true);
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(wrapper.findComponent(LinksLayer).props('showLinks')).toBe(true);
});
});
@@ -345,7 +344,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('shows the hover tip in the view selector', async () => {
@@ -366,7 +365,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('does not show the hover tip', async () => {
@@ -384,7 +383,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
afterEach(() => {
@@ -393,9 +392,10 @@ describe('Pipeline graph wrapper', () => {
it('reads the view type from localStorage when available', () => {
const viewSelectorNeedsSegment = wrapper
- .findAll('[data-testid="pipeline-view-selector"] > label')
+ .find(GlButtonGroup)
+ .findAllComponents(GlButton)
.at(1);
- expect(viewSelectorNeedsSegment.classes()).toContain('active');
+ expect(viewSelectorNeedsSegment.classes()).toContain('selected');
});
});
@@ -412,7 +412,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
afterEach(() => {
@@ -435,7 +435,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('does not appear when pipeline does not use needs', () => {
@@ -462,7 +462,7 @@ describe('Pipeline graph wrapper', () => {
beforeEach(async () => {
createComponentWithApollo();
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('is not called', () => {
@@ -506,7 +506,7 @@ describe('Pipeline graph wrapper', () => {
});
jest.runOnlyPendingTimers();
- await wrapper.vm.$nextTick();
+ await nextTick();
});
it('attempts to collect metrics', () => {
diff --git a/spec/frontend/pipelines/graph/graph_view_selector_spec.js b/spec/frontend/pipelines/graph/graph_view_selector_spec.js
index f4faa25545b..f574f4dccc5 100644
--- a/spec/frontend/pipelines/graph/graph_view_selector_spec.js
+++ b/spec/frontend/pipelines/graph/graph_view_selector_spec.js
@@ -1,4 +1,4 @@
-import { GlAlert, GlLoadingIcon, GlSegmentedControl } from '@gitlab/ui';
+import { GlAlert, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import { LAYER_VIEW, STAGE_VIEW } from '~/pipelines/components/graph/constants';
import GraphViewSelector from '~/pipelines/components/graph/graph_view_selector.vue';
@@ -7,9 +7,9 @@ describe('the graph view selector component', () => {
let wrapper;
const findDependenciesToggle = () => wrapper.find('[data-testid="show-links-toggle"]');
- const findViewTypeSelector = () => wrapper.findComponent(GlSegmentedControl);
- const findStageViewLabel = () => findViewTypeSelector().findAll('label').at(0);
- const findLayersViewLabel = () => findViewTypeSelector().findAll('label').at(1);
+ const findViewTypeSelector = () => wrapper.findComponent(GlButtonGroup);
+ const findStageViewButton = () => findViewTypeSelector().findAllComponents(GlButton).at(0);
+ const findLayerViewButton = () => findViewTypeSelector().findAllComponents(GlButton).at(1);
const findSwitcherLoader = () => wrapper.find('[data-testid="switcher-loading-state"]');
const findToggleLoader = () => findDependenciesToggle().find(GlLoadingIcon);
const findHoverTip = () => wrapper.findComponent(GlAlert);
@@ -51,8 +51,13 @@ describe('the graph view selector component', () => {
createComponent({ mountFn: mount });
});
- it('shows the Stage view label as active in the selector', () => {
- expect(findStageViewLabel().classes()).toContain('active');
+ it('shows the Stage view button as selected', () => {
+ expect(findStageViewButton().classes('selected')).toBe(true);
+ });
+
+ it('shows the Job dependencies view button not selected', () => {
+ expect(findLayerViewButton().exists()).toBe(true);
+ expect(findLayerViewButton().classes('selected')).toBe(false);
});
it('does not show the Job dependencies (links) toggle', () => {
@@ -70,8 +75,13 @@ describe('the graph view selector component', () => {
});
});
- it('shows the Job dependencies view label as active in the selector', () => {
- expect(findLayersViewLabel().classes()).toContain('active');
+ it('shows the Job dependencies view as selected', () => {
+ expect(findLayerViewButton().classes('selected')).toBe(true);
+ });
+
+ it('shows the Stage button as not selected', () => {
+ expect(findStageViewButton().exists()).toBe(true);
+ expect(findStageViewButton().classes('selected')).toBe(false);
});
it('shows the Job dependencies (links) toggle', () => {
@@ -94,7 +104,7 @@ describe('the graph view selector component', () => {
expect(wrapper.emitted().updateViewType).toBeUndefined();
expect(findSwitcherLoader().exists()).toBe(false);
- await findStageViewLabel().trigger('click');
+ await findStageViewButton().trigger('click');
/*
Loading happens before the event is emitted or timers are run.
Then we run the timer because the event is emitted in setInterval
@@ -123,6 +133,14 @@ describe('the graph view selector component', () => {
expect(wrapper.emitted().updateShowLinksState).toHaveLength(1);
expect(wrapper.emitted().updateShowLinksState).toEqual([[true]]);
});
+
+ it('does not emit an event if the click occurs on the currently selected view button', async () => {
+ expect(wrapper.emitted().updateShowLinksState).toBeUndefined();
+
+ await findLayerViewButton().trigger('click');
+
+ expect(wrapper.emitted().updateShowLinksState).toBeUndefined();
+ });
});
describe('hover tip callout', () => {
diff --git a/spec/frontend/pipelines/graph/mock_data.js b/spec/frontend/pipelines/graph/mock_data.js
index 3812483766d..dcbbde7bf36 100644
--- a/spec/frontend/pipelines/graph/mock_data.js
+++ b/spec/frontend/pipelines/graph/mock_data.js
@@ -4,6 +4,7 @@ export const mockPipelineResponse = {
data: {
project: {
__typename: 'Project',
+ id: '1',
pipeline: {
__typename: 'Pipeline',
id: 163,
@@ -21,9 +22,11 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiStage',
+ id: '2',
name: 'build',
status: {
__typename: 'DetailedStatus',
+ id: '3',
action: null,
},
groups: {
@@ -31,10 +34,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiGroup',
+ id: '4',
name: 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
size: 1,
status: {
__typename: 'DetailedStatus',
+ id: '5',
label: 'passed',
group: 'success',
icon: 'status_success',
@@ -44,10 +49,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '6',
name: 'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '7',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -55,6 +62,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '8',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1482/retry',
@@ -72,9 +80,11 @@ export const mockPipelineResponse = {
{
__typename: 'CiGroup',
name: 'build_b',
+ id: '9',
size: 1,
status: {
__typename: 'DetailedStatus',
+ id: '10',
label: 'passed',
group: 'success',
icon: 'status_success',
@@ -84,10 +94,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '11',
name: 'build_b',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '12',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -95,6 +107,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '13',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1515/retry',
@@ -111,10 +124,12 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiGroup',
+ id: '14',
name: 'build_c',
size: 1,
status: {
__typename: 'DetailedStatus',
+ id: '15',
label: 'passed',
group: 'success',
icon: 'status_success',
@@ -124,10 +139,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '16',
name: 'build_c',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '17',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -135,6 +152,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '18',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1484/retry',
@@ -151,10 +169,12 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiGroup',
+ id: '19',
name: 'build_d',
size: 3,
status: {
__typename: 'DetailedStatus',
+ id: '20',
label: 'passed',
group: 'success',
icon: 'status_success',
@@ -164,10 +184,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '21',
name: 'build_d 1/3',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '22',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -175,6 +197,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '23',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1485/retry',
@@ -188,10 +211,12 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiJob',
+ id: '24',
name: 'build_d 2/3',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '25',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -199,6 +224,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '26',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1486/retry',
@@ -212,10 +238,12 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiJob',
+ id: '27',
name: 'build_d 3/3',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '28',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -223,6 +251,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '29',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1487/retry',
@@ -242,9 +271,11 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiStage',
+ id: '30',
name: 'test',
status: {
__typename: 'DetailedStatus',
+ id: '31',
action: null,
},
groups: {
@@ -252,10 +283,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiGroup',
+ id: '32',
name: 'test_a',
size: 1,
status: {
__typename: 'DetailedStatus',
+ id: '33',
label: 'passed',
group: 'success',
icon: 'status_success',
@@ -265,10 +298,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '34',
name: 'test_a',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '35',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -276,6 +311,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '36',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1514/retry',
@@ -287,14 +323,17 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiBuildNeed',
+ id: '37',
name: 'build_c',
},
{
__typename: 'CiBuildNeed',
+ id: '38',
name: 'build_b',
},
{
__typename: 'CiBuildNeed',
+ id: '39',
name:
'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
},
@@ -306,10 +345,12 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiGroup',
+ id: '40',
name: 'test_b',
size: 2,
status: {
__typename: 'DetailedStatus',
+ id: '41',
label: 'passed',
group: 'success',
icon: 'status_success',
@@ -319,10 +360,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '42',
name: 'test_b 1/2',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '43',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -330,6 +373,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '44',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1489/retry',
@@ -341,22 +385,27 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiBuildNeed',
+ id: '45',
name: 'build_d 3/3',
},
{
__typename: 'CiBuildNeed',
+ id: '46',
name: 'build_d 2/3',
},
{
__typename: 'CiBuildNeed',
+ id: '47',
name: 'build_d 1/3',
},
{
__typename: 'CiBuildNeed',
+ id: '48',
name: 'build_b',
},
{
__typename: 'CiBuildNeed',
+ id: '49',
name:
'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
},
@@ -365,10 +414,12 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiJob',
+ id: '67',
name: 'test_b 2/2',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '50',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -376,6 +427,7 @@ export const mockPipelineResponse = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '51',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/abcd-dag/-/jobs/1490/retry',
@@ -387,22 +439,27 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiBuildNeed',
+ id: '52',
name: 'build_d 3/3',
},
{
__typename: 'CiBuildNeed',
+ id: '53',
name: 'build_d 2/3',
},
{
__typename: 'CiBuildNeed',
+ id: '54',
name: 'build_d 1/3',
},
{
__typename: 'CiBuildNeed',
+ id: '55',
name: 'build_b',
},
{
__typename: 'CiBuildNeed',
+ id: '56',
name:
'build_a_nlfjkdnlvskfnksvjknlfdjvlvnjdkjdf_nvjkenjkrlngjeknjkl',
},
@@ -415,9 +472,11 @@ export const mockPipelineResponse = {
{
__typename: 'CiGroup',
name: 'test_c',
+ id: '57',
size: 1,
status: {
__typename: 'DetailedStatus',
+ id: '58',
label: null,
group: 'success',
icon: 'status_success',
@@ -427,10 +486,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '59',
name: 'test_c',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '60',
icon: 'status_success',
tooltip: null,
hasDetails: true,
@@ -448,9 +509,11 @@ export const mockPipelineResponse = {
},
{
__typename: 'CiGroup',
+ id: '61',
name: 'test_d',
size: 1,
status: {
+ id: '62',
__typename: 'DetailedStatus',
label: null,
group: 'success',
@@ -461,10 +524,12 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiJob',
+ id: '53',
name: 'test_d',
scheduledAt: null,
status: {
__typename: 'DetailedStatus',
+ id: '64',
icon: 'status_success',
tooltip: null,
hasDetails: true,
@@ -477,6 +542,7 @@ export const mockPipelineResponse = {
nodes: [
{
__typename: 'CiBuildNeed',
+ id: '65',
name: 'build_b',
},
],
@@ -502,6 +568,7 @@ export const downstream = {
iid: '31',
path: '/root/elemenohpee/-/pipelines/175',
status: {
+ id: '70',
group: 'success',
label: 'passed',
icon: 'status_success',
@@ -509,6 +576,7 @@ export const downstream = {
},
sourceJob: {
name: 'test_c',
+ id: '71',
__typename: 'CiJob',
},
project: {
@@ -525,12 +593,14 @@ export const downstream = {
iid: '27',
path: '/root/abcd-dag/-/pipelines/181',
status: {
+ id: '72',
group: 'success',
label: 'passed',
icon: 'status_success',
__typename: 'DetailedStatus',
},
sourceJob: {
+ id: '73',
name: 'test_d',
__typename: 'CiJob',
},
@@ -551,6 +621,7 @@ export const upstream = {
iid: '24',
path: '/root/abcd-dag/-/pipelines/161',
status: {
+ id: '74',
group: 'success',
label: 'passed',
icon: 'status_success',
@@ -571,6 +642,7 @@ export const wrappedPipelineReturn = {
data: {
project: {
__typename: 'Project',
+ id: '75',
pipeline: {
__typename: 'Pipeline',
id: 'gid://gitlab/Ci::Pipeline/175',
@@ -592,12 +664,14 @@ export const wrappedPipelineReturn = {
__typename: 'Pipeline',
status: {
__typename: 'DetailedStatus',
+ id: '77',
group: 'success',
label: 'passed',
icon: 'status_success',
},
sourceJob: {
name: 'test_c',
+ id: '78',
__typename: 'CiJob',
},
project: {
@@ -613,8 +687,10 @@ export const wrappedPipelineReturn = {
{
name: 'build',
__typename: 'CiStage',
+ id: '79',
status: {
action: null,
+ id: '80',
__typename: 'DetailedStatus',
},
groups: {
@@ -622,8 +698,10 @@ export const wrappedPipelineReturn = {
nodes: [
{
__typename: 'CiGroup',
+ id: '81',
status: {
__typename: 'DetailedStatus',
+ id: '82',
label: 'passed',
group: 'success',
icon: 'status_success',
@@ -635,6 +713,7 @@ export const wrappedPipelineReturn = {
nodes: [
{
__typename: 'CiJob',
+ id: '83',
name: 'build_n',
scheduledAt: null,
needs: {
@@ -643,6 +722,7 @@ export const wrappedPipelineReturn = {
},
status: {
__typename: 'DetailedStatus',
+ id: '84',
icon: 'status_success',
tooltip: 'passed',
hasDetails: true,
@@ -650,6 +730,7 @@ export const wrappedPipelineReturn = {
group: 'success',
action: {
__typename: 'StatusAction',
+ id: '85',
buttonTitle: 'Retry this job',
icon: 'retry',
path: '/root/elemenohpee/-/jobs/1662/retry',
diff --git a/spec/frontend/pipelines/mock_data.js b/spec/frontend/pipelines/mock_data.js
index fdc78d48901..b9d20eb7ca5 100644
--- a/spec/frontend/pipelines/mock_data.js
+++ b/spec/frontend/pipelines/mock_data.js
@@ -14,6 +14,7 @@ export const mockPipelineHeader = {
},
createdAt: threeWeeksAgo.toISOString(),
user: {
+ id: 'user-1',
name: 'Foo',
username: 'foobar',
email: 'foo@bar.com',
@@ -27,6 +28,7 @@ export const mockFailedPipelineHeader = {
retryable: true,
cancelable: false,
detailedStatus: {
+ id: 'status-1',
group: 'failed',
icon: 'status_failed',
label: 'failed',
@@ -43,6 +45,7 @@ export const mockFailedPipelineNoPermissions = {
},
createdAt: threeWeeksAgo.toISOString(),
user: {
+ id: 'user-1',
name: 'Foo',
username: 'foobar',
email: 'foo@bar.com',
@@ -52,6 +55,7 @@ export const mockFailedPipelineNoPermissions = {
retryable: true,
cancelable: false,
detailedStatus: {
+ id: 'status-1',
group: 'running',
icon: 'status_running',
label: 'running',
@@ -66,6 +70,7 @@ export const mockRunningPipelineHeader = {
retryable: false,
cancelable: true,
detailedStatus: {
+ id: 'status-1',
group: 'running',
icon: 'status_running',
label: 'running',
@@ -82,6 +87,7 @@ export const mockRunningPipelineNoPermissions = {
},
createdAt: threeWeeksAgo.toISOString(),
user: {
+ id: 'user-1',
name: 'Foo',
username: 'foobar',
email: 'foo@bar.com',
@@ -91,6 +97,7 @@ export const mockRunningPipelineNoPermissions = {
retryable: false,
cancelable: true,
detailedStatus: {
+ id: 'status-1',
group: 'running',
icon: 'status_running',
label: 'running',
@@ -105,6 +112,7 @@ export const mockCancelledPipelineHeader = {
retryable: true,
cancelable: false,
detailedStatus: {
+ id: 'status-1',
group: 'cancelled',
icon: 'status_cancelled',
label: 'cancelled',
@@ -119,6 +127,7 @@ export const mockSuccessfulPipelineHeader = {
retryable: false,
cancelable: false,
detailedStatus: {
+ id: 'status-1',
group: 'success',
icon: 'status_success',
label: 'success',
@@ -130,13 +139,16 @@ export const mockSuccessfulPipelineHeader = {
export const mockRunningPipelineHeaderData = {
data: {
project: {
+ id: '1',
pipeline: {
...mockRunningPipelineHeader,
iid: '28',
user: {
+ id: 'user-1',
name: 'Foo',
username: 'foobar',
webPath: '/foo',
+ webUrl: '/foo',
email: 'foo@bar.com',
avatarUrl: 'link',
status: null,
@@ -493,3 +505,132 @@ export const mockSearch = [
export const mockBranchesAfterMap = ['branch-1', 'branch-10', 'branch-11'];
export const mockTagsAfterMap = ['tag-3', 'tag-2', 'tag-1', 'main-tag'];
+
+export const mockPipelineJobsQueryResponse = {
+ data: {
+ project: {
+ id: 'gid://gitlab/Project/20',
+ __typename: 'Project',
+ pipeline: {
+ id: 'gid://gitlab/Ci::Pipeline/224',
+ __typename: 'Pipeline',
+ jobs: {
+ __typename: 'CiJobConnection',
+ pageInfo: {
+ endCursor: 'eyJpZCI6Ijg0NyJ9',
+ hasNextPage: true,
+ hasPreviousPage: false,
+ startCursor: 'eyJpZCI6IjYyMCJ9',
+ __typename: 'PageInfo',
+ },
+ nodes: [
+ {
+ artifacts: {
+ nodes: [
+ {
+ downloadPath: '/root/ci-project/-/jobs/620/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ allowFailure: false,
+ status: 'SUCCESS',
+ scheduledAt: null,
+ manualJob: false,
+ triggered: null,
+ createdByTag: false,
+ detailedStatus: {
+ id: 'success-620-620',
+ detailsPath: '/root/ci-project/-/jobs/620',
+ group: 'success',
+ icon: 'status_success',
+ label: 'passed',
+ text: 'passed',
+ tooltip: 'passed (retried)',
+ action: null,
+ __typename: 'DetailedStatus',
+ },
+ id: 'gid://gitlab/Ci::Build/620',
+ refName: 'main',
+ refPath: '/root/ci-project/-/commits/main',
+ tags: [],
+ shortSha: '5acce24b',
+ commitPath: '/root/ci-project/-/commit/5acce24b3737d4f0d649ad0a26ae1903a2b35f5e',
+ stage: { id: 'gid://gitlab/Ci::Stage/148', name: 'test', __typename: 'CiStage' },
+ name: 'coverage_job',
+ duration: 4,
+ finishedAt: '2021-12-06T14:13:49Z',
+ coverage: 82.71,
+ retryable: false,
+ playable: false,
+ cancelable: false,
+ active: false,
+ stuck: false,
+ userPermissions: {
+ readBuild: true,
+ readJobArtifacts: true,
+ updateBuild: true,
+ __typename: 'JobPermissions',
+ },
+ __typename: 'CiJob',
+ },
+ {
+ artifacts: {
+ nodes: [
+ {
+ downloadPath: '/root/ci-project/-/jobs/619/artifacts/download?file_type=trace',
+ fileType: 'TRACE',
+ __typename: 'CiJobArtifact',
+ },
+ ],
+ __typename: 'CiJobArtifactConnection',
+ },
+ allowFailure: false,
+ status: 'SUCCESS',
+ scheduledAt: null,
+ manualJob: false,
+ triggered: null,
+ createdByTag: false,
+ detailedStatus: {
+ id: 'success-619-619',
+ detailsPath: '/root/ci-project/-/jobs/619',
+ group: 'success',
+ icon: 'status_success',
+ label: 'passed',
+ text: 'passed',
+ tooltip: 'passed (retried)',
+ action: null,
+ __typename: 'DetailedStatus',
+ },
+ id: 'gid://gitlab/Ci::Build/619',
+ refName: 'main',
+ refPath: '/root/ci-project/-/commits/main',
+ tags: [],
+ shortSha: '5acce24b',
+ commitPath: '/root/ci-project/-/commit/5acce24b3737d4f0d649ad0a26ae1903a2b35f5e',
+ stage: { id: 'gid://gitlab/Ci::Stage/148', name: 'test', __typename: 'CiStage' },
+ name: 'test_job_two',
+ duration: 4,
+ finishedAt: '2021-12-06T14:13:44Z',
+ coverage: null,
+ retryable: false,
+ playable: false,
+ cancelable: false,
+ active: false,
+ stuck: false,
+ userPermissions: {
+ readBuild: true,
+ readJobArtifacts: true,
+ updateBuild: true,
+ __typename: 'JobPermissions',
+ },
+ __typename: 'CiJob',
+ },
+ ],
+ },
+ },
+ },
+ },
+};