import { GlFormRadio, GlIcon, GlFormRadioGroup, GlLink } from '@gitlab/ui'; import { mount, shallowMount } from '@vue/test-utils'; import SnippetVisibilityEdit from '~/snippets/components/snippet_visibility_edit.vue'; import { SNIPPET_VISIBILITY, SNIPPET_VISIBILITY_PRIVATE, SNIPPET_VISIBILITY_INTERNAL, SNIPPET_VISIBILITY_PUBLIC, SNIPPET_LEVELS_RESTRICTED, SNIPPET_LEVELS_DISABLED, } from '~/snippets/constants'; describe('Snippet Visibility Edit component', () => { let wrapper; const defaultHelpLink = '/foo/bar'; const defaultVisibilityLevel = 'private'; function createComponent({ propsData = {}, visibilityLevels = [0, 10, 20], multipleLevelsRestricted = false, deep = false, } = {}) { const method = deep ? mount : shallowMount; wrapper = method.call(this, SnippetVisibilityEdit, { propsData: { helpLink: defaultHelpLink, isProjectSnippet: false, value: defaultVisibilityLevel, ...propsData, }, provide: { visibilityLevels, multipleLevelsRestricted, }, }); } const findLink = () => wrapper.find('label').find(GlLink); const findRadios = () => wrapper.find(GlFormRadioGroup).findAll(GlFormRadio); const findRadiosData = () => findRadios().wrappers.map((x) => { return { value: x.find('input').attributes('value'), icon: x.find(GlIcon).props('name'), description: x.find('.help-text').text(), text: x.find('.js-visibility-option').text(), }; }); afterEach(() => { wrapper.destroy(); }); describe('rendering', () => { it('matches the snapshot', () => { createComponent(); expect(wrapper.element).toMatchSnapshot(); }); it('renders label help link', () => { createComponent(); expect(findLink().attributes('href')).toBe(defaultHelpLink); }); it('when helpLink is not defined, does not render label help link', () => { createComponent({ propsData: { helpLink: null } }); expect(findLink().exists()).toBe(false); }); describe('Visibility options', () => { const findRestrictedInfo = () => wrapper.find('[data-testid="restricted-levels-info"]'); const RESULTING_OPTIONS = { 0: { value: SNIPPET_VISIBILITY_PRIVATE, icon: SNIPPET_VISIBILITY.private.icon, text: SNIPPET_VISIBILITY.private.label, description: SNIPPET_VISIBILITY.private.description, }, 10: { value: SNIPPET_VISIBILITY_INTERNAL, icon: SNIPPET_VISIBILITY.internal.icon, text: SNIPPET_VISIBILITY.internal.label, description: SNIPPET_VISIBILITY.internal.description, }, 20: { value: SNIPPET_VISIBILITY_PUBLIC, icon: SNIPPET_VISIBILITY.public.icon, text: SNIPPET_VISIBILITY.public.label, description: SNIPPET_VISIBILITY.public.description, }, }; it.each` levels | resultOptions ${''} | ${[]} ${[]} | ${[]} ${[0]} | ${[RESULTING_OPTIONS[0]]} ${[0, 10]} | ${[RESULTING_OPTIONS[0], RESULTING_OPTIONS[10]]} ${[0, 10, 20]} | ${[RESULTING_OPTIONS[0], RESULTING_OPTIONS[10], RESULTING_OPTIONS[20]]} ${[0, 20]} | ${[RESULTING_OPTIONS[0], RESULTING_OPTIONS[20]]} ${[10, 20]} | ${[RESULTING_OPTIONS[10], RESULTING_OPTIONS[20]]} `('renders correct visibility options for $levels', ({ levels, resultOptions }) => { createComponent({ visibilityLevels: levels, deep: true }); expect(findRadiosData()).toEqual(resultOptions); }); it.each` levels | levelsRestricted | resultText ${[]} | ${false} | ${SNIPPET_LEVELS_DISABLED} ${[]} | ${true} | ${SNIPPET_LEVELS_DISABLED} ${[0]} | ${true} | ${SNIPPET_LEVELS_RESTRICTED} ${[0]} | ${false} | ${''} ${[0, 10, 20]} | ${false} | ${''} `( 'renders correct information about restricted visibility levels for $levels', ({ levels, levelsRestricted, resultText }) => { createComponent({ visibilityLevels: levels, multipleLevelsRestricted: levelsRestricted, }); expect(findRestrictedInfo().text()).toBe(resultText); }, ); it('when project snippet, renders special private description', () => { createComponent({ propsData: { isProjectSnippet: true }, deep: true }); expect(findRadiosData()[0]).toEqual({ value: SNIPPET_VISIBILITY_PRIVATE, icon: SNIPPET_VISIBILITY.private.icon, text: SNIPPET_VISIBILITY.private.label, description: SNIPPET_VISIBILITY.private.description_project, }); }); }); }); describe('functionality', () => { it('pre-selects correct option in the list', () => { const value = SNIPPET_VISIBILITY_INTERNAL; createComponent({ propsData: { value } }); expect(wrapper.find(GlFormRadioGroup).attributes('checked')).toBe(value); }); }); });