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/ci/pipeline_editor/components/editor')
-rw-r--r--spec/frontend/ci/pipeline_editor/components/editor/ci_config_merged_preview_spec.js69
-rw-r--r--spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js115
-rw-r--r--spec/frontend/ci/pipeline_editor/components/editor/text_editor_spec.js134
3 files changed, 318 insertions, 0 deletions
diff --git a/spec/frontend/ci/pipeline_editor/components/editor/ci_config_merged_preview_spec.js b/spec/frontend/ci/pipeline_editor/components/editor/ci_config_merged_preview_spec.js
new file mode 100644
index 00000000000..2a2bc2547cc
--- /dev/null
+++ b/spec/frontend/ci/pipeline_editor/components/editor/ci_config_merged_preview_spec.js
@@ -0,0 +1,69 @@
+import { GlIcon } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+
+import { EDITOR_READY_EVENT } from '~/editor/constants';
+import CiConfigMergedPreview from '~/ci/pipeline_editor/components/editor/ci_config_merged_preview.vue';
+import { mockLintResponse, mockCiConfigPath } from '../../mock_data';
+
+describe('Text editor component', () => {
+ let wrapper;
+
+ const MockSourceEditor = {
+ template: '<div/>',
+ props: ['value', 'fileName', 'editorOptions'],
+ mounted() {
+ this.$emit(EDITOR_READY_EVENT);
+ },
+ };
+
+ const createComponent = ({ props = {} } = {}) => {
+ wrapper = shallowMount(CiConfigMergedPreview, {
+ propsData: {
+ ciConfigData: mockLintResponse,
+ ...props,
+ },
+ provide: {
+ ciConfigPath: mockCiConfigPath,
+ },
+ stubs: {
+ SourceEditor: MockSourceEditor,
+ },
+ });
+ };
+
+ const findIcon = () => wrapper.findComponent(GlIcon);
+ const findEditor = () => wrapper.findComponent(MockSourceEditor);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when status is valid', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('shows an information message that the section is not editable', () => {
+ expect(findIcon().exists()).toBe(true);
+ expect(wrapper.text()).toContain(wrapper.vm.$options.i18n.viewOnlyMessage);
+ });
+
+ it('contains an editor', () => {
+ expect(findEditor().exists()).toBe(true);
+ });
+
+ it('editor contains the value provided', () => {
+ expect(findEditor().props('value')).toBe(mockLintResponse.mergedYaml);
+ });
+
+ it('editor is configured for the CI config path', () => {
+ expect(findEditor().props('fileName')).toBe(mockCiConfigPath);
+ });
+
+ it('editor is readonly', () => {
+ expect(findEditor().props('editorOptions')).toMatchObject({
+ readOnly: true,
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js b/spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js
new file mode 100644
index 00000000000..d7f0ce838d6
--- /dev/null
+++ b/spec/frontend/ci/pipeline_editor/components/editor/ci_editor_header_spec.js
@@ -0,0 +1,115 @@
+import { shallowMount } from '@vue/test-utils';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
+import CiEditorHeader from '~/ci/pipeline_editor/components/editor/ci_editor_header.vue';
+import {
+ pipelineEditorTrackingOptions,
+ TEMPLATE_REPOSITORY_URL,
+} from '~/ci/pipeline_editor/constants';
+
+describe('CI Editor Header', () => {
+ let wrapper;
+ let trackingSpy = null;
+
+ const createComponent = ({ showDrawer = false } = {}) => {
+ wrapper = extendedWrapper(
+ shallowMount(CiEditorHeader, {
+ propsData: {
+ showDrawer,
+ },
+ }),
+ );
+ };
+
+ const findLinkBtn = () => wrapper.findByTestId('template-repo-link');
+ const findHelpBtn = () => wrapper.findByTestId('drawer-toggle');
+
+ afterEach(() => {
+ wrapper.destroy();
+ unmockTracking();
+ });
+
+ const testTracker = async (element, expectedAction) => {
+ const { label } = pipelineEditorTrackingOptions;
+
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+ await element.vm.$emit('click');
+
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, expectedAction, {
+ label,
+ });
+ };
+
+ describe('link button', () => {
+ beforeEach(() => {
+ createComponent();
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+ });
+
+ it('finds the browse template button', () => {
+ expect(findLinkBtn().exists()).toBe(true);
+ });
+
+ it('contains the link to the template repo', () => {
+ expect(findLinkBtn().attributes('href')).toBe(TEMPLATE_REPOSITORY_URL);
+ });
+
+ it('has the external-link icon', () => {
+ expect(findLinkBtn().props('icon')).toBe('external-link');
+ });
+
+ it('tracks the click on the browse button', async () => {
+ const { browseTemplates } = pipelineEditorTrackingOptions.actions;
+
+ testTracker(findLinkBtn(), browseTemplates);
+ });
+ });
+
+ describe('help button', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('finds the help button', () => {
+ expect(findHelpBtn().exists()).toBe(true);
+ });
+
+ it('has the information-o icon', () => {
+ expect(findHelpBtn().props('icon')).toBe('information-o');
+ });
+
+ describe('when pipeline editor drawer is closed', () => {
+ beforeEach(() => {
+ createComponent({ showDrawer: false });
+ });
+
+ it('emits open drawer event when clicked', () => {
+ expect(wrapper.emitted('open-drawer')).toBeUndefined();
+
+ findHelpBtn().vm.$emit('click');
+
+ expect(wrapper.emitted('open-drawer')).toHaveLength(1);
+ });
+
+ it('tracks open help drawer action', async () => {
+ const { actions } = pipelineEditorTrackingOptions;
+
+ testTracker(findHelpBtn(), actions.openHelpDrawer);
+ });
+ });
+
+ describe('when pipeline editor drawer is open', () => {
+ beforeEach(() => {
+ createComponent({ showDrawer: true });
+ });
+
+ it('emits close drawer event when clicked', () => {
+ expect(wrapper.emitted('close-drawer')).toBeUndefined();
+
+ findHelpBtn().vm.$emit('click');
+
+ expect(wrapper.emitted('close-drawer')).toHaveLength(1);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/ci/pipeline_editor/components/editor/text_editor_spec.js b/spec/frontend/ci/pipeline_editor/components/editor/text_editor_spec.js
new file mode 100644
index 00000000000..63e23c41263
--- /dev/null
+++ b/spec/frontend/ci/pipeline_editor/components/editor/text_editor_spec.js
@@ -0,0 +1,134 @@
+import { shallowMount } from '@vue/test-utils';
+
+import { EDITOR_READY_EVENT } from '~/editor/constants';
+import { SOURCE_EDITOR_DEBOUNCE } from '~/ci/pipeline_editor/constants';
+import TextEditor from '~/ci/pipeline_editor/components/editor/text_editor.vue';
+import {
+ mockCiConfigPath,
+ mockCiYml,
+ mockCommitSha,
+ mockProjectPath,
+ mockProjectNamespace,
+ mockDefaultBranch,
+} from '../../mock_data';
+
+describe('Pipeline Editor | Text editor component', () => {
+ let wrapper;
+
+ let editorReadyListener;
+ let mockUse;
+ let mockRegisterCiSchema;
+ let mockEditorInstance;
+ let editorInstanceDetail;
+
+ const MockSourceEditor = {
+ template: '<div/>',
+ props: ['value', 'fileName', 'editorOptions', 'debounceValue'],
+ };
+
+ const createComponent = (glFeatures = {}, mountFn = shallowMount) => {
+ wrapper = mountFn(TextEditor, {
+ provide: {
+ projectPath: mockProjectPath,
+ projectNamespace: mockProjectNamespace,
+ ciConfigPath: mockCiConfigPath,
+ defaultBranch: mockDefaultBranch,
+ glFeatures,
+ },
+ propsData: {
+ commitSha: mockCommitSha,
+ },
+ attrs: {
+ value: mockCiYml,
+ },
+ listeners: {
+ [EDITOR_READY_EVENT]: editorReadyListener,
+ },
+ stubs: {
+ SourceEditor: MockSourceEditor,
+ },
+ });
+ };
+
+ const findEditor = () => wrapper.findComponent(MockSourceEditor);
+
+ beforeEach(() => {
+ editorReadyListener = jest.fn();
+ mockUse = jest.fn();
+ mockRegisterCiSchema = jest.fn();
+ mockEditorInstance = {
+ use: mockUse,
+ registerCiSchema: mockRegisterCiSchema,
+ };
+ editorInstanceDetail = {
+ detail: {
+ instance: mockEditorInstance,
+ },
+ };
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+
+ mockUse.mockClear();
+ mockRegisterCiSchema.mockClear();
+ });
+
+ describe('template', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('contains an editor', () => {
+ expect(findEditor().exists()).toBe(true);
+ });
+
+ it('editor contains the value provided', () => {
+ expect(findEditor().props('value')).toBe(mockCiYml);
+ });
+
+ it('editor is configured for the CI config path', () => {
+ expect(findEditor().props('fileName')).toBe(mockCiConfigPath);
+ });
+
+ it('passes down editor configs options', () => {
+ expect(findEditor().props('editorOptions')).toEqual({ quickSuggestions: true });
+ });
+
+ it('passes down editor debounce value', () => {
+ expect(findEditor().props('debounceValue')).toBe(SOURCE_EDITOR_DEBOUNCE);
+ });
+
+ it('bubbles up events', () => {
+ findEditor().vm.$emit(EDITOR_READY_EVENT, editorInstanceDetail);
+
+ expect(editorReadyListener).toHaveBeenCalled();
+ });
+ });
+
+ describe('CI schema', () => {
+ describe('when `schema_linting` feature flag is on', () => {
+ beforeEach(() => {
+ createComponent({ schemaLinting: true });
+ findEditor().vm.$emit(EDITOR_READY_EVENT, editorInstanceDetail);
+ });
+
+ it('configures editor with syntax highlight', () => {
+ expect(mockUse).toHaveBeenCalledTimes(1);
+ expect(mockRegisterCiSchema).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('when `schema_linting` feature flag is off', () => {
+ beforeEach(() => {
+ createComponent();
+ findEditor().vm.$emit(EDITOR_READY_EVENT, editorInstanceDetail);
+ });
+
+ it('does not call the register CI schema function', () => {
+ expect(mockUse).not.toHaveBeenCalled();
+ expect(mockRegisterCiSchema).not.toHaveBeenCalled();
+ });
+ });
+ });
+});