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/blob/filepath_form/components')
-rw-r--r--spec/frontend/blob/filepath_form/components/filepath_form_spec.js70
-rw-r--r--spec/frontend/blob/filepath_form/components/mock_data.js57
-rw-r--r--spec/frontend/blob/filepath_form/components/template_selector_spec.js167
3 files changed, 294 insertions, 0 deletions
diff --git a/spec/frontend/blob/filepath_form/components/filepath_form_spec.js b/spec/frontend/blob/filepath_form/components/filepath_form_spec.js
new file mode 100644
index 00000000000..8a890cdc75a
--- /dev/null
+++ b/spec/frontend/blob/filepath_form/components/filepath_form_spec.js
@@ -0,0 +1,70 @@
+import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import { GlFormInput } from '@gitlab/ui';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import FilepathForm from '~/blob/filepath_form/components/filepath_form.vue';
+import TemplateSelector from '~/blob/filepath_form/components/template_selector.vue';
+import { Templates as TemplatesMock } from './mock_data';
+
+describe('Filepath Form component', () => {
+ let wrapper;
+
+ const findNavLinks = () => document.querySelector('.nav-links');
+ const findNavLinkWrite = () => findNavLinks().querySelector('#edit');
+ const findNavLinkPreview = () => findNavLinks().querySelector('#preview');
+
+ const findInput = () => wrapper.findComponent(GlFormInput);
+ const findTemplateSelector = () => wrapper.findComponent(TemplateSelector);
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(FilepathForm, {
+ propsData: {
+ templates: TemplatesMock,
+ inputOptions: {},
+ ...props,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ setHTMLFixture(`
+ <div class="file-editor">
+ <ul class="nav-links">
+ <a class="nav-link" id="edit" href="#editor">Write</a>
+ <a class="nav-link" id="preview" href="#preview">Preview</a>
+ </ul>
+ </div>
+ `);
+ createComponent();
+ });
+
+ afterEach(() => {
+ resetHTMLFixture();
+ });
+
+ it('renders input with correct attributes', () => {
+ createComponent({ inputOptions: { name: 'foo', value: 'bar' } });
+ expect(findInput().attributes()).toMatchObject({
+ name: 'foo',
+ value: 'bar',
+ });
+ });
+
+ describe('when write button is clicked', () => {
+ it('renders template selector', async () => {
+ findNavLinkWrite().click();
+ await nextTick();
+
+ expect(findTemplateSelector().exists()).toBe(true);
+ });
+ });
+
+ describe('when preview button is clicked', () => {
+ it('hides template selector', async () => {
+ findNavLinkPreview().click();
+ await nextTick();
+
+ expect(findTemplateSelector().exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/blob/filepath_form/components/mock_data.js b/spec/frontend/blob/filepath_form/components/mock_data.js
new file mode 100644
index 00000000000..fc19d6f1887
--- /dev/null
+++ b/spec/frontend/blob/filepath_form/components/mock_data.js
@@ -0,0 +1,57 @@
+export const SuggestCiYmlData = {
+ trackLabel: 'suggest_gitlab_ci_yml',
+ dismissKey: '10',
+ mergeRequestPath: 'mr_path',
+ humanAccess: 'owner',
+};
+
+export const Templates = {
+ licenses: {
+ Other: [
+ {
+ name: 'GNU Affero General Public License v3.0',
+ id: 'agpl-3.0',
+ key: 'agpl-3.0',
+ project_id: 10,
+ },
+ ],
+ Popular: [
+ {
+ name: 'Apache License 2.0',
+ id: 'apache-2.0',
+ key: 'apache-2.0',
+ project_id: 10,
+ },
+ ],
+ },
+ gitignore_names: {
+ Languages: [
+ {
+ name: 'Actionscript',
+ id: 'Actionscript',
+ key: 'Actionscript',
+ project_id: 10,
+ },
+ ],
+ },
+ gitlab_ci_ymls: {
+ General: [
+ {
+ name: '5-Minute-Production-App',
+ id: '5-Minute-Production-App',
+ key: '5-Minute-Production-App',
+ project_id: 10,
+ },
+ ],
+ },
+ dockerfile_names: {
+ General: [
+ {
+ name: 'Binary',
+ id: 'Binary',
+ key: 'Binary',
+ project_id: 10,
+ },
+ ],
+ },
+};
diff --git a/spec/frontend/blob/filepath_form/components/template_selector_spec.js b/spec/frontend/blob/filepath_form/components/template_selector_spec.js
new file mode 100644
index 00000000000..b1419320e1e
--- /dev/null
+++ b/spec/frontend/blob/filepath_form/components/template_selector_spec.js
@@ -0,0 +1,167 @@
+import { GlCollapsibleListbox } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import TemplateSelector from '~/blob/filepath_form/components/template_selector.vue';
+import SuggestGitlabCiYml from '~/blob/suggest_gitlab_ci_yml/components/popover.vue';
+import { Templates as TemplatesMock, SuggestCiYmlData as SuggestCiYmlDataMock } from './mock_data';
+
+describe('Template Selector component', () => {
+ let wrapper;
+
+ const findListbox = () => wrapper.findComponent(GlCollapsibleListbox);
+ const findSuggestCiYmlPopover = () => wrapper.findComponent(SuggestGitlabCiYml);
+ const findDisplayedTemplates = () =>
+ findListbox()
+ .props('items')
+ .reduce((acc, item) => [...acc, ...item.options], [])
+ .map((template) => template.value);
+
+ const getTemplateKeysFromMock = (key) =>
+ Object.values(TemplatesMock[key])
+ .reduce((acc, items) => [...acc, ...items], [])
+ .map((template) => template.key);
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(TemplateSelector, {
+ propsData: {
+ filename: '',
+ templates: TemplatesMock,
+ ...props,
+ },
+ });
+ };
+
+ describe('when filename input is empty', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('does not render listbox', () => {
+ expect(findListbox().exists()).toBe(false);
+ });
+
+ it('does not render suggest-ci-yml popover', () => {
+ expect(findSuggestCiYmlPopover().exists()).toBe(false);
+ });
+ });
+
+ describe.each`
+ filename | key
+ ${'LICENSE'} | ${'licenses'}
+ ${'Dockerfile'} | ${'dockerfile_names'}
+ ${'.gitignore'} | ${'gitignore_names'}
+ ${'.gitlab-ci.yml'} | ${'gitlab_ci_ymls'}
+ `('when filename is $filename', ({ filename, key }) => {
+ beforeEach(() => {
+ createComponent({ filename });
+ });
+
+ it('renders listbox with correct props', () => {
+ expect(findListbox().exists()).toBe(true);
+ expect(findListbox().props('toggleText')).toBe('Apply a template');
+ expect(findListbox().props('searchPlaceholder')).toBe('Filter');
+ expect(findDisplayedTemplates()).toEqual(getTemplateKeysFromMock(key));
+ });
+
+ it('does not render suggest-ci-yml popover', () => {
+ expect(findSuggestCiYmlPopover().exists()).toBe(false);
+ });
+ });
+
+ describe('when filename input is .gitlab-ci.yml with suggestCiYmlData prop', () => {
+ beforeEach(() => {
+ createComponent({ filename: '.gitlab-ci.yml', suggestCiYmlData: SuggestCiYmlDataMock });
+ });
+
+ it('renders listbox with correct props', () => {
+ expect(findListbox().exists()).toBe(true);
+ expect(findListbox().props('toggleText')).toBe('Apply a template');
+ expect(findListbox().props('searchPlaceholder')).toBe('Filter');
+ });
+
+ it('renders suggest-ci-yml popover', () => {
+ expect(findSuggestCiYmlPopover().exists()).toBe(true);
+ });
+ });
+
+ describe('has filename that matches template pattern', () => {
+ const filename = 'LICENSE';
+ const templates = TemplatesMock.licenses.Other;
+
+ describe('has initial template prop', () => {
+ const initialTemplate = TemplatesMock.licenses.Other[0];
+
+ beforeEach(() => {
+ createComponent({ filename, initialTemplate: initialTemplate.key });
+ });
+
+ it('renders listbox toggle button with selected template name', () => {
+ expect(findListbox().props('toggleText')).toBe(initialTemplate.name);
+ });
+
+ it('selected template is checked', () => {
+ expect(findListbox().props('selected')).toBe(initialTemplate.key);
+ });
+ });
+
+ describe('when template is selected', () => {
+ beforeEach(() => {
+ createComponent({ filename });
+ findListbox().vm.$emit('select', templates[0].key);
+ });
+
+ it('emit `selected` event with selected template', () => {
+ const licenseSelectorType = {
+ key: 'licenses',
+ name: 'LICENSE',
+ pattern: /^(.+\/)?(licen[sc]e|copying)($|\.)/i,
+ type: 'licenses',
+ };
+
+ const { template, type } = wrapper.emitted('selected')[0][0];
+ expect(template).toBe(templates[0]);
+ expect(type).toMatchObject(licenseSelectorType);
+ });
+
+ it('set loading state to true', () => {
+ expect(findListbox().props('loading')).toBe(true);
+ });
+
+ describe('when stopLoading callback from `selected` event is called', () => {
+ it('set loading state to false', async () => {
+ const { stopLoading } = wrapper.emitted('selected')[0][0];
+
+ stopLoading();
+ await nextTick();
+
+ expect(findListbox().props('loading')).toBe(false);
+ });
+ });
+ });
+
+ describe('when searching for filter', () => {
+ const searchTerm = 'GNU';
+
+ beforeEach(() => {
+ createComponent({ filename: 'LICENSE' });
+ findListbox().vm.$emit('search', searchTerm);
+ });
+
+ it('shows matching templates', () => {
+ const displayedTemplates = findDisplayedTemplates();
+ const matchingTemplate = templates.find((template) =>
+ template.name.toLowerCase().includes(searchTerm.toLowerCase()),
+ );
+ expect(displayedTemplates).toContain(matchingTemplate?.key);
+ });
+
+ it('hides non-matching templates', () => {
+ const displayedTemplates = findDisplayedTemplates();
+ const nonMatchingTemplate = templates.find(
+ (template) => !template.name.includes(searchTerm),
+ );
+ expect(displayedTemplates).not.toContain(nonMatchingTemplate?.key);
+ });
+ });
+ });
+});