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/template_selector_spec.js')
-rw-r--r--spec/frontend/blob/filepath_form/components/template_selector_spec.js167
1 files changed, 167 insertions, 0 deletions
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);
+ });
+ });
+ });
+});