From a5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 16 Jun 2021 18:25:58 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-0-stable-ee --- .../components/commit/commit_section_spec.js | 9 +- .../drawer/cards/first_pipeline_card_spec.js | 12 +- .../drawer/ui/pipeline_visual_reference_spec.js | 31 ----- .../components/editor/text_editor_spec.js | 51 ++++--- .../components/file-nav/branch_switcher_spec.js | 153 +++++++++++++++++---- 5 files changed, 167 insertions(+), 89 deletions(-) delete mode 100644 spec/frontend/pipeline_editor/components/drawer/ui/pipeline_visual_reference_spec.js (limited to 'spec/frontend/pipeline_editor/components') diff --git a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js index 9e677425807..39081e07e52 100644 --- a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js +++ b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js @@ -118,7 +118,8 @@ describe('Pipeline Editor | Commit section', () => { }); it('calls the mutation with the CREATE action', () => { - expect(mockMutate).toHaveBeenCalledTimes(1); + // the extra calls are for updating client queries (currentBranch and lastCommitBranch) + expect(mockMutate).toHaveBeenCalledTimes(3); expect(mockMutate).toHaveBeenCalledWith({ mutation: commitCreate, update: expect.any(Function), @@ -138,7 +139,7 @@ describe('Pipeline Editor | Commit section', () => { }); it('calls the mutation with the UPDATE action', () => { - expect(mockMutate).toHaveBeenCalledTimes(1); + expect(mockMutate).toHaveBeenCalledTimes(3); expect(mockMutate).toHaveBeenCalledWith({ mutation: commitCreate, update: expect.any(Function), @@ -158,7 +159,7 @@ describe('Pipeline Editor | Commit section', () => { }); it('calls the mutation with the current branch', () => { - expect(mockMutate).toHaveBeenCalledTimes(1); + expect(mockMutate).toHaveBeenCalledTimes(3); expect(mockMutate).toHaveBeenCalledWith({ mutation: commitCreate, update: expect.any(Function), @@ -181,7 +182,7 @@ describe('Pipeline Editor | Commit section', () => { it('a second commit submits the latest sha, keeping the form updated', async () => { await submitCommit(); - expect(mockMutate).toHaveBeenCalledTimes(2); + expect(mockMutate).toHaveBeenCalledTimes(6); expect(mockMutate).toHaveBeenCalledWith({ mutation: commitCreate, update: expect.any(Function), 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 8a4f07c4d88..e435c0dcc08 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 @@ -1,13 +1,11 @@ import { getByRole } from '@testing-library/dom'; import { mount } from '@vue/test-utils'; import FirstPipelineCard from '~/pipeline_editor/components/drawer/cards/first_pipeline_card.vue'; -import PipelineVisualReference from '~/pipeline_editor/components/drawer/ui/pipeline_visual_reference.vue'; describe('First pipeline card', () => { let wrapper; const defaultProvide = { - ciExamplesHelpPagePath: '/pipelines/examples', runnerHelpPagePath: '/help/runners', }; @@ -20,9 +18,9 @@ describe('First pipeline card', () => { }; const getLinkByName = (name) => getByRole(wrapper.element, 'link', { name }).href; - const findPipelinesLink = () => getLinkByName(/examples and templates/i); const findRunnersLink = () => getLinkByName(/make sure your instance has runners available/i); - const findVisualReference = () => wrapper.findComponent(PipelineVisualReference); + const findInstructionsList = () => wrapper.find('ol'); + const findAllInstructions = () => findInstructionsList().findAll('li'); beforeEach(() => { createComponent(); @@ -37,11 +35,11 @@ describe('First pipeline card', () => { }); it('renders the content', () => { - expect(findVisualReference().exists()).toBe(true); + expect(findInstructionsList().exists()).toBe(true); + expect(findAllInstructions()).toHaveLength(3); }); - it('renders the links', () => { + it('renders the link', () => { expect(findRunnersLink()).toContain(defaultProvide.runnerHelpPagePath); - expect(findPipelinesLink()).toContain(defaultProvide.ciExamplesHelpPagePath); }); }); diff --git a/spec/frontend/pipeline_editor/components/drawer/ui/pipeline_visual_reference_spec.js b/spec/frontend/pipeline_editor/components/drawer/ui/pipeline_visual_reference_spec.js deleted file mode 100644 index e4834544484..00000000000 --- a/spec/frontend/pipeline_editor/components/drawer/ui/pipeline_visual_reference_spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import DemoJobPill from '~/pipeline_editor/components/drawer/ui/demo_job_pill.vue'; -import PipelineVisualReference from '~/pipeline_editor/components/drawer/ui/pipeline_visual_reference.vue'; - -describe('Demo job pill', () => { - let wrapper; - - const createComponent = () => { - wrapper = shallowMount(PipelineVisualReference); - }; - - const findAllDemoJobPills = () => wrapper.findAllComponents(DemoJobPill); - - beforeEach(() => { - createComponent(); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders all stage names', () => { - expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.stageNames.build); - expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.stageNames.test); - expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.stageNames.deploy); - }); - - it('renders all job pills', () => { - expect(findAllDemoJobPills()).toHaveLength(4); - }); -}); diff --git a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js index 7a5b01fb04a..6f9245e39aa 100644 --- a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js +++ b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js @@ -9,6 +9,7 @@ import { mockCommitSha, mockProjectPath, mockProjectNamespace, + mockDefaultBranch, } from '../../mock_data'; describe('Pipeline Editor | Text editor component', () => { @@ -32,12 +33,14 @@ describe('Pipeline Editor | Text editor component', () => { }, }; - const createComponent = (opts = {}, mountFn = shallowMount) => { + const createComponent = (glFeatures = {}, mountFn = shallowMount) => { wrapper = mountFn(TextEditor, { provide: { projectPath: mockProjectPath, projectNamespace: mockProjectNamespace, ciConfigPath: mockCiConfigPath, + defaultBranch: mockDefaultBranch, + glFeatures, }, attrs: { value: mockCiYml, @@ -54,7 +57,6 @@ describe('Pipeline Editor | Text editor component', () => { stubs: { EditorLite: MockEditorLite, }, - ...opts, }); }; @@ -66,7 +68,6 @@ describe('Pipeline Editor | Text editor component', () => { afterEach(() => { wrapper.destroy(); - wrapper = null; mockUse.mockClear(); mockRegisterCiSchema.mockClear(); @@ -100,25 +101,37 @@ describe('Pipeline Editor | Text editor component', () => { }); }); - describe('register CI schema', () => { - beforeEach(async () => { - createComponent(); - - // Since the editor will have already mounted, the event will have fired. - // To ensure we properly test this, we clear the mock and re-remit the event. - mockRegisterCiSchema.mockClear(); - mockUse.mockClear(); + describe('CI schema', () => { + describe('when `schema_linting` feature flag is on', () => { + beforeEach(() => { + createComponent({ schemaLinting: true }); + // Since the editor will have already mounted, the event will have fired. + // To ensure we properly test this, we clear the mock and re-remit the event. + mockRegisterCiSchema.mockClear(); + mockUse.mockClear(); + findEditor().vm.$emit(EDITOR_READY_EVENT); + }); - findEditor().vm.$emit(EDITOR_READY_EVENT); + it('configures editor with syntax highlight', () => { + expect(mockUse).toHaveBeenCalledTimes(1); + expect(mockRegisterCiSchema).toHaveBeenCalledTimes(1); + expect(mockRegisterCiSchema).toHaveBeenCalledWith({ + projectNamespace: mockProjectNamespace, + projectPath: mockProjectPath, + ref: mockCommitSha, + }); + }); }); - it('configures editor with syntax highlight', async () => { - expect(mockUse).toHaveBeenCalledTimes(1); - expect(mockRegisterCiSchema).toHaveBeenCalledTimes(1); - expect(mockRegisterCiSchema).toHaveBeenCalledWith({ - projectNamespace: mockProjectNamespace, - projectPath: mockProjectPath, - ref: mockCommitSha, + describe('when `schema_linting` feature flag is off', () => { + beforeEach(() => { + createComponent(); + findEditor().vm.$emit(EDITOR_READY_EVENT); + }); + + it('does not call the register CI schema function', () => { + expect(mockUse).not.toHaveBeenCalled(); + expect(mockRegisterCiSchema).not.toHaveBeenCalled(); }); }); }); diff --git a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js index d6763a7de41..e731ad8695e 100644 --- a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js +++ b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js @@ -11,7 +11,7 @@ import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import BranchSwitcher from '~/pipeline_editor/components/file_nav/branch_switcher.vue'; import { DEFAULT_FAILURE } from '~/pipeline_editor/constants'; -import getAvailableBranches from '~/pipeline_editor/graphql/queries/available_branches.graphql'; +import getAvailableBranchesQuery from '~/pipeline_editor/graphql/queries/available_branches.graphql'; import { mockBranchPaginationLimit, mockDefaultBranch, @@ -22,6 +22,7 @@ import { mockTotalBranches, mockTotalBranchResults, mockTotalSearchResults, + mockNewBranch, } from '../../mock_data'; const localVue = createLocalVue(); @@ -31,9 +32,12 @@ describe('Pipeline editor branch switcher', () => { let wrapper; let mockApollo; let mockAvailableBranchQuery; + let mockCurrentBranchQuery; + let mockLastCommitBranchQuery; const createComponent = ( - { isQueryLoading, mountFn, options } = { + { currentBranch, isQueryLoading, mountFn, options } = { + currentBranch: mockDefaultBranch, isQueryLoading: false, mountFn: shallowMount, options: {}, @@ -58,8 +62,8 @@ describe('Pipeline editor branch switcher', () => { }, data() { return { - branches: ['main'], - currentBranch: mockDefaultBranch, + availableBranches: ['main'], + currentBranch, }; }, ...options, @@ -67,8 +71,18 @@ describe('Pipeline editor branch switcher', () => { }; const createComponentWithApollo = (mountFn = shallowMount) => { - const handlers = [[getAvailableBranches, mockAvailableBranchQuery]]; - mockApollo = createMockApollo(handlers); + const handlers = [[getAvailableBranchesQuery, mockAvailableBranchQuery]]; + const resolvers = { + Query: { + currentBranch() { + return mockCurrentBranchQuery(); + }, + lastCommitBranch() { + return mockLastCommitBranchQuery(); + }, + }, + }; + mockApollo = createMockApollo(handlers, resolvers); createComponent({ mountFn, @@ -76,11 +90,6 @@ describe('Pipeline editor branch switcher', () => { localVue, apolloProvider: mockApollo, mocks: {}, - data() { - return { - currentBranch: mockDefaultBranch, - }; - }, }, }); }; @@ -90,15 +99,40 @@ describe('Pipeline editor branch switcher', () => { const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType); const findInfiniteScroll = () => wrapper.findComponent(GlInfiniteScroll); + const defaultBranchInDropdown = () => findDropdownItems().at(0); + + const setMockResolvedValues = ({ availableBranches, currentBranch, lastCommitBranch }) => { + if (availableBranches) { + mockAvailableBranchQuery.mockResolvedValue(availableBranches); + } + + if (currentBranch) { + mockCurrentBranchQuery.mockResolvedValue(currentBranch); + } + + mockLastCommitBranchQuery.mockResolvedValue(lastCommitBranch || ''); + }; beforeEach(() => { mockAvailableBranchQuery = jest.fn(); + mockCurrentBranchQuery = jest.fn(); + mockLastCommitBranchQuery = jest.fn(); }); afterEach(() => { wrapper.destroy(); }); + const testErrorHandling = () => { + expect(wrapper.emitted('showError')).toBeDefined(); + expect(wrapper.emitted('showError')[0]).toEqual([ + { + reasons: [wrapper.vm.$options.i18n.fetchError], + type: DEFAULT_FAILURE, + }, + ]); + }; + describe('when querying for the first time', () => { beforeEach(() => { createComponentWithApollo(); @@ -111,7 +145,10 @@ describe('Pipeline editor branch switcher', () => { describe('after querying', () => { beforeEach(async () => { - mockAvailableBranchQuery.mockResolvedValue(mockProjectBranches); + setMockResolvedValues({ + availableBranches: mockProjectBranches, + currentBranch: mockDefaultBranch, + }); createComponentWithApollo(mount); await waitForPromises(); }); @@ -126,10 +163,8 @@ describe('Pipeline editor branch switcher', () => { }); it('renders current branch with a check mark', () => { - const defaultBranchInDropdown = findDropdownItems().at(0); - - expect(defaultBranchInDropdown.text()).toBe(mockDefaultBranch); - expect(defaultBranchInDropdown.props('isChecked')).toBe(true); + expect(defaultBranchInDropdown().text()).toBe(mockDefaultBranch); + expect(defaultBranchInDropdown().props('isChecked')).toBe(true); }); it('does not render check mark for other branches', () => { @@ -142,7 +177,10 @@ describe('Pipeline editor branch switcher', () => { describe('on fetch error', () => { beforeEach(async () => { - mockAvailableBranchQuery.mockResolvedValue(new Error()); + setMockResolvedValues({ + availableBranches: new Error(), + currentBranch: mockDefaultBranch, + }); createComponentWithApollo(); await waitForPromises(); }); @@ -152,20 +190,17 @@ describe('Pipeline editor branch switcher', () => { }); it('shows an error message', () => { - expect(wrapper.emitted('showError')).toBeDefined(); - expect(wrapper.emitted('showError')[0]).toEqual([ - { - reasons: [wrapper.vm.$options.i18n.fetchError], - type: DEFAULT_FAILURE, - }, - ]); + testErrorHandling(); }); }); describe('when switching branches', () => { beforeEach(async () => { jest.spyOn(window.history, 'pushState').mockImplementation(() => {}); - mockAvailableBranchQuery.mockResolvedValue(mockProjectBranches); + setMockResolvedValues({ + availableBranches: mockProjectBranches, + currentBranch: mockDefaultBranch, + }); createComponentWithApollo(mount); await waitForPromises(); }); @@ -212,14 +247,32 @@ describe('Pipeline editor branch switcher', () => { describe('when searching', () => { beforeEach(async () => { - mockAvailableBranchQuery.mockResolvedValue(mockProjectBranches); + setMockResolvedValues({ + availableBranches: mockProjectBranches, + currentBranch: mockDefaultBranch, + }); createComponentWithApollo(mount); await waitForPromises(); + }); + + afterEach(() => { + mockAvailableBranchQuery.mockClear(); + }); + + it('shows error message on fetch error', async () => { + mockAvailableBranchQuery.mockResolvedValue(new Error()); + + findSearchBox().vm.$emit('input', 'te'); + await waitForPromises(); - mockAvailableBranchQuery.mockResolvedValue(mockSearchBranches); + testErrorHandling(); }); describe('with a search term', () => { + beforeEach(async () => { + mockAvailableBranchQuery.mockResolvedValue(mockSearchBranches); + }); + it('calls query with correct variables', async () => { findSearchBox().vm.$emit('input', 'te'); await waitForPromises(); @@ -253,6 +306,7 @@ describe('Pipeline editor branch switcher', () => { describe('without a search term', () => { beforeEach(async () => { + mockAvailableBranchQuery.mockResolvedValue(mockSearchBranches); findSearchBox().vm.$emit('input', 'te'); await waitForPromises(); @@ -296,7 +350,10 @@ describe('Pipeline editor branch switcher', () => { describe('when scrolling to the bottom of the list', () => { beforeEach(async () => { - mockAvailableBranchQuery.mockResolvedValue(mockProjectBranches); + setMockResolvedValues({ + availableBranches: mockProjectBranches, + currentBranch: mockDefaultBranch, + }); createComponentWithApollo(); await waitForPromises(); }); @@ -326,6 +383,15 @@ describe('Pipeline editor branch switcher', () => { searchPattern: '*', }); }); + + it('shows error message on fetch error', async () => { + mockAvailableBranchQuery.mockResolvedValue(new Error()); + + findInfiniteScroll().vm.$emit('bottomReached'); + await waitForPromises(); + + testErrorHandling(); + }); }); describe('when search term exists', () => { @@ -343,4 +409,35 @@ describe('Pipeline editor branch switcher', () => { }); }); }); + + describe('when committing a new branch', () => { + const createNewBranch = async () => { + setMockResolvedValues({ + currentBranch: mockNewBranch, + lastCommitBranch: mockNewBranch, + }); + await wrapper.vm.$apollo.queries.currentBranch.refetch(); + await wrapper.vm.$apollo.queries.lastCommitBranch.refetch(); + }; + + beforeEach(async () => { + setMockResolvedValues({ + availableBranches: mockProjectBranches, + currentBranch: mockDefaultBranch, + }); + createComponentWithApollo(mount); + await waitForPromises(); + await createNewBranch(); + }); + + it('sets new branch as current branch', () => { + expect(defaultBranchInDropdown().text()).toBe(mockNewBranch); + expect(defaultBranchInDropdown().props('isChecked')).toBe(true); + }); + + it('adds new branch to branch switcher', () => { + expect(defaultBranchInDropdown().text()).toBe(mockNewBranch); + expect(findDropdownItems()).toHaveLength(mockTotalBranchResults + 1); + }); + }); }); -- cgit v1.2.1