diff options
Diffstat (limited to 'spec/frontend/pipeline_editor')
5 files changed, 94 insertions, 222 deletions
diff --git a/spec/frontend/pipeline_editor/components/drawer/cards/first_pipeline_card_spec.js b/spec/frontend/pipeline_editor/components/drawer/cards/first_pipeline_card_spec.js index bf5d15516c2..7e1e5004d91 100644 --- a/spec/frontend/pipeline_editor/components/drawer/cards/first_pipeline_card_spec.js +++ b/spec/frontend/pipeline_editor/components/drawer/cards/first_pipeline_card_spec.js @@ -8,16 +8,8 @@ describe('First pipeline card', () => { let wrapper; let trackingSpy; - const defaultProvide = { - runnerHelpPagePath: '/help/runners', - }; - const createComponent = () => { - wrapper = mount(FirstPipelineCard, { - provide: { - ...defaultProvide, - }, - }); + wrapper = mount(FirstPipelineCard); }; const getLinkByName = (name) => getByRole(wrapper.element, 'link', { name }); @@ -43,7 +35,7 @@ describe('First pipeline card', () => { }); it('renders the link', () => { - expect(findRunnersLink().href).toContain(defaultProvide.runnerHelpPagePath); + expect(findRunnersLink().href).toBe(wrapper.vm.$options.RUNNER_HELP_URL); }); describe('tracking', () => { diff --git a/spec/frontend/pipeline_editor/components/lint/ci_lint_spec.js b/spec/frontend/pipeline_editor/components/lint/ci_lint_spec.js deleted file mode 100644 index 238942a34ff..00000000000 --- a/spec/frontend/pipeline_editor/components/lint/ci_lint_spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import { GlAlert, GlLink } from '@gitlab/ui'; -import { mount, shallowMount } from '@vue/test-utils'; -import CiLint from '~/pipeline_editor/components/lint/ci_lint.vue'; -import { mergeUnwrappedCiConfig, mockLintHelpPagePath } from '../../mock_data'; - -describe('~/pipeline_editor/components/lint/ci_lint.vue', () => { - let wrapper; - - const createComponent = ({ props, mountFn = shallowMount } = {}) => { - wrapper = mountFn(CiLint, { - provide: { - lintHelpPagePath: mockLintHelpPagePath, - }, - propsData: { - ciConfig: mergeUnwrappedCiConfig(), - ...props, - }, - }); - }; - - const findAllByTestId = (selector) => wrapper.findAll(`[data-testid="${selector}"]`); - const findAlert = () => wrapper.find(GlAlert); - const findLintParameters = () => findAllByTestId('ci-lint-parameter'); - const findLintParameterAt = (i) => findLintParameters().at(i); - const findLintValueAt = (i) => findAllByTestId('ci-lint-value').at(i); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('Valid Results', () => { - beforeEach(() => { - createComponent({ props: { isValid: true }, mountFn: mount }); - }); - - it('displays valid results', () => { - expect(findAlert().text()).toMatch('Status: Syntax is correct.'); - }); - - it('displays link to the right help page', () => { - expect(findAlert().find(GlLink).attributes('href')).toBe(mockLintHelpPagePath); - }); - - it('displays jobs', () => { - expect(findLintParameters()).toHaveLength(3); - - expect(findLintParameterAt(0).text()).toBe('Test Job - job_test_1'); - expect(findLintParameterAt(1).text()).toBe('Test Job - job_test_2'); - expect(findLintParameterAt(2).text()).toBe('Build Job - job_build'); - }); - - it('displays jobs details', () => { - expect(findLintParameters()).toHaveLength(3); - - expect(findLintValueAt(0).text()).toMatchInterpolatedText( - 'echo "test 1" Only policy: branches, tags When: on_success', - ); - expect(findLintValueAt(1).text()).toMatchInterpolatedText( - 'echo "test 2" Only policy: branches, tags When: on_success', - ); - expect(findLintValueAt(2).text()).toMatchInterpolatedText( - 'echo "build" Only policy: branches, tags When: on_success', - ); - }); - - it('displays invalid results', () => { - createComponent({ props: { isValid: false }, mountFn: mount }); - - expect(findAlert().text()).toMatch('Status: Syntax is incorrect.'); - }); - }); -}); diff --git a/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js b/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js index 87a7f07f7d4..2f3e1b49b37 100644 --- a/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js +++ b/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js @@ -1,11 +1,12 @@ +// TODO + import { GlAlert, GlBadge, GlLoadingIcon, GlTabs } from '@gitlab/ui'; -import { createLocalVue, mount, shallowMount } from '@vue/test-utils'; +import { mount, shallowMount } from '@vue/test-utils'; import VueApollo from 'vue-apollo'; import Vue, { nextTick } from 'vue'; import createMockApollo from 'helpers/mock_apollo_helper'; import setWindowLocation from 'helpers/set_window_location_helper'; import CiConfigMergedPreview from '~/pipeline_editor/components/editor/ci_config_merged_preview.vue'; -import CiLint from '~/pipeline_editor/components/lint/ci_lint.vue'; import CiValidate from '~/pipeline_editor/components/validate/ci_validate.vue'; import WalkthroughPopover from '~/pipeline_editor/components/popovers/walkthrough_popover.vue'; import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tabs.vue'; @@ -30,8 +31,7 @@ import { mockLintResponseWithoutMerged, } from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(VueApollo); +Vue.use(VueApollo); Vue.config.ignoredElements = ['gl-emoji']; @@ -64,7 +64,12 @@ describe('Pipeline editor tabs component', () => { }; }, provide: { + ciConfigPath: '/path/to/ci-config', ciLintPath: mockCiLintPath, + currentBranch: 'main', + projectFullPath: '/path/to/project', + simulatePipelineHelpPagePath: 'path/to/help/page', + validateTabIllustrationPath: 'path/to/svg', ...provide, }, stubs: { @@ -88,21 +93,18 @@ describe('Pipeline editor tabs component', () => { provide, mountFn, options: { - localVue, apolloProvider: mockApollo, }, }); }; const findEditorTab = () => wrapper.find('[data-testid="editor-tab"]'); - const findLintTab = () => wrapper.find('[data-testid="lint-tab"]'); const findMergedTab = () => wrapper.find('[data-testid="merged-tab"]'); const findValidateTab = () => wrapper.find('[data-testid="validate-tab"]'); const findVisualizationTab = () => wrapper.find('[data-testid="visualization-tab"]'); const findAlert = () => wrapper.findComponent(GlAlert); const findBadge = () => wrapper.findComponent(GlBadge); - const findCiLint = () => wrapper.findComponent(CiLint); const findCiValidate = () => wrapper.findComponent(CiValidate); const findGlTabs = () => wrapper.findComponent(GlTabs); const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); @@ -121,7 +123,8 @@ describe('Pipeline editor tabs component', () => { describe('editor tab', () => { it('displays editor only after the tab is mounted', async () => { - createComponent({ mountFn: mount }); + mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse); + createComponentWithApollo({ mountFn: mount }); expect(findTextEditor().exists()).toBe(false); @@ -156,138 +159,57 @@ describe('Pipeline editor tabs component', () => { }); describe('validate tab', () => { - describe('with simulatePipeline feature flag ON', () => { - describe('after loading', () => { - beforeEach(() => { - createComponent({ - provide: { glFeatures: { simulatePipeline: true } }, - }); - }); - - it('displays the tab and the validate component', () => { - expect(findValidateTab().exists()).toBe(true); - expect(findCiValidate().exists()).toBe(true); - }); + describe('after loading', () => { + beforeEach(() => { + createComponent(); }); - describe('NEW badge', () => { - describe('default', () => { - beforeEach(() => { - mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse); - createComponentWithApollo({ - mountFn: mount, - props: { - currentTab: VALIDATE_TAB, - }, - provide: { - glFeatures: { simulatePipeline: true }, - ciConfigPath: '/path/to/ci-config', - currentBranch: 'main', - projectFullPath: '/path/to/project', - simulatePipelineHelpPagePath: 'path/to/help/page', - validateTabIllustrationPath: 'path/to/svg', - }, - }); - }); - - it('renders badge by default', () => { - expect(findBadge().exists()).toBe(true); - expect(findBadge().text()).toBe(wrapper.vm.$options.i18n.new); - }); - - it('hides badge when moving away from the validate tab', async () => { - expect(findBadge().exists()).toBe(true); - - await findEditorTab().vm.$emit('click'); - - expect(findBadge().exists()).toBe(false); - }); - }); - - describe('if badge has been dismissed before', () => { - beforeEach(() => { - localStorage.setItem(VALIDATE_TAB_BADGE_DISMISSED_KEY, 'true'); - mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse); - createComponentWithApollo({ - mountFn: mount, - provide: { - glFeatures: { simulatePipeline: true }, - ciConfigPath: '/path/to/ci-config', - currentBranch: 'main', - projectFullPath: '/path/to/project', - simulatePipelineHelpPagePath: 'path/to/help/page', - validateTabIllustrationPath: 'path/to/svg', - }, - }); - }); - - it('does not render badge if it has been dismissed before', () => { - expect(findBadge().exists()).toBe(false); - }); - }); + it('displays the tab and the validate component', () => { + expect(findValidateTab().exists()).toBe(true); + expect(findCiValidate().exists()).toBe(true); }); }); - describe('with simulatePipeline feature flag OFF', () => { - beforeEach(() => { - createComponent({ - provide: { - glFeatures: { - simulatePipeline: false, + describe('NEW badge', () => { + describe('default', () => { + beforeEach(() => { + mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse); + createComponentWithApollo({ + mountFn: mount, + props: { + currentTab: VALIDATE_TAB, }, - }, + }); }); - }); - it('does not render the tab and the validate component', () => { - expect(findValidateTab().exists()).toBe(false); - expect(findCiValidate().exists()).toBe(false); - }); - }); - }); + it('renders badge by default', () => { + expect(findBadge().exists()).toBe(true); + expect(findBadge().text()).toBe(wrapper.vm.$options.i18n.new); + }); - describe('lint tab', () => { - describe('while loading', () => { - beforeEach(() => { - createComponent({ appStatus: EDITOR_APP_STATUS_LOADING }); - }); + it('hides badge when moving away from the validate tab', async () => { + expect(findBadge().exists()).toBe(true); - it('displays a loading icon if the lint query is loading', () => { - expect(findLoadingIcon().exists()).toBe(true); - }); + await findEditorTab().vm.$emit('click'); - it('does not display the lint component', () => { - expect(findCiLint().exists()).toBe(false); - }); - }); - describe('after loading', () => { - beforeEach(() => { - createComponent(); - }); - - it('display the tab and the lint component', () => { - expect(findLintTab().exists()).toBe(true); - expect(findCiLint().exists()).toBe(true); + expect(findBadge().exists()).toBe(false); + }); }); - }); - describe('with simulatePipeline feature flag ON', () => { - beforeEach(() => { - createComponent({ - provide: { - glFeatures: { - simulatePipeline: true, - }, - }, + describe('if badge has been dismissed before', () => { + beforeEach(() => { + localStorage.setItem(VALIDATE_TAB_BADGE_DISMISSED_KEY, 'true'); + mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse); + createComponentWithApollo({ mountFn: mount }); }); - }); - it('does not render the tab and the lint component', () => { - expect(findLintTab().exists()).toBe(false); - expect(findCiLint().exists()).toBe(false); + it('does not render badge if it has been dismissed before', () => { + expect(findBadge().exists()).toBe(false); + }); }); }); }); + describe('merged tab', () => { describe('while loading', () => { beforeEach(() => { @@ -328,19 +250,19 @@ describe('Pipeline editor tabs component', () => { describe('show tab content based on status', () => { it.each` - appStatus | editor | viz | lint | merged + appStatus | editor | viz | validate | merged ${undefined} | ${true} | ${true} | ${true} | ${true} - ${EDITOR_APP_STATUS_EMPTY} | ${true} | ${false} | ${false} | ${false} + ${EDITOR_APP_STATUS_EMPTY} | ${true} | ${false} | ${true} | ${false} ${EDITOR_APP_STATUS_INVALID} | ${true} | ${false} | ${true} | ${false} ${EDITOR_APP_STATUS_VALID} | ${true} | ${true} | ${true} | ${true} `( - 'when status is $appStatus, we show - editor:$editor | viz:$viz | lint:$lint | merged:$merged ', - ({ appStatus, editor, viz, lint, merged }) => { + 'when status is $appStatus, we show - editor:$editor | viz:$viz | validate:$validate | merged:$merged ', + ({ appStatus, editor, viz, validate, merged }) => { createComponent({ appStatus }); expect(findTextEditor().exists()).toBe(editor); expect(findPipelineGraph().exists()).toBe(viz); - expect(findCiLint().exists()).toBe(lint); + expect(findValidateTab().exists()).toBe(validate); expect(findMergedPreview().exists()).toBe(merged); }, ); @@ -386,11 +308,8 @@ describe('Pipeline editor tabs component', () => { describe('pipeline editor walkthrough', () => { describe('when isNewCiConfigFile prop is true (default)', () => { - beforeEach(async () => { - createComponent({ - mountFn: mount, - }); - await nextTick(); + beforeEach(() => { + createComponent(); }); it('shows walkthrough popover', async () => { @@ -400,8 +319,7 @@ describe('Pipeline editor tabs component', () => { describe('when isNewCiConfigFile prop is false', () => { it('does not show walkthrough popover', async () => { - createComponent({ props: { isNewCiConfigFile: false }, mountFn: mount }); - await nextTick(); + createComponent({ props: { isNewCiConfigFile: false } }); expect(findWalkthroughPopover().exists()).toBe(false); }); }); @@ -411,7 +329,6 @@ describe('Pipeline editor tabs component', () => { const handler = jest.fn(); createComponent({ - mountFn: mount, listeners: { event: handler, }, diff --git a/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js b/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js index f5f01b675b2..09d4f9736ad 100644 --- a/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js +++ b/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js @@ -2,6 +2,7 @@ import { GlAlert, GlDropdown, GlIcon, GlLoadingIcon, GlPopover } from '@gitlab/u import { nextTick } from 'vue'; import { createLocalVue } from '@vue/test-utils'; import VueApollo from 'vue-apollo'; +import { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import createMockApollo from 'helpers/mock_apollo_helper'; import CiLintResults from '~/pipeline_editor/components/lint/ci_lint_results.vue'; @@ -9,6 +10,7 @@ import CiValidate, { i18n } from '~/pipeline_editor/components/validate/ci_valid import ValidatePipelinePopover from '~/pipeline_editor/components/popovers/validate_pipeline_popover.vue'; import getBlobContent from '~/pipeline_editor/graphql/queries/blob_content.query.graphql'; import lintCIMutation from '~/pipeline_editor/graphql/mutations/client/lint_ci.mutation.graphql'; +import { pipelineEditorTrackingOptions } from '~/pipeline_editor/constants'; import { mockBlobContentQueryResponse, mockCiLintPath, @@ -24,6 +26,7 @@ describe('Pipeline Editor Validate Tab', () => { let wrapper; let mockApollo; let mockBlobContentData; + let trackingSpy; const createComponent = ({ props, @@ -140,9 +143,24 @@ describe('Pipeline Editor Validate Tab', () => { mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse); await createComponentWithApollo(); + trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockLintDataValid); }); + afterEach(() => { + unmockTracking(); + }); + + it('tracks the simulation event', () => { + const { + label, + actions: { simulatePipeline }, + } = pipelineEditorTrackingOptions; + findCta().vm.$emit('click'); + + expect(trackingSpy).toHaveBeenCalledWith(undefined, simulatePipeline, { label }); + }); + it('renders loading state while simulation is ongoing', async () => { findCta().vm.$emit('click'); await nextTick(); @@ -159,7 +177,7 @@ describe('Pipeline Editor Validate Tab', () => { expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ mutation: lintCIMutation, variables: { - dry_run: true, + dry: true, content: mockCiYml, endpoint: mockCiLintPath, }, @@ -224,10 +242,27 @@ describe('Pipeline Editor Validate Tab', () => { mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse); await createComponentWithApollo(); + trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockLintDataValid); await findCta().vm.$emit('click'); }); + afterEach(() => { + unmockTracking(); + }); + + it('tracks the second simulation event', async () => { + const { + label, + actions: { resimulatePipeline }, + } = pipelineEditorTrackingOptions; + + await wrapper.setProps({ ciFileContent: 'new yaml content' }); + findResultsCta().vm.$emit('click'); + + expect(trackingSpy).toHaveBeenCalledWith(undefined, resimulatePipeline, { label }); + }); + it('renders content change status', async () => { await wrapper.setProps({ ciFileContent: 'new yaml content' }); @@ -243,7 +278,7 @@ describe('Pipeline Editor Validate Tab', () => { expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ mutation: lintCIMutation, variables: { - dry_run: true, + dry: true, content: 'new yaml content', endpoint: mockCiLintPath, }, diff --git a/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js index c6964f190b4..0cb7155c8c0 100644 --- a/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js +++ b/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js @@ -14,7 +14,7 @@ import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tab import { CREATE_TAB, FILE_TREE_DISPLAY_KEY, - LINT_TAB, + VALIDATE_TAB, MERGED_TAB, TABS_INDEX, VISUALIZE_TAB, @@ -138,7 +138,7 @@ describe('Pipeline editor home wrapper', () => { tab | shouldShow ${MERGED_TAB} | ${false} ${VISUALIZE_TAB} | ${false} - ${LINT_TAB} | ${false} + ${VALIDATE_TAB} | ${false} ${CREATE_TAB} | ${true} `( 'when the active tab is $tab the commit form is shown: $shouldShow', @@ -170,7 +170,7 @@ describe('Pipeline editor home wrapper', () => { tab | shouldShow ${MERGED_TAB} | ${false} ${VISUALIZE_TAB} | ${false} - ${LINT_TAB} | ${false} + ${VALIDATE_TAB} | ${false} ${CREATE_TAB} | ${true} `( 'when the tab query param is $tab the commit form is shown: $shouldShow', |