diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-09 21:09:24 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-09 21:09:24 +0300 |
commit | b19efd72743e22fd3b340b3c2906ba113e1390de (patch) | |
tree | 6afb0cff9382cf949654608368731ed4883a0678 /spec/frontend/pipeline_editor | |
parent | 9ea69b43c3502c4c63e6d47da40786875197fcf3 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/pipeline_editor')
5 files changed, 210 insertions, 0 deletions
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 new file mode 100644 index 00000000000..fa937100982 --- /dev/null +++ b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js @@ -0,0 +1,123 @@ +import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui'; +import { shallowMount, createLocalVue } from '@vue/test-utils'; +import VueApollo from 'vue-apollo'; +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 { mockDefaultBranch, mockProjectBranches, mockProjectFullPath } from '../../mock_data'; + +const localVue = createLocalVue(); +localVue.use(VueApollo); + +describe('Pipeline editor branch switcher', () => { + let wrapper; + let mockApollo; + let mockAvailableBranchQuery; + + const createComponentWithApollo = () => { + const resolvers = { + Query: { + project: mockAvailableBranchQuery, + }, + }; + + mockApollo = createMockApollo([], resolvers); + wrapper = shallowMount(BranchSwitcher, { + localVue, + apolloProvider: mockApollo, + provide: { + projectFullPath: mockProjectFullPath, + }, + data() { + return { + currentBranch: mockDefaultBranch, + }; + }, + }); + }; + + const findDropdown = () => wrapper.findComponent(GlDropdown); + const findDropdownItems = () => wrapper.findAll(GlDropdownItem); + + beforeEach(() => { + mockAvailableBranchQuery = jest.fn(); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('while querying', () => { + beforeEach(() => { + createComponentWithApollo(); + }); + + it('does not render dropdown', () => { + expect(findDropdown().exists()).toBe(false); + }); + }); + + describe('after querying', () => { + beforeEach(async () => { + mockAvailableBranchQuery.mockResolvedValue(mockProjectBranches); + createComponentWithApollo(); + await waitForPromises(); + }); + + it('query is called with correct variables', async () => { + expect(mockAvailableBranchQuery).toHaveBeenCalledTimes(1); + expect(mockAvailableBranchQuery).toHaveBeenCalledWith( + expect.anything(), + { + fullPath: mockProjectFullPath, + }, + expect.anything(), + expect.anything(), + ); + }); + + it('renders list of branches', () => { + expect(findDropdown().exists()).toBe(true); + expect(findDropdownItems()).toHaveLength(mockProjectBranches.repository.branches.length); + }); + + it('renders current branch at the top of the list with a check mark', () => { + const firstDropdownItem = findDropdownItems().at(0); + const icon = firstDropdownItem.findComponent(GlIcon); + + expect(firstDropdownItem.text()).toBe(mockDefaultBranch); + expect(icon.exists()).toBe(true); + expect(icon.props('name')).toBe('check'); + }); + + it('does not render check mark for other branches', () => { + const secondDropdownItem = findDropdownItems().at(1); + const icon = secondDropdownItem.findComponent(GlIcon); + + expect(icon.classes()).toContain('gl-visibility-hidden'); + }); + }); + + describe('on fetch error', () => { + beforeEach(async () => { + mockAvailableBranchQuery.mockResolvedValue(new Error()); + createComponentWithApollo(); + await waitForPromises(); + }); + + it('does not render dropdown', () => { + expect(findDropdown().exists()).toBe(false); + }); + + 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, + }, + ]); + }); + }); +}); diff --git a/spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js b/spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js new file mode 100644 index 00000000000..94a0a7d14ee --- /dev/null +++ b/spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js @@ -0,0 +1,49 @@ +import { shallowMount } from '@vue/test-utils'; +import BranchSwitcher from '~/pipeline_editor/components/file_nav/branch_switcher.vue'; +import PipelineEditorFileNav from '~/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue'; + +describe('Pipeline editor file nav', () => { + let wrapper; + const mockProvide = { + glFeatures: { + pipelineEditorBranchSwitcher: true, + }, + }; + + const createComponent = ({ provide = {} } = {}) => { + wrapper = shallowMount(PipelineEditorFileNav, { + provide: { + ...mockProvide, + ...provide, + }, + }); + }; + + const findBranchSwitcher = () => wrapper.findComponent(BranchSwitcher); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('template', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders the branch switcher', () => { + expect(findBranchSwitcher().exists()).toBe(true); + }); + }); + + describe('with branch switcher feature flag OFF', () => { + it('does not render the branch switcher', () => { + createComponent({ + provide: { + glFeatures: { pipelineEditorBranchSwitcher: false }, + }, + }); + + expect(findBranchSwitcher().exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/pipeline_editor/graphql/resolvers_spec.js b/spec/frontend/pipeline_editor/graphql/resolvers_spec.js index d39c0d80296..f0932fc55d3 100644 --- a/spec/frontend/pipeline_editor/graphql/resolvers_spec.js +++ b/spec/frontend/pipeline_editor/graphql/resolvers_spec.js @@ -9,6 +9,7 @@ import { mockDefaultBranch, mockLintResponse, mockProjectFullPath, + mockProjectBranches, } from '../mock_data'; jest.mock('~/api', () => { @@ -46,6 +47,23 @@ describe('~/pipeline_editor/graphql/resolvers', () => { await expect(result.rawData).resolves.toBe(mockCiYml); }); }); + + describe('project', () => { + it('resolves project data with type names', async () => { + const result = await resolvers.Query.project(); + + // eslint-disable-next-line no-underscore-dangle + expect(result.__typename).toBe('Project'); + }); + + it('resolves project with available list of branches', async () => { + const result = await resolvers.Query.project(); + + expect(result.repository.branches).toHaveLength( + mockProjectBranches.repository.branches.length, + ); + }); + }); }); describe('Mutation', () => { diff --git a/spec/frontend/pipeline_editor/mock_data.js b/spec/frontend/pipeline_editor/mock_data.js index 16d5ba0e714..7f651a42231 100644 --- a/spec/frontend/pipeline_editor/mock_data.js +++ b/spec/frontend/pipeline_editor/mock_data.js @@ -138,6 +138,20 @@ export const mergeUnwrappedCiConfig = (mergedConfig) => { }; }; +export const mockProjectBranches = { + __typename: 'Project', + repository: { + __typename: 'Repository', + branches: [ + { __typename: 'Branch', name: 'master' }, + { __typename: 'Branch', name: 'main' }, + { __typename: 'Branch', name: 'develop' }, + { __typename: 'Branch', name: 'production' }, + { __typename: 'Branch', name: 'test' }, + ], + }, +}; + export const mockProjectPipeline = { pipeline: { commitPath: '/-/commit/aabbccdd', diff --git a/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js index 43e22db1d44..a1e3d24acfa 100644 --- a/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js +++ b/spec/frontend/pipeline_editor/pipeline_editor_home_spec.js @@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; import CommitSection from '~/pipeline_editor/components/commit/commit_section.vue'; +import PipelineEditorFileNav from '~/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue'; import PipelineEditorHeader from '~/pipeline_editor/components/header/pipeline_editor_header.vue'; import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tabs.vue'; import { MERGED_TAB, VISUALIZE_TAB } from '~/pipeline_editor/constants'; @@ -27,6 +28,7 @@ describe('Pipeline editor home wrapper', () => { const findPipelineEditorHeader = () => wrapper.findComponent(PipelineEditorHeader); const findPipelineEditorTabs = () => wrapper.findComponent(PipelineEditorTabs); const findCommitSection = () => wrapper.findComponent(CommitSection); + const findFileNav = () => wrapper.findComponent(PipelineEditorFileNav); afterEach(() => { wrapper.destroy(); @@ -38,6 +40,10 @@ describe('Pipeline editor home wrapper', () => { createComponent(); }); + it('shows the file nav', () => { + expect(findFileNav().exists()).toBe(true); + }); + it('shows the pipeline editor header', () => { expect(findPipelineEditorHeader().exists()).toBe(true); }); |