From 85dc423f7090da0a52c73eb66faf22ddb20efff9 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Sat, 19 Sep 2020 01:45:44 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-4-stable-ee --- .../gitlab_ci_yaml_visualization_spec.js | 47 +++++++ .../frontend/pipelines/pipeline_graph/mock_data.js | 80 +++++++++++ .../pipeline_graph/pipeline_graph_spec.js | 59 ++++++++ .../pipelines/pipeline_graph/utils_spec.js | 150 +++++++++++++++++++++ 4 files changed, 336 insertions(+) create mode 100644 spec/frontend/pipelines/pipeline_graph/gitlab_ci_yaml_visualization_spec.js create mode 100644 spec/frontend/pipelines/pipeline_graph/mock_data.js create mode 100644 spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js create mode 100644 spec/frontend/pipelines/pipeline_graph/utils_spec.js (limited to 'spec/frontend/pipelines/pipeline_graph') diff --git a/spec/frontend/pipelines/pipeline_graph/gitlab_ci_yaml_visualization_spec.js b/spec/frontend/pipelines/pipeline_graph/gitlab_ci_yaml_visualization_spec.js new file mode 100644 index 00000000000..fea42350959 --- /dev/null +++ b/spec/frontend/pipelines/pipeline_graph/gitlab_ci_yaml_visualization_spec.js @@ -0,0 +1,47 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlTab } from '@gitlab/ui'; +import { yamlString } from './mock_data'; +import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue'; +import GitlabCiYamlVisualization from '~/pipelines/components/pipeline_graph/gitlab_ci_yaml_visualization.vue'; + +describe('gitlab yaml visualization component', () => { + const defaultProps = { blobData: yamlString }; + let wrapper; + + const createComponent = props => { + return shallowMount(GitlabCiYamlVisualization, { + propsData: { + ...defaultProps, + ...props, + }, + }); + }; + + const findGlTabComponents = () => wrapper.findAll(GlTab); + const findPipelineGraph = () => wrapper.find(PipelineGraph); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('tabs component', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + + it('renders the file and visualization tabs', () => { + expect(findGlTabComponents()).toHaveLength(2); + }); + }); + + describe('graph component', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + + it('is hidden by default', () => { + expect(findPipelineGraph().exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/pipelines/pipeline_graph/mock_data.js b/spec/frontend/pipelines/pipeline_graph/mock_data.js new file mode 100644 index 00000000000..5a5d6c021a6 --- /dev/null +++ b/spec/frontend/pipelines/pipeline_graph/mock_data.js @@ -0,0 +1,80 @@ +export const yamlString = `stages: +- empty +- build +- test +- deploy +- final + +include: +- template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml' + +build_a: + stage: build + script: echo hello +build_b: + stage: build + script: echo hello +build_c: + stage: build + script: echo hello +build_d: + stage: Queen + script: echo hello + +test_a: + stage: test + script: ls + needs: [build_a, build_b, build_c] +test_b: + stage: test + script: ls + needs: [build_a, build_b, build_d] +test_c: + stage: test + script: ls + needs: [build_a, build_b, build_c] + +deploy_a: + stage: deploy + script: echo hello +`; + +export const pipelineData = { + stages: [ + { + name: 'build', + groups: [], + }, + { + name: 'build', + groups: [ + { + name: 'build_1', + jobs: [{ script: 'echo hello', stage: 'build' }], + }, + ], + }, + { + name: 'test', + groups: [ + { + name: 'test_1', + jobs: [{ script: 'yarn test', stage: 'test' }], + }, + { + name: 'test_2', + jobs: [{ script: 'yarn karma', stage: 'test' }], + }, + ], + }, + { + name: 'deploy', + groups: [ + { + name: 'deploy_1', + jobs: [{ script: 'yarn magick', stage: 'deploy' }], + }, + ], + }, + ], +}; diff --git a/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js b/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js new file mode 100644 index 00000000000..30e192e5726 --- /dev/null +++ b/spec/frontend/pipelines/pipeline_graph/pipeline_graph_spec.js @@ -0,0 +1,59 @@ +import { shallowMount } from '@vue/test-utils'; +import { pipelineData } from './mock_data'; +import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue'; +import StagePill from '~/pipelines/components/pipeline_graph/stage_pill.vue'; +import JobPill from '~/pipelines/components/pipeline_graph/job_pill.vue'; + +describe('pipeline graph component', () => { + const defaultProps = { pipelineData }; + let wrapper; + + const createComponent = props => { + return shallowMount(PipelineGraph, { + propsData: { + ...defaultProps, + ...props, + }, + }); + }; + + const findAllStagePills = () => wrapper.findAll(StagePill); + const findAllJobPills = () => wrapper.findAll(JobPill); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('with no data', () => { + beforeEach(() => { + wrapper = createComponent({ pipelineData: {} }); + }); + + it('renders an empty section', () => { + expect(wrapper.text()).toContain('No content to show'); + expect(findAllStagePills()).toHaveLength(0); + expect(findAllJobPills()).toHaveLength(0); + }); + }); + + describe('with data', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + it('renders the right number of stage pills', () => { + const expectedStagesLength = pipelineData.stages.length; + + expect(findAllStagePills()).toHaveLength(expectedStagesLength); + }); + + it('renders the right number of job pills', () => { + // We count the number of jobs in the mock data + const expectedJobsLength = pipelineData.stages.reduce((acc, val) => { + return acc + val.groups.length; + }, 0); + + expect(findAllJobPills()).toHaveLength(expectedJobsLength); + }); + }); +}); diff --git a/spec/frontend/pipelines/pipeline_graph/utils_spec.js b/spec/frontend/pipelines/pipeline_graph/utils_spec.js new file mode 100644 index 00000000000..dd85c8c2bd0 --- /dev/null +++ b/spec/frontend/pipelines/pipeline_graph/utils_spec.js @@ -0,0 +1,150 @@ +import { preparePipelineGraphData } from '~/pipelines/utils'; + +describe('preparePipelineGraphData', () => { + const emptyResponse = { stages: [] }; + const jobName1 = 'build_1'; + const jobName2 = 'build_2'; + const jobName3 = 'test_1'; + const jobName4 = 'deploy_1'; + const job1 = { [jobName1]: { script: 'echo hello', stage: 'build' } }; + const job2 = { [jobName2]: { script: 'echo build', stage: 'build' } }; + const job3 = { [jobName3]: { script: 'echo test', stage: 'test' } }; + const job4 = { [jobName4]: { script: 'echo deploy', stage: 'deploy' } }; + + describe('returns an object with an empty array of stages if', () => { + it('no data is passed', () => { + expect(preparePipelineGraphData({})).toEqual(emptyResponse); + }); + + it('no stages are found', () => { + expect(preparePipelineGraphData({ includes: 'template/myTemplate.gitlab-ci.yml' })).toEqual( + emptyResponse, + ); + }); + }); + + describe('returns the correct array of stages', () => { + it('when multiple jobs are in the same stage', () => { + const expectedData = { + stages: [ + { + name: job1[jobName1].stage, + groups: [ + { + name: jobName1, + jobs: [{ script: job1[jobName1].script, stage: job1[jobName1].stage }], + }, + { + name: jobName2, + jobs: [{ script: job2[jobName2].script, stage: job2[jobName2].stage }], + }, + ], + }, + ], + }; + + expect(preparePipelineGraphData({ ...job1, ...job2 })).toEqual(expectedData); + }); + + it('when stages are defined by the user', () => { + const userDefinedStage = 'myStage'; + const userDefinedStage2 = 'myStage2'; + + const expectedData = { + stages: [ + { + name: userDefinedStage, + groups: [], + }, + { + name: userDefinedStage2, + groups: [], + }, + ], + }; + + expect(preparePipelineGraphData({ stages: [userDefinedStage, userDefinedStage2] })).toEqual( + expectedData, + ); + }); + + it('by combining user defined stage and job stages, it preserves user defined order', () => { + const userDefinedStage = 'myStage'; + const userDefinedStageThatOverlaps = 'deploy'; + + const expectedData = { + stages: [ + { + name: userDefinedStage, + groups: [], + }, + { + name: job4[jobName4].stage, + groups: [ + { + name: jobName4, + jobs: [{ script: job4[jobName4].script, stage: job4[jobName4].stage }], + }, + ], + }, + { + name: job1[jobName1].stage, + groups: [ + { + name: jobName1, + jobs: [{ script: job1[jobName1].script, stage: job1[jobName1].stage }], + }, + { + name: jobName2, + jobs: [{ script: job2[jobName2].script, stage: job2[jobName2].stage }], + }, + ], + }, + { + name: job3[jobName3].stage, + groups: [ + { + name: jobName3, + jobs: [{ script: job3[jobName3].script, stage: job3[jobName3].stage }], + }, + ], + }, + ], + }; + + expect( + preparePipelineGraphData({ + stages: [userDefinedStage, userDefinedStageThatOverlaps], + ...job1, + ...job2, + ...job3, + ...job4, + }), + ).toEqual(expectedData); + }); + + it('with only unique values', () => { + const expectedData = { + stages: [ + { + name: job1[jobName1].stage, + groups: [ + { + name: jobName1, + jobs: [{ script: job1[jobName1].script, stage: job1[jobName1].stage }], + }, + ], + }, + ], + }; + + expect( + preparePipelineGraphData({ + stages: ['build'], + ...job1, + ...job1, + }), + ).toEqual(expectedData); + }); + }); +}); -- cgit v1.2.1