diff options
Diffstat (limited to 'spec/frontend/ci/pipeline_editor')
7 files changed, 403 insertions, 5 deletions
diff --git a/spec/frontend/ci/pipeline_editor/components/graph/mock_data.js b/spec/frontend/ci/pipeline_editor/components/graph/mock_data.js new file mode 100644 index 00000000000..db77e0a0573 --- /dev/null +++ b/spec/frontend/ci/pipeline_editor/components/graph/mock_data.js @@ -0,0 +1,283 @@ +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 pipelineDataWithNoNeeds = { + stages: [ + { + name: 'build', + groups: [ + { + name: 'build_1', + jobs: [{ script: 'echo hello', stage: 'build' }], + }, + ], + }, + { + name: 'test', + groups: [ + { + name: 'test_1', + jobs: [{ script: 'yarn test', stage: 'test' }], + }, + ], + }, + ], +}; + +export const pipelineData = { + stages: [ + { + 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', needs: ['test_1'] }], + }, + ], + }, + ], +}; + +export const invalidNeedsData = { + stages: [ + { + 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', needs: ['invalid_job'] }], + }, + ], + }, + ], +}; + +export const parallelNeedData = { + stages: [ + { + name: 'build', + groups: [ + { + name: 'build_1', + parallel: 3, + jobs: [ + { script: 'echo hello', stage: 'build', name: 'build_1 1/3' }, + { script: 'echo hello', stage: 'build', name: 'build_1 2/3' }, + { script: 'echo hello', stage: 'build', name: 'build_1 3/3' }, + ], + }, + ], + }, + { + name: 'test', + groups: [ + { + name: 'test_1', + jobs: [{ script: 'yarn test', stage: 'test', needs: ['build_1'] }], + }, + ], + }, + ], +}; + +export const sameStageNeeds = { + stages: [ + { + name: 'build', + groups: [ + { + name: 'build_1', + jobs: [{ script: 'echo hello', stage: 'build', name: 'build_1' }], + }, + ], + }, + { + name: 'build', + groups: [ + { + name: 'build_2', + jobs: [{ script: 'yarn test', stage: 'build', needs: ['build_1'] }], + }, + ], + }, + { + name: 'build', + groups: [ + { + name: 'build_3', + jobs: [{ script: 'yarn test', stage: 'build', needs: ['build_2'] }], + }, + ], + }, + ], +}; + +export const largePipelineData = { + stages: [ + { + name: 'build', + groups: [ + { + name: 'build_1', + jobs: [{ script: 'echo hello', stage: 'build' }], + }, + { + name: 'build_2', + jobs: [{ script: 'echo hello', stage: 'build' }], + }, + { + name: 'build_3', + jobs: [{ script: 'echo hello', stage: 'build' }], + }, + ], + }, + { + name: 'test', + groups: [ + { + name: 'test_1', + jobs: [{ script: 'yarn test', stage: 'test', needs: ['build_2'] }], + }, + { + name: 'test_2', + jobs: [{ script: 'yarn karma', stage: 'test', needs: ['build_2'] }], + }, + ], + }, + { + name: 'deploy', + groups: [ + { + name: 'deploy_1', + jobs: [{ script: 'yarn magick', stage: 'deploy', needs: ['test_1'] }], + }, + { + name: 'deploy_2', + jobs: [{ script: 'yarn magick', stage: 'deploy', needs: ['build_3'] }], + }, + { + name: 'deploy_3', + jobs: [{ script: 'yarn magick', stage: 'deploy', needs: ['test_2'] }], + }, + ], + }, + ], +}; + +export const singleStageData = { + stages: [ + { + name: 'build', + groups: [ + { + name: 'build_1', + jobs: [{ script: 'echo hello', stage: 'build' }], + }, + ], + }, + ], +}; + +export const rootRect = { + bottom: 463, + height: 271, + left: 236, + right: 1252, + top: 192, + width: 1016, + x: 236, + y: 192, +}; + +export const jobRect = { + bottom: 312, + height: 24, + left: 308, + right: 428, + top: 288, + width: 120, + x: 308, + y: 288, +}; diff --git a/spec/frontend/ci/pipeline_editor/components/graph/pipeline_graph_spec.js b/spec/frontend/ci/pipeline_editor/components/graph/pipeline_graph_spec.js new file mode 100644 index 00000000000..95edfb01cf0 --- /dev/null +++ b/spec/frontend/ci/pipeline_editor/components/graph/pipeline_graph_spec.js @@ -0,0 +1,100 @@ +import { GlAlert } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import { setHTMLFixture } from 'helpers/fixtures'; +import { CI_CONFIG_STATUS_VALID } from '~/ci/pipeline_editor/constants'; +import LinksInner from '~/ci/pipeline_details/graph/components/links_inner.vue'; +import LinksLayer from '~/ci/common/private/job_links_layer.vue'; +import JobPill from '~/ci/pipeline_editor/components/graph/job_pill.vue'; +import PipelineGraph from '~/ci/pipeline_editor/components/graph/pipeline_graph.vue'; +import StageName from '~/ci/pipeline_editor/components/graph/stage_name.vue'; +import { pipelineData, singleStageData } from './mock_data'; + +describe('pipeline graph component', () => { + const defaultProps = { pipelineData }; + let wrapper; + + const containerId = 'pipeline-graph-container-0'; + setHTMLFixture(`<div id="${containerId}"></div>`); + + const createComponent = (props = defaultProps) => { + return shallowMount(PipelineGraph, { + propsData: { + ...props, + }, + stubs: { LinksLayer, LinksInner }, + data() { + return { + measurements: { + width: 1000, + height: 1000, + }, + }; + }, + }); + }; + + const findAlert = () => wrapper.findComponent(GlAlert); + const findAllJobPills = () => wrapper.findAllComponents(JobPill); + const findAllStageNames = () => wrapper.findAllComponents(StageName); + const findLinksLayer = () => wrapper.findComponent(LinksLayer); + const findPipelineGraph = () => wrapper.find('[data-testid="graph-container"]'); + + describe('with `VALID` status', () => { + beforeEach(() => { + wrapper = createComponent({ + pipelineData: { + status: CI_CONFIG_STATUS_VALID, + stages: [{ name: 'hello', groups: [] }], + }, + }); + }); + + it('renders the graph with no status error', () => { + expect(findAlert().exists()).toBe(false); + expect(findPipelineGraph().exists()).toBe(true); + expect(findLinksLayer().exists()).toBe(true); + }); + }); + + describe('with only one stage', () => { + beforeEach(() => { + wrapper = createComponent({ pipelineData: singleStageData }); + }); + + it('renders the right number of stage titles', () => { + const expectedStagesLength = singleStageData.stages.length; + + expect(findAllStageNames()).toHaveLength(expectedStagesLength); + }); + + it('renders the right number of job pills', () => { + // We count the number of jobs in the mock data + const expectedJobsLength = singleStageData.stages.reduce((acc, val) => { + return acc + val.groups.length; + }, 0); + + expect(findAllJobPills()).toHaveLength(expectedJobsLength); + }); + }); + + describe('with multiple stages and jobs', () => { + beforeEach(() => { + wrapper = createComponent(); + }); + + it('renders the right number of stage titles', () => { + const expectedStagesLength = pipelineData.stages.length; + + expect(findAllStageNames()).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/ci/pipeline_editor/components/header/pipeline_editor_header_spec.js b/spec/frontend/ci/pipeline_editor/components/header/pipeline_editor_header_spec.js index a651664851e..655bfe538c6 100644 --- a/spec/frontend/ci/pipeline_editor/components/header/pipeline_editor_header_spec.js +++ b/spec/frontend/ci/pipeline_editor/components/header/pipeline_editor_header_spec.js @@ -1,4 +1,5 @@ import { shallowMount } from '@vue/test-utils'; +import { GlCard } from '@gitlab/ui'; import PipelineEditorHeader from '~/ci/pipeline_editor/components/header/pipeline_editor_header.vue'; import PipelineStatus from '~/ci/pipeline_editor/components/header/pipeline_status.vue'; import ValidationSegment from '~/ci/pipeline_editor/components/header/validation_segment.vue'; @@ -20,6 +21,9 @@ describe('Pipeline editor header', () => { isNewCiConfigFile: false, ...props, }, + stubs: { + GlCard, + }, }); }; diff --git a/spec/frontend/ci/pipeline_editor/components/header/pipeline_editor_mini_graph_spec.js b/spec/frontend/ci/pipeline_editor/components/header/pipeline_editor_mini_graph_spec.js index f5e0b65d615..4ec1dd4b605 100644 --- a/spec/frontend/ci/pipeline_editor/components/header/pipeline_editor_mini_graph_spec.js +++ b/spec/frontend/ci/pipeline_editor/components/header/pipeline_editor_mini_graph_spec.js @@ -4,8 +4,8 @@ import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import PipelineEditorMiniGraph from '~/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue'; -import LegacyPipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/legacy_pipeline_mini_graph.vue'; -import getLinkedPipelinesQuery from '~/pipelines/graphql/queries/get_linked_pipelines.query.graphql'; +import LegacyPipelineMiniGraph from '~/ci/pipeline_mini_graph/legacy_pipeline_mini_graph.vue'; +import getLinkedPipelinesQuery from '~/ci/pipeline_details/graphql/queries/get_linked_pipelines.query.graphql'; import { PIPELINE_FAILURE } from '~/ci/pipeline_editor/constants'; import { mockLinkedPipelines, mockProjectFullPath, mockProjectPipeline } from '../../mock_data'; diff --git a/spec/frontend/ci/pipeline_editor/components/header/pipeline_status_spec.js b/spec/frontend/ci/pipeline_editor/components/header/pipeline_status_spec.js index 3bbe14adb88..1a2ed60a6f4 100644 --- a/spec/frontend/ci/pipeline_editor/components/header/pipeline_status_spec.js +++ b/spec/frontend/ci/pipeline_editor/components/header/pipeline_status_spec.js @@ -6,8 +6,9 @@ import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import PipelineStatus, { i18n } from '~/ci/pipeline_editor/components/header/pipeline_status.vue'; import getPipelineQuery from '~/ci/pipeline_editor/graphql/queries/pipeline.query.graphql'; -import PipelineMiniGraph from '~/pipelines/components/pipeline_mini_graph/pipeline_mini_graph.vue'; +import PipelineMiniGraph from '~/ci/pipeline_mini_graph/pipeline_mini_graph.vue'; import PipelineEditorMiniGraph from '~/ci/pipeline_editor/components/header/pipeline_editor_mini_graph.vue'; +import getPipelineEtag from '~/ci/pipeline_editor/graphql/queries/client/pipeline_etag.query.graphql'; import { mockCommitSha, mockProjectPipeline, mockProjectFullPath } from '../../mock_data'; Vue.use(VueApollo); @@ -21,6 +22,16 @@ describe('Pipeline Status', () => { const handlers = [[getPipelineQuery, mockPipelineQuery]]; mockApollo = createMockApollo(handlers); + mockApollo.clients.defaultClient.cache.writeQuery({ + query: getPipelineEtag, + data: { + etags: { + __typename: 'EtagValues', + pipeline: 'pipelines/1', + }, + }, + }); + wrapper = shallowMount(PipelineStatus, { apolloProvider: mockApollo, propsData: { diff --git a/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js b/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js index 77252a5c0b6..69e91f11309 100644 --- a/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js +++ b/spec/frontend/ci/pipeline_editor/components/pipeline_editor_tabs_spec.js @@ -19,7 +19,7 @@ import { VALIDATE_TAB, VALIDATE_TAB_BADGE_DISMISSED_KEY, } from '~/ci/pipeline_editor/constants'; -import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue'; +import PipelineGraph from '~/ci/pipeline_editor/components/graph/pipeline_graph.vue'; import getBlobContent from '~/ci/pipeline_editor/graphql/queries/blob_content.query.graphql'; import { mockBlobContentQueryResponse, diff --git a/spec/frontend/ci/pipeline_editor/mock_data.js b/spec/frontend/ci/pipeline_editor/mock_data.js index 007abde939f..e08c35f1555 100644 --- a/spec/frontend/ci/pipeline_editor/mock_data.js +++ b/spec/frontend/ci/pipeline_editor/mock_data.js @@ -1,5 +1,5 @@ import { CI_CONFIG_STATUS_INVALID, CI_CONFIG_STATUS_VALID } from '~/ci/pipeline_editor/constants'; -import { unwrapStagesWithNeeds } from '~/pipelines/components/unwrapping_utils'; +import { unwrapStagesWithNeeds } from '~/ci/pipeline_details/utils/unwrapping_utils'; import { DOCS_URL_IN_EE_DIR } from 'jh_else_ce/lib/utils/url_utility'; export const commonOptions = { |