Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/pipeline_editor/components')
-rw-r--r--spec/frontend/pipeline_editor/components/commit/commit_form_spec.js4
-rw-r--r--spec/frontend/pipeline_editor/components/file-nav/pipeline_editor_file_nav_spec.js133
-rw-r--r--spec/frontend/pipeline_editor/components/file-tree/container_spec.js138
-rw-r--r--spec/frontend/pipeline_editor/components/file-tree/file_item_spec.js52
-rw-r--r--spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js2
-rw-r--r--spec/frontend/pipeline_editor/components/popovers/file_tree_popover_spec.js56
-rw-r--r--spec/frontend/pipeline_editor/components/popovers/walkthrough_popover_spec.js (renamed from spec/frontend/pipeline_editor/components/walkthrough_popover_spec.js)2
7 files changed, 379 insertions, 8 deletions
diff --git a/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js b/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js
index 59bd71b0e60..bec6c2a8d0c 100644
--- a/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js
+++ b/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js
@@ -71,7 +71,7 @@ describe('Pipeline Editor | Commit Form', () => {
expect(wrapper.emitted('submit')[0]).toEqual([
{
message: mockCommitMessage,
- targetBranch: mockDefaultBranch,
+ sourceBranch: mockDefaultBranch,
openMergeRequest: false,
},
]);
@@ -127,7 +127,7 @@ describe('Pipeline Editor | Commit Form', () => {
expect(wrapper.emitted('submit')[0]).toEqual([
{
message: anotherMessage,
- targetBranch: anotherBranch,
+ sourceBranch: anotherBranch,
openMergeRequest: true,
},
]);
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
index e24de832d6d..a61796dbed2 100644
--- 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
@@ -1,19 +1,58 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
import { shallowMount } from '@vue/test-utils';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import createMockApollo from 'helpers/mock_apollo_helper';
import BranchSwitcher from '~/pipeline_editor/components/file_nav/branch_switcher.vue';
import PipelineEditorFileNav from '~/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue';
+import FileTreePopover from '~/pipeline_editor/components/popovers/file_tree_popover.vue';
+import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.query.graphql';
+import {
+ EDITOR_APP_STATUS_EMPTY,
+ EDITOR_APP_STATUS_LOADING,
+ EDITOR_APP_STATUS_VALID,
+} from '~/pipeline_editor/constants';
+
+Vue.use(VueApollo);
describe('Pipeline editor file nav', () => {
let wrapper;
- const createComponent = ({ provide = {} } = {}) => {
- wrapper = shallowMount(PipelineEditorFileNav, {
- provide: {
- ...provide,
+ const mockApollo = createMockApollo();
+
+ const createComponent = ({
+ appStatus = EDITOR_APP_STATUS_VALID,
+ isNewCiConfigFile = false,
+ pipelineEditorFileTree = false,
+ } = {}) => {
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getAppStatus,
+ data: {
+ app: {
+ __typename: 'PipelineEditorApp',
+ status: appStatus,
+ },
},
});
+
+ wrapper = extendedWrapper(
+ shallowMount(PipelineEditorFileNav, {
+ apolloProvider: mockApollo,
+ provide: {
+ glFeatures: {
+ pipelineEditorFileTree,
+ },
+ },
+ propsData: {
+ isNewCiConfigFile,
+ },
+ }),
+ );
};
const findBranchSwitcher = () => wrapper.findComponent(BranchSwitcher);
+ const findFileTreeBtn = () => wrapper.findByTestId('file-tree-toggle');
+ const findPopoverContainer = () => wrapper.findComponent(FileTreePopover);
afterEach(() => {
wrapper.destroy();
@@ -27,5 +66,91 @@ describe('Pipeline editor file nav', () => {
it('renders the branch switcher', () => {
expect(findBranchSwitcher().exists()).toBe(true);
});
+
+ it('does not render the file tree button', () => {
+ expect(findFileTreeBtn().exists()).toBe(false);
+ });
+
+ it('does not render the file tree popover', () => {
+ expect(findPopoverContainer().exists()).toBe(false);
+ });
+ });
+
+ describe('with pipelineEditorFileTree feature flag ON', () => {
+ describe('when editor is in the empty state', () => {
+ beforeEach(() => {
+ createComponent({
+ appStatus: EDITOR_APP_STATUS_EMPTY,
+ isNewCiConfigFile: false,
+ pipelineEditorFileTree: true,
+ });
+ });
+
+ it('does not render the file tree button', () => {
+ expect(findFileTreeBtn().exists()).toBe(false);
+ });
+
+ it('does not render the file tree popover', () => {
+ expect(findPopoverContainer().exists()).toBe(false);
+ });
+ });
+
+ describe('when user is about to create their config file for the first time', () => {
+ beforeEach(() => {
+ createComponent({
+ appStatus: EDITOR_APP_STATUS_VALID,
+ isNewCiConfigFile: true,
+ pipelineEditorFileTree: true,
+ });
+ });
+
+ it('does not render the file tree button', () => {
+ expect(findFileTreeBtn().exists()).toBe(false);
+ });
+
+ it('does not render the file tree popover', () => {
+ expect(findPopoverContainer().exists()).toBe(false);
+ });
+ });
+
+ describe('when app is in a global loading state', () => {
+ it('renders the file tree button with a loading icon', () => {
+ createComponent({
+ appStatus: EDITOR_APP_STATUS_LOADING,
+ isNewCiConfigFile: false,
+ pipelineEditorFileTree: true,
+ });
+
+ expect(findFileTreeBtn().exists()).toBe(true);
+ expect(findFileTreeBtn().attributes('loading')).toBe('true');
+ });
+ });
+
+ describe('when editor has a non-empty config file open', () => {
+ beforeEach(() => {
+ createComponent({
+ appStatus: EDITOR_APP_STATUS_VALID,
+ isNewCiConfigFile: false,
+ pipelineEditorFileTree: true,
+ });
+ });
+
+ it('renders the file tree button', () => {
+ expect(findFileTreeBtn().exists()).toBe(true);
+ expect(findFileTreeBtn().props('icon')).toBe('file-tree');
+ });
+
+ it('renders the file tree popover', () => {
+ expect(findPopoverContainer().exists()).toBe(true);
+ });
+
+ it('file tree button emits toggle-file-tree event', () => {
+ expect(wrapper.emitted('toggle-file-tree')).toBe(undefined);
+
+ findFileTreeBtn().vm.$emit('click');
+
+ expect(wrapper.emitted('toggle-file-tree')).toHaveLength(1);
+ });
+ });
});
});
diff --git a/spec/frontend/pipeline_editor/components/file-tree/container_spec.js b/spec/frontend/pipeline_editor/components/file-tree/container_spec.js
new file mode 100644
index 00000000000..04a93e8db25
--- /dev/null
+++ b/spec/frontend/pipeline_editor/components/file-tree/container_spec.js
@@ -0,0 +1,138 @@
+import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import { GlAlert } from '@gitlab/ui';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import { createMockDirective } from 'helpers/vue_mock_directive';
+import PipelineEditorFileTreeContainer from '~/pipeline_editor/components/file_tree/container.vue';
+import PipelineEditorFileTreeItem from '~/pipeline_editor/components/file_tree/file_item.vue';
+import { FILE_TREE_TIP_DISMISSED_KEY } from '~/pipeline_editor/constants';
+import { mockCiConfigPath, mockIncludes, mockIncludesHelpPagePath } from '../../mock_data';
+
+describe('Pipeline editor file nav', () => {
+ let wrapper;
+
+ const createComponent = ({ includes = mockIncludes, stubs } = {}) => {
+ wrapper = extendedWrapper(
+ shallowMount(PipelineEditorFileTreeContainer, {
+ provide: {
+ ciConfigPath: mockCiConfigPath,
+ includesHelpPagePath: mockIncludesHelpPagePath,
+ },
+ propsData: {
+ includes,
+ },
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
+ stubs,
+ }),
+ );
+ };
+
+ const findTip = () => wrapper.findComponent(GlAlert);
+ const findCurrentConfigFilename = () => wrapper.findByTestId('current-config-filename');
+ const fileTreeItems = () => wrapper.findAll(PipelineEditorFileTreeItem);
+
+ afterEach(() => {
+ localStorage.clear();
+ wrapper.destroy();
+ });
+
+ describe('template', () => {
+ beforeEach(() => {
+ createComponent({ stubs: { GlAlert } });
+ });
+
+ it('renders config file as a file item', () => {
+ expect(findCurrentConfigFilename().text()).toBe(mockCiConfigPath);
+ });
+ });
+
+ describe('when includes list is empty', () => {
+ describe('when dismiss state is not saved in local storage', () => {
+ beforeEach(() => {
+ createComponent({
+ includes: [],
+ stubs: { GlAlert },
+ });
+ });
+
+ it('does not render filenames', () => {
+ expect(fileTreeItems().exists()).toBe(false);
+ });
+
+ it('renders alert tip', async () => {
+ expect(findTip().exists()).toBe(true);
+ });
+
+ it('renders learn more link', async () => {
+ expect(findTip().props('secondaryButtonLink')).toBe(mockIncludesHelpPagePath);
+ });
+
+ it('can dismiss the tip', async () => {
+ expect(findTip().exists()).toBe(true);
+
+ findTip().vm.$emit('dismiss');
+ await nextTick();
+
+ expect(findTip().exists()).toBe(false);
+ });
+ });
+
+ describe('when dismiss state is saved in local storage', () => {
+ beforeEach(() => {
+ localStorage.setItem(FILE_TREE_TIP_DISMISSED_KEY, 'true');
+ createComponent({
+ includes: [],
+ stubs: { GlAlert },
+ });
+ });
+
+ it('does not render alert tip', async () => {
+ expect(findTip().exists()).toBe(false);
+ });
+ });
+
+ describe('when component receives new props with includes files', () => {
+ beforeEach(() => {
+ createComponent({ includes: [] });
+ });
+
+ it('hides tip and renders list of files', async () => {
+ expect(findTip().exists()).toBe(true);
+ expect(fileTreeItems()).toHaveLength(0);
+
+ await wrapper.setProps({ includes: mockIncludes });
+
+ expect(findTip().exists()).toBe(false);
+ expect(fileTreeItems()).toHaveLength(mockIncludes.length);
+ });
+ });
+ });
+
+ describe('when there are includes files', () => {
+ beforeEach(() => {
+ createComponent({ stubs: { GlAlert } });
+ });
+
+ it('does not render alert tip', () => {
+ expect(findTip().exists()).toBe(false);
+ });
+
+ it('renders the list of files', () => {
+ expect(fileTreeItems()).toHaveLength(mockIncludes.length);
+ });
+
+ describe('when component receives new props with empty includes', () => {
+ it('shows tip and does not render list of files', async () => {
+ expect(findTip().exists()).toBe(false);
+ expect(fileTreeItems()).toHaveLength(mockIncludes.length);
+
+ await wrapper.setProps({ includes: [] });
+
+ expect(findTip().exists()).toBe(true);
+ expect(fileTreeItems()).toHaveLength(0);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_editor/components/file-tree/file_item_spec.js b/spec/frontend/pipeline_editor/components/file-tree/file_item_spec.js
new file mode 100644
index 00000000000..f12ac14c6be
--- /dev/null
+++ b/spec/frontend/pipeline_editor/components/file-tree/file_item_spec.js
@@ -0,0 +1,52 @@
+import { GlLink } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import FileIcon from '~/vue_shared/components/file_icon.vue';
+import PipelineEditorFileTreeItem from '~/pipeline_editor/components/file_tree/file_item.vue';
+import { mockIncludesWithBlob, mockDefaultIncludes } from '../../mock_data';
+
+describe('Pipeline editor file nav', () => {
+ let wrapper;
+
+ const createComponent = ({ file = mockDefaultIncludes } = {}) => {
+ wrapper = shallowMount(PipelineEditorFileTreeItem, {
+ propsData: {
+ file,
+ },
+ });
+ };
+
+ const fileIcon = () => wrapper.findComponent(FileIcon);
+ const link = () => wrapper.findComponent(GlLink);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('template', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders file icon', () => {
+ expect(fileIcon().exists()).toBe(true);
+ });
+
+ it('renders file name', () => {
+ expect(wrapper.text()).toBe(mockDefaultIncludes.location);
+ });
+
+ it('links to raw path by default', () => {
+ expect(link().attributes('href')).toBe(mockDefaultIncludes.raw);
+ });
+ });
+
+ describe('when file has blob link', () => {
+ beforeEach(() => {
+ createComponent({ file: mockIncludesWithBlob });
+ });
+
+ it('links to blob path', () => {
+ expect(link().attributes('href')).toBe(mockIncludesWithBlob.blob);
+ });
+ });
+});
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 6dffb7e5470..d159a20a8d6 100644
--- a/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js
+++ b/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js
@@ -3,7 +3,7 @@ import { shallowMount, mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import setWindowLocation from 'helpers/set_window_location_helper';
import CiConfigMergedPreview from '~/pipeline_editor/components/editor/ci_config_merged_preview.vue';
-import WalkthroughPopover from '~/pipeline_editor/components/walkthrough_popover.vue';
+import WalkthroughPopover from '~/pipeline_editor/components/popovers/walkthrough_popover.vue';
import CiLint from '~/pipeline_editor/components/lint/ci_lint.vue';
import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tabs.vue';
import EditorTab from '~/pipeline_editor/components/ui/editor_tab.vue';
diff --git a/spec/frontend/pipeline_editor/components/popovers/file_tree_popover_spec.js b/spec/frontend/pipeline_editor/components/popovers/file_tree_popover_spec.js
new file mode 100644
index 00000000000..98ce3f6ea40
--- /dev/null
+++ b/spec/frontend/pipeline_editor/components/popovers/file_tree_popover_spec.js
@@ -0,0 +1,56 @@
+import { nextTick } from 'vue';
+import { GlLink, GlPopover, GlSprintf } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import FileTreePopover from '~/pipeline_editor/components/popovers/file_tree_popover.vue';
+import { FILE_TREE_POPOVER_DISMISSED_KEY } from '~/pipeline_editor/constants';
+import { mockIncludesHelpPagePath } from '../../mock_data';
+
+describe('FileTreePopover component', () => {
+ let wrapper;
+
+ const findPopover = () => wrapper.findComponent(GlPopover);
+ const findLink = () => findPopover().findComponent(GlLink);
+
+ const createComponent = ({ stubs } = {}) => {
+ wrapper = shallowMount(FileTreePopover, {
+ provide: {
+ includesHelpPagePath: mockIncludesHelpPagePath,
+ },
+ stubs,
+ });
+ };
+
+ afterEach(() => {
+ localStorage.clear();
+ wrapper.destroy();
+ });
+
+ describe('default', () => {
+ beforeEach(async () => {
+ createComponent({ stubs: { GlSprintf } });
+ });
+
+ it('renders dismissable popover', async () => {
+ expect(findPopover().exists()).toBe(true);
+
+ findPopover().vm.$emit('close-button-clicked');
+ await nextTick();
+
+ expect(findPopover().exists()).toBe(false);
+ });
+
+ it('renders learn more link', () => {
+ expect(findLink().exists()).toBe(true);
+ expect(findLink().attributes('href')).toBe(mockIncludesHelpPagePath);
+ });
+ });
+
+ describe('when popover has already been dismissed before', () => {
+ it('does not render popover', async () => {
+ localStorage.setItem(FILE_TREE_POPOVER_DISMISSED_KEY, 'true');
+ createComponent();
+
+ expect(findPopover().exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_editor/components/walkthrough_popover_spec.js b/spec/frontend/pipeline_editor/components/popovers/walkthrough_popover_spec.js
index a9ce89ff521..8d172a8462a 100644
--- a/spec/frontend/pipeline_editor/components/walkthrough_popover_spec.js
+++ b/spec/frontend/pipeline_editor/components/popovers/walkthrough_popover_spec.js
@@ -1,6 +1,6 @@
import { mount, shallowMount } from '@vue/test-utils';
import Vue from 'vue';
-import WalkthroughPopover from '~/pipeline_editor/components/walkthrough_popover.vue';
+import WalkthroughPopover from '~/pipeline_editor/components/popovers/walkthrough_popover.vue';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
Vue.config.ignoredElements = ['gl-emoji'];