summaryrefslogtreecommitdiff
path: root/spec/frontend/pipelines/graph/graph_component_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/pipelines/graph/graph_component_spec.js')
-rw-r--r--spec/frontend/pipelines/graph/graph_component_spec.js312
1 files changed, 45 insertions, 267 deletions
diff --git a/spec/frontend/pipelines/graph/graph_component_spec.js b/spec/frontend/pipelines/graph/graph_component_spec.js
index 5a17be1af23..7572dd83798 100644
--- a/spec/frontend/pipelines/graph/graph_component_spec.js
+++ b/spec/frontend/pipelines/graph/graph_component_spec.js
@@ -1,305 +1,83 @@
-import Vue from 'vue';
-import { mount } from '@vue/test-utils';
-import { setHTMLFixture } from 'helpers/fixtures';
-import PipelineStore from '~/pipelines/stores/pipeline_store';
-import graphComponent from '~/pipelines/components/graph/graph_component.vue';
+import { mount, shallowMount } from '@vue/test-utils';
+import PipelineGraph from '~/pipelines/components/graph/graph_component.vue';
import StageColumnComponent from '~/pipelines/components/graph/stage_column_component.vue';
-import linkedPipelinesColumn from '~/pipelines/components/graph/linked_pipelines_column.vue';
-import graphJSON from './mock_data';
-import linkedPipelineJSON from './linked_pipelines_mock_data';
-import PipelinesMediator from '~/pipelines/pipeline_details_mediator';
+import LinkedPipelinesColumn from '~/pipelines/components/graph/linked_pipelines_column.vue';
+import { GRAPHQL } from '~/pipelines/components/graph/constants';
+import {
+ generateResponse,
+ mockPipelineResponse,
+ pipelineWithUpstreamDownstream,
+} from './mock_data';
describe('graph component', () => {
- let store;
- let mediator;
let wrapper;
- const findExpandPipelineBtn = () => wrapper.find('[data-testid="expandPipelineButton"]');
- const findAllExpandPipelineBtns = () => wrapper.findAll('[data-testid="expandPipelineButton"]');
+ const findLinkedColumns = () => wrapper.findAll(LinkedPipelinesColumn);
const findStageColumns = () => wrapper.findAll(StageColumnComponent);
- const findStageColumnAt = i => findStageColumns().at(i);
- beforeEach(() => {
- mediator = new PipelinesMediator({ endpoint: '' });
- store = new PipelineStore();
- store.storePipeline(linkedPipelineJSON);
-
- setHTMLFixture('<div class="layout-page"></div>');
- });
+ const defaultProps = {
+ pipeline: generateResponse(mockPipelineResponse, 'root/fungi-xoxo'),
+ };
+
+ const createComponent = ({ mountFn = shallowMount, props = {} } = {}) => {
+ wrapper = mountFn(PipelineGraph, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ provide: {
+ dataMethod: GRAPHQL,
+ },
+ });
+ };
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
- describe('while is loading', () => {
- it('should render a loading icon', () => {
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: true,
- pipeline: {},
- mediator,
- },
- });
-
- expect(wrapper.find('.gl-spinner').exists()).toBe(true);
- });
- });
-
describe('with data', () => {
beforeEach(() => {
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: false,
- pipeline: graphJSON,
- mediator,
- },
- });
+ createComponent({ mountFn: mount });
});
- it('renders the graph', () => {
- expect(wrapper.find('.js-pipeline-graph').exists()).toBe(true);
- expect(wrapper.find('.loading-icon').exists()).toBe(false);
- expect(wrapper.find('.stage-column-list').exists()).toBe(true);
- });
-
- it('renders columns in the graph', () => {
- expect(findStageColumns()).toHaveLength(graphJSON.details.stages.length);
- });
- });
-
- describe('when linked pipelines are present', () => {
- beforeEach(() => {
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: false,
- pipeline: store.state.pipeline,
- mediator,
- },
- });
- });
-
- describe('rendered output', () => {
- it('should include the pipelines graph', () => {
- expect(wrapper.find('.js-pipeline-graph').exists()).toBe(true);
- });
-
- it('should not include the loading icon', () => {
- expect(wrapper.find('.fa-spinner').exists()).toBe(false);
- });
-
- it('should include the stage column', () => {
- expect(findStageColumnAt(0).exists()).toBe(true);
- });
-
- it('stage column should have no-margin, gl-mr-26, has-only-one-job classes if there is only one job', () => {
- expect(findStageColumnAt(0).classes()).toEqual(
- expect.arrayContaining(['no-margin', 'gl-mr-26', 'has-only-one-job']),
- );
- });
-
- it('should include the left-margin class on the second child', () => {
- expect(findStageColumnAt(1).classes('left-margin')).toBe(true);
- });
-
- it('should include the left-connector class in the build of the second child', () => {
- expect(
- findStageColumnAt(1)
- .find('.build:nth-child(1)')
- .classes('left-connector'),
- ).toBe(true);
- });
-
- it('should include the js-has-linked-pipelines flag', () => {
- expect(wrapper.find('.js-has-linked-pipelines').exists()).toBe(true);
- });
- });
-
- describe('computeds and methods', () => {
- describe('capitalizeStageName', () => {
- it('it capitalizes the stage name', () => {
- expect(
- wrapper
- .findAll('.stage-column .stage-name')
- .at(1)
- .text(),
- ).toBe('Prebuild');
- });
- });
-
- describe('stageConnectorClass', () => {
- it('it returns left-margin when there is a triggerer', () => {
- expect(findStageColumnAt(1).classes('left-margin')).toBe(true);
- });
- });
+ it('renders the main columns in the graph', () => {
+ expect(findStageColumns()).toHaveLength(defaultProps.pipeline.stages.length);
});
- describe('linked pipelines components', () => {
+ describe('when column requests a refresh', () => {
beforeEach(() => {
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: false,
- pipeline: store.state.pipeline,
- mediator,
- },
- });
+ findStageColumns()
+ .at(0)
+ .vm.$emit('refreshPipelineGraph');
});
- it('should render an upstream pipelines column at first position', () => {
- expect(wrapper.find(linkedPipelinesColumn).exists()).toBe(true);
- expect(wrapper.find('.stage-column .stage-name').text()).toBe('Upstream');
- });
-
- it('should render a downstream pipelines column at last position', () => {
- const stageColumnNames = wrapper.findAll('.stage-column .stage-name');
-
- expect(wrapper.find(linkedPipelinesColumn).exists()).toBe(true);
- expect(stageColumnNames.at(stageColumnNames.length - 1).text()).toBe('Downstream');
- });
-
- describe('triggered by', () => {
- describe('on click', () => {
- it('should emit `onClickUpstreamPipeline` when triggered by linked pipeline is clicked', () => {
- const btnWrapper = findExpandPipelineBtn();
-
- btnWrapper.trigger('click');
-
- btnWrapper.vm.$nextTick(() => {
- expect(wrapper.emitted().onClickUpstreamPipeline).toEqual([
- store.state.pipeline.triggered_by,
- ]);
- });
- });
- });
-
- describe('with expanded pipeline', () => {
- it('should render expanded pipeline', done => {
- // expand the pipeline
- store.state.pipeline.triggered_by[0].isExpanded = true;
-
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: false,
- pipeline: store.state.pipeline,
- mediator,
- },
- });
-
- Vue.nextTick()
- .then(() => {
- expect(wrapper.find('.js-upstream-pipeline-12').exists()).toBe(true);
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('triggered', () => {
- describe('on click', () => {
- it('should emit `onClickTriggered`', () => {
- // We have to mock this method since we do both style change and
- // emit and event, not mocking returns an error.
- wrapper.setMethods({
- handleClickedDownstream: jest.fn(() =>
- wrapper.vm.$emit('onClickTriggered', ...store.state.pipeline.triggered),
- ),
- });
-
- const btnWrappers = findAllExpandPipelineBtns();
- const downstreamBtnWrapper = btnWrappers.at(btnWrappers.length - 1);
-
- downstreamBtnWrapper.trigger('click');
-
- downstreamBtnWrapper.vm.$nextTick(() => {
- expect(wrapper.emitted().onClickTriggered).toEqual([store.state.pipeline.triggered]);
- });
- });
- });
-
- describe('with expanded pipeline', () => {
- it('should render expanded pipeline', done => {
- // expand the pipeline
- store.state.pipeline.triggered[0].isExpanded = true;
-
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: false,
- pipeline: store.state.pipeline,
- mediator,
- },
- });
-
- Vue.nextTick()
- .then(() => {
- expect(wrapper.find('.js-downstream-pipeline-34993051')).not.toBeNull();
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('when column requests a refresh', () => {
- beforeEach(() => {
- findStageColumnAt(0).vm.$emit('refreshPipelineGraph');
- });
-
- it('refreshPipelineGraph is emitted', () => {
- expect(wrapper.emitted().refreshPipelineGraph).toHaveLength(1);
- });
- });
+ it('refreshPipelineGraph is emitted', () => {
+ expect(wrapper.emitted().refreshPipelineGraph).toHaveLength(1);
});
});
});
describe('when linked pipelines are not present', () => {
beforeEach(() => {
- const pipeline = Object.assign(linkedPipelineJSON, { triggered: null, triggered_by: null });
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: false,
- pipeline,
- mediator,
- },
- });
+ createComponent({ mountFn: mount });
});
- describe('rendered output', () => {
- it('should include the first column with a no margin', () => {
- const firstColumn = wrapper.find('.stage-column');
-
- expect(firstColumn.classes('no-margin')).toBe(true);
- });
-
- it('should not render a linked pipelines column', () => {
- expect(wrapper.find('.linked-pipelines-column').exists()).toBe(false);
- });
- });
-
- describe('stageConnectorClass', () => {
- it('it returns no-margin when no triggerer and there is one job', () => {
- expect(findStageColumnAt(0).classes('no-margin')).toBe(true);
- });
-
- it('it returns left-margin when no triggerer and not the first stage', () => {
- expect(findStageColumnAt(1).classes('left-margin')).toBe(true);
- });
+ it('should not render a linked pipelines column', () => {
+ expect(findLinkedColumns()).toHaveLength(0);
});
});
- describe('capitalizeStageName', () => {
- it('capitalizes and escapes stage name', () => {
- wrapper = mount(graphComponent, {
- propsData: {
- isLoading: false,
- pipeline: graphJSON,
- mediator,
- },
+ describe('when linked pipelines are present', () => {
+ beforeEach(() => {
+ createComponent({
+ mountFn: mount,
+ props: { pipeline: pipelineWithUpstreamDownstream(mockPipelineResponse) },
});
+ });
- expect(findStageColumnAt(1).props('title')).toEqual(
- 'Deploy &lt;img src=x onerror=alert(document.domain)&gt;',
- );
+ it('should render linked pipelines columns', () => {
+ expect(findLinkedColumns()).toHaveLength(2);
});
});
});