diff options
Diffstat (limited to 'spec/frontend/registry')
13 files changed, 91 insertions, 348 deletions
diff --git a/spec/frontend/registry/explorer/components/delete_button_spec.js b/spec/frontend/registry/explorer/components/delete_button_spec.js index bb0fe81117a..a79ca77a464 100644 --- a/spec/frontend/registry/explorer/components/delete_button_spec.js +++ b/spec/frontend/registry/explorer/components/delete_button_spec.js @@ -54,7 +54,6 @@ describe('delete_button', () => { mountComponent({ disabled: true }); expect(findButton().attributes()).toMatchObject({ 'aria-label': 'Foo title', - category: 'secondary', icon: 'remove', title: 'Foo title', variant: 'danger', diff --git a/spec/frontend/registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/registry/explorer/components/details_page/details_header_spec.js index cb31efa428f..fc93e9094c9 100644 --- a/spec/frontend/registry/explorer/components/details_page/details_header_spec.js +++ b/spec/frontend/registry/explorer/components/details_page/details_header_spec.js @@ -1,5 +1,6 @@ import { shallowMount } from '@vue/test-utils'; import { GlSprintf } from '@gitlab/ui'; +import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import component from '~/registry/explorer/components/details_page/details_header.vue'; import { DETAILS_PAGE_TITLE } from '~/registry/explorer/constants'; @@ -11,6 +12,7 @@ describe('Details Header', () => { propsData, stubs: { GlSprintf, + TitleArea, }, }); }; diff --git a/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js b/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js index a21facefc97..ef22979ca7d 100644 --- a/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js +++ b/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js @@ -6,7 +6,7 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import component from '~/registry/explorer/components/details_page/tags_list_row.vue'; import DeleteButton from '~/registry/explorer/components/delete_button.vue'; -import DetailsRow from '~/registry/shared/components/details_row.vue'; +import DetailsRow from '~/vue_shared/components/registry/details_row.vue'; import { REMOVE_TAG_BUTTON_TITLE, REMOVE_TAG_BUTTON_DISABLE_TOOLTIP, diff --git a/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js index 1f560753476..401202026bb 100644 --- a/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js +++ b/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js @@ -115,7 +115,6 @@ describe('Tags List', () => { // The list has only two tags and for some reasons .at(-1) does not work expect(rows.at(1).attributes()).toMatchObject({ - last: 'true', isdesktop: 'true', }); }); diff --git a/spec/frontend/registry/explorer/components/list_item_spec.js b/spec/frontend/registry/explorer/components/list_item_spec.js deleted file mode 100644 index f244627a8c3..00000000000 --- a/spec/frontend/registry/explorer/components/list_item_spec.js +++ /dev/null @@ -1,156 +0,0 @@ -import { GlButton } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import component from '~/registry/explorer/components/list_item.vue'; - -describe('list item', () => { - let wrapper; - - const findLeftActionSlot = () => wrapper.find('[data-testid="left-action"]'); - const findLeftPrimarySlot = () => wrapper.find('[data-testid="left-primary"]'); - const findLeftSecondarySlot = () => wrapper.find('[data-testid="left-secondary"]'); - const findRightPrimarySlot = () => wrapper.find('[data-testid="right-primary"]'); - const findRightSecondarySlot = () => wrapper.find('[data-testid="right-secondary"]'); - const findRightActionSlot = () => wrapper.find('[data-testid="right-action"]'); - const findDetailsSlot = name => wrapper.find(`[data-testid="${name}"]`); - const findToggleDetailsButton = () => wrapper.find(GlButton); - - const mountComponent = (propsData, slots) => { - wrapper = shallowMount(component, { - propsData, - slots: { - 'left-action': '<div data-testid="left-action" />', - 'left-primary': '<div data-testid="left-primary" />', - 'left-secondary': '<div data-testid="left-secondary" />', - 'right-primary': '<div data-testid="right-primary" />', - 'right-secondary': '<div data-testid="right-secondary" />', - 'right-action': '<div data-testid="right-action" />', - ...slots, - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - it.each` - slotName | finderFunction - ${'left-primary'} | ${findLeftPrimarySlot} - ${'left-secondary'} | ${findLeftSecondarySlot} - ${'right-primary'} | ${findRightPrimarySlot} - ${'right-secondary'} | ${findRightSecondarySlot} - ${'left-action'} | ${findLeftActionSlot} - ${'right-action'} | ${findRightActionSlot} - `('has a $slotName slot', ({ finderFunction }) => { - mountComponent(); - - expect(finderFunction().exists()).toBe(true); - }); - - describe.each` - slotNames - ${['details_foo']} - ${['details_foo', 'details_bar']} - ${['details_foo', 'details_bar', 'details_baz']} - `('$slotNames details slots', ({ slotNames }) => { - const slotMocks = slotNames.reduce((acc, current) => { - acc[current] = `<div data-testid="${current}" />`; - return acc; - }, {}); - - it('are visible when details is shown', async () => { - mountComponent({}, slotMocks); - - await wrapper.vm.$nextTick(); - findToggleDetailsButton().vm.$emit('click'); - - await wrapper.vm.$nextTick(); - slotNames.forEach(name => { - expect(findDetailsSlot(name).exists()).toBe(true); - }); - }); - it('are not visible when details are not shown', () => { - mountComponent({}, slotMocks); - - slotNames.forEach(name => { - expect(findDetailsSlot(name).exists()).toBe(false); - }); - }); - }); - - describe('details toggle button', () => { - it('is visible when at least one details slot exists', async () => { - mountComponent({}, { details_foo: '<span></span>' }); - await wrapper.vm.$nextTick(); - expect(findToggleDetailsButton().exists()).toBe(true); - }); - - it('is hidden without details slot', () => { - mountComponent(); - expect(findToggleDetailsButton().exists()).toBe(false); - }); - }); - - describe('disabled prop', () => { - it('when true applies disabled-content class', () => { - mountComponent({ disabled: true }); - - expect(wrapper.classes('disabled-content')).toBe(true); - }); - - it('when false does not apply disabled-content class', () => { - mountComponent({ disabled: false }); - - expect(wrapper.classes('disabled-content')).toBe(false); - }); - }); - - describe('first prop', () => { - it('when is true displays a double top border', () => { - mountComponent({ first: true }); - - expect(wrapper.classes('gl-border-t-2')).toBe(true); - }); - - it('when is false display a single top border', () => { - mountComponent({ first: false }); - - expect(wrapper.classes('gl-border-t-1')).toBe(true); - }); - }); - - describe('last prop', () => { - it('when is true displays a double bottom border', () => { - mountComponent({ last: true }); - - expect(wrapper.classes('gl-border-b-2')).toBe(true); - }); - - it('when is false display a single bottom border', () => { - mountComponent({ last: false }); - - expect(wrapper.classes('gl-border-b-1')).toBe(true); - }); - }); - - describe('selected prop', () => { - it('when true applies the selected border and background', () => { - mountComponent({ selected: true }); - - expect(wrapper.classes()).toEqual( - expect.arrayContaining(['gl-bg-blue-50', 'gl-border-blue-200']), - ); - expect(wrapper.classes()).toEqual(expect.not.arrayContaining(['gl-border-gray-100'])); - }); - - it('when false applies the default border', () => { - mountComponent({ selected: false }); - - expect(wrapper.classes()).toEqual( - expect.not.arrayContaining(['gl-bg-blue-50', 'gl-border-blue-200']), - ); - expect(wrapper.classes()).toEqual(expect.arrayContaining(['gl-border-gray-100'])); - }); - }); -}); diff --git a/spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js b/spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js index b0291de5f3c..b4471ab8122 100644 --- a/spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js +++ b/spec/frontend/registry/explorer/components/list_page/cli_commands_spec.js @@ -1,10 +1,10 @@ import Vuex from 'vuex'; import { mount, createLocalVue } from '@vue/test-utils'; -import { GlDeprecatedDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui'; +import { GlDeprecatedDropdown } from '@gitlab/ui'; import Tracking from '~/tracking'; import * as getters from '~/registry/explorer/stores/getters'; import QuickstartDropdown from '~/registry/explorer/components/list_page/cli_commands.vue'; -import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue'; import { QUICK_START, @@ -24,7 +24,7 @@ describe('cli_commands', () => { let store; const findDropdownButton = () => wrapper.find(GlDeprecatedDropdown); - const findFormGroups = () => wrapper.findAll(GlFormGroup); + const findCodeInstruction = () => wrapper.findAll(CodeInstruction); const mountComponent = () => { store = new Vuex.Store({ @@ -67,54 +67,29 @@ describe('cli_commands', () => { }); describe.each` - index | id | labelText | titleText | getter | trackedEvent - ${0} | ${'docker-login-btn'} | ${LOGIN_COMMAND_LABEL} | ${COPY_LOGIN_TITLE} | ${'dockerLoginCommand'} | ${'click_copy_login'} - ${1} | ${'docker-build-btn'} | ${BUILD_COMMAND_LABEL} | ${COPY_BUILD_TITLE} | ${'dockerBuildCommand'} | ${'click_copy_build'} - ${2} | ${'docker-push-btn'} | ${PUSH_COMMAND_LABEL} | ${COPY_PUSH_TITLE} | ${'dockerPushCommand'} | ${'click_copy_push'} - `('form group at $index', ({ index, id, labelText, titleText, getter, trackedEvent }) => { - let formGroup; - - const findFormInputGroup = parent => parent.find(GlFormInputGroup); - const findClipboardButton = parent => parent.find(ClipboardButton); + index | labelText | titleText | getter | trackedEvent + ${0} | ${LOGIN_COMMAND_LABEL} | ${COPY_LOGIN_TITLE} | ${'dockerLoginCommand'} | ${'click_copy_login'} + ${1} | ${BUILD_COMMAND_LABEL} | ${COPY_BUILD_TITLE} | ${'dockerBuildCommand'} | ${'click_copy_build'} + ${2} | ${PUSH_COMMAND_LABEL} | ${COPY_PUSH_TITLE} | ${'dockerPushCommand'} | ${'click_copy_push'} + `('code instructions at $index', ({ index, labelText, titleText, getter, trackedEvent }) => { + let codeInstruction; beforeEach(() => { - formGroup = findFormGroups().at(index); + codeInstruction = findCodeInstruction().at(index); }); it('exists', () => { - expect(formGroup.exists()).toBe(true); - }); - - it(`has a label ${labelText}`, () => { - expect(formGroup.text()).toBe(labelText); - }); - - it(`contains a form input group with ${id} id and with value equal to ${getter} getter`, () => { - const formInputGroup = findFormInputGroup(formGroup); - expect(formInputGroup.exists()).toBe(true); - expect(formInputGroup.attributes('id')).toBe(id); - expect(formInputGroup.props('value')).toBe(store.getters[getter]); - }); - - it(`contains a clipboard button with title of ${titleText} and text equal to ${getter} getter`, () => { - const clipBoardButton = findClipboardButton(formGroup); - expect(clipBoardButton.exists()).toBe(true); - expect(clipBoardButton.props('title')).toBe(titleText); - expect(clipBoardButton.props('text')).toBe(store.getters[getter]); + expect(codeInstruction.exists()).toBe(true); }); - it('clipboard button tracks click event', () => { - const clipBoardButton = findClipboardButton(formGroup); - clipBoardButton.trigger('click'); - /* This expect to be called with first argument undefined so that - * the function internally can default to document.body.dataset.page - * https://docs.gitlab.com/ee/telemetry/frontend.html#tracking-within-vue-components - */ - expect(Tracking.event).toHaveBeenCalledWith( - undefined, - trackedEvent, - expect.objectContaining({ label: 'quickstart_dropdown' }), - ); + it(`has the correct props`, () => { + expect(codeInstruction.props()).toMatchObject({ + label: labelText, + instruction: store.getters[getter], + copyText: titleText, + trackingAction: trackedEvent, + trackingLabel: 'quickstart_dropdown', + }); }); }); }); diff --git a/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js index aaeaaf00748..c5b4b3fa5d8 100644 --- a/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js +++ b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js @@ -3,7 +3,7 @@ import { GlIcon, GlSprintf } from '@gitlab/ui'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import Component from '~/registry/explorer/components/list_page/image_list_row.vue'; -import ListItem from '~/registry/explorer/components/list_item.vue'; +import ListItem from '~/vue_shared/components/registry/list_item.vue'; import DeleteButton from '~/registry/explorer/components/delete_button.vue'; import { ROW_SCHEDULED_FOR_DELETION, diff --git a/spec/frontend/registry/explorer/components/list_page/registry_header_spec.js b/spec/frontend/registry/explorer/components/list_page/registry_header_spec.js index 7484fccbea7..7a27f8fa431 100644 --- a/spec/frontend/registry/explorer/components/list_page/registry_header_spec.js +++ b/spec/frontend/registry/explorer/components/list_page/registry_header_spec.js @@ -1,12 +1,12 @@ import { shallowMount } from '@vue/test-utils'; import { GlSprintf, GlLink } from '@gitlab/ui'; import Component from '~/registry/explorer/components/list_page/registry_header.vue'; +import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import { CONTAINER_REGISTRY_TITLE, LIST_INTRO_TEXT, EXPIRATION_POLICY_DISABLED_MESSAGE, EXPIRATION_POLICY_DISABLED_TEXT, - EXPIRATION_POLICY_WILL_RUN_IN, } from '~/registry/explorer/constants'; jest.mock('~/lib/utils/datetime_utility', () => ({ @@ -17,12 +17,10 @@ jest.mock('~/lib/utils/datetime_utility', () => ({ describe('registry_header', () => { let wrapper; - const findHeader = () => wrapper.find('[data-testid="header"]'); - const findTitle = () => wrapper.find('[data-testid="title"]'); + const findTitleArea = () => wrapper.find(TitleArea); const findCommandsSlot = () => wrapper.find('[data-testid="commands-slot"]'); const findInfoArea = () => wrapper.find('[data-testid="info-area"]'); const findIntroText = () => wrapper.find('[data-testid="default-intro"]'); - const findSubHeader = () => wrapper.find('[data-testid="subheader"]'); const findImagesCountSubHeader = () => wrapper.find('[data-testid="images-count"]'); const findExpirationPolicySubHeader = () => wrapper.find('[data-testid="expiration-policy"]'); const findDisabledExpirationPolicyMessage = () => @@ -32,10 +30,12 @@ describe('registry_header', () => { wrapper = shallowMount(Component, { stubs: { GlSprintf, + TitleArea, }, propsData, slots, }); + return wrapper.vm.$nextTick(); }; afterEach(() => { @@ -44,90 +44,80 @@ describe('registry_header', () => { }); describe('header', () => { - it('exists', () => { + it('has a title', () => { mountComponent(); - expect(findHeader().exists()).toBe(true); - }); - it('contains the title of the page', () => { - mountComponent(); - const title = findTitle(); - expect(title.exists()).toBe(true); - expect(title.text()).toBe(CONTAINER_REGISTRY_TITLE); + expect(findTitleArea().props('title')).toBe(CONTAINER_REGISTRY_TITLE); }); it('has a commands slot', () => { - mountComponent(null, { commands: 'baz' }); + mountComponent(null, { commands: '<div data-testid="commands-slot">baz</div>' }); + expect(findCommandsSlot().text()).toBe('baz'); }); - }); - describe('subheader', () => { - describe('when there are no images', () => { - it('is hidden ', () => { - mountComponent(); - expect(findSubHeader().exists()).toBe(false); - }); - }); + describe('sub header parts', () => { + describe('images count', () => { + it('exists', async () => { + await mountComponent({ imagesCount: 1 }); - describe('when there are images', () => { - it('is visible', () => { - mountComponent({ imagesCount: 1 }); - expect(findSubHeader().exists()).toBe(true); - }); + expect(findImagesCountSubHeader().exists()).toBe(true); + }); + + it('when there is one image', async () => { + await mountComponent({ imagesCount: 1 }); - describe('sub header parts', () => { - describe('images count', () => { - it('exists', () => { - mountComponent({ imagesCount: 1 }); - expect(findImagesCountSubHeader().exists()).toBe(true); + expect(findImagesCountSubHeader().props()).toMatchObject({ + text: '1 Image repository', + icon: 'container-image', }); + }); + + it('when there is more than one image', async () => { + await mountComponent({ imagesCount: 3 }); + + expect(findImagesCountSubHeader().props('text')).toBe('3 Image repositories'); + }); + }); - it('when there is one image', () => { - mountComponent({ imagesCount: 1 }); - expect(findImagesCountSubHeader().text()).toMatchInterpolatedText('1 Image repository'); + describe('expiration policy', () => { + it('when is disabled', async () => { + await mountComponent({ + expirationPolicy: { enabled: false }, + expirationPolicyHelpPagePath: 'foo', + imagesCount: 1, }); - it('when there is more than one image', () => { - mountComponent({ imagesCount: 3 }); - expect(findImagesCountSubHeader().text()).toMatchInterpolatedText( - '3 Image repositories', - ); + const text = findExpirationPolicySubHeader(); + expect(text.exists()).toBe(true); + expect(text.props()).toMatchObject({ + text: EXPIRATION_POLICY_DISABLED_TEXT, + icon: 'expire', + size: 'xl', }); }); - describe('expiration policy', () => { - it('when is disabled', () => { - mountComponent({ - expirationPolicy: { enabled: false }, - expirationPolicyHelpPagePath: 'foo', - imagesCount: 1, - }); - const text = findExpirationPolicySubHeader(); - expect(text.exists()).toBe(true); - expect(text.text()).toMatchInterpolatedText(EXPIRATION_POLICY_DISABLED_TEXT); + it('when is enabled', async () => { + await mountComponent({ + expirationPolicy: { enabled: true }, + expirationPolicyHelpPagePath: 'foo', + imagesCount: 1, }); - it('when is enabled', () => { - mountComponent({ - expirationPolicy: { enabled: true }, - expirationPolicyHelpPagePath: 'foo', - imagesCount: 1, - }); - const text = findExpirationPolicySubHeader(); - expect(text.exists()).toBe(true); - expect(text.text()).toMatchInterpolatedText(EXPIRATION_POLICY_WILL_RUN_IN); - }); - it('when the expiration policy is completely disabled', () => { - mountComponent({ - expirationPolicy: { enabled: true }, - expirationPolicyHelpPagePath: 'foo', - imagesCount: 1, - hideExpirationPolicyData: true, - }); - const text = findExpirationPolicySubHeader(); - expect(text.exists()).toBe(false); + const text = findExpirationPolicySubHeader(); + expect(text.exists()).toBe(true); + expect(text.props('text')).toBe('Expiration policy will run in '); + }); + it('when the expiration policy is completely disabled', async () => { + await mountComponent({ + expirationPolicy: { enabled: true }, + expirationPolicyHelpPagePath: 'foo', + imagesCount: 1, + hideExpirationPolicyData: true, }); + + const text = findExpirationPolicySubHeader(); + expect(text.exists()).toBe(false); }); }); }); @@ -136,12 +126,13 @@ describe('registry_header', () => { describe('info area', () => { it('exists', () => { mountComponent(); + expect(findInfoArea().exists()).toBe(true); }); describe('default message', () => { beforeEach(() => { - mountComponent({ helpPagePath: 'bar' }); + return mountComponent({ helpPagePath: 'bar' }); }); it('exists', () => { @@ -165,6 +156,7 @@ describe('registry_header', () => { describe('when there are no images', () => { it('is hidden', () => { mountComponent(); + expect(findDisabledExpirationPolicyMessage().exists()).toBe(false); }); }); @@ -172,7 +164,7 @@ describe('registry_header', () => { describe('when there are images', () => { describe('when expiration policy is disabled', () => { beforeEach(() => { - mountComponent({ + return mountComponent({ expirationPolicy: { enabled: false }, expirationPolicyHelpPagePath: 'foo', imagesCount: 1, @@ -202,6 +194,7 @@ describe('registry_header', () => { expirationPolicy: { enabled: true }, imagesCount: 1, }); + expect(findDisabledExpirationPolicyMessage().exists()).toBe(false); }); }); @@ -212,6 +205,7 @@ describe('registry_header', () => { imagesCount: 1, hideExpirationPolicyData: true, }); + expect(findDisabledExpirationPolicyMessage().exists()).toBe(false); }); }); diff --git a/spec/frontend/registry/explorer/components/registry_breadcrumb_spec.js b/spec/frontend/registry/explorer/components/registry_breadcrumb_spec.js index f04585a6ff4..b906e44a4f7 100644 --- a/spec/frontend/registry/explorer/components/registry_breadcrumb_spec.js +++ b/spec/frontend/registry/explorer/components/registry_breadcrumb_spec.js @@ -117,7 +117,7 @@ describe('Registry Breadcrumb', () => { }); it('has the same tag as the last children of the crumbs', () => { - expect(findLastCrumb().is(lastChildren.tagName)).toBe(true); + expect(findLastCrumb().element.tagName).toBe(lastChildren.tagName.toUpperCase()); }); it('has the same classes as the last children of the crumbs', () => { diff --git a/spec/frontend/registry/explorer/pages/list_spec.js b/spec/frontend/registry/explorer/pages/list_spec.js index b4e46fda2c4..b24422adb03 100644 --- a/spec/frontend/registry/explorer/pages/list_spec.js +++ b/spec/frontend/registry/explorer/pages/list_spec.js @@ -8,6 +8,7 @@ import GroupEmptyState from '~/registry/explorer/components/list_page/group_empt import ProjectEmptyState from '~/registry/explorer/components/list_page/project_empty_state.vue'; import RegistryHeader from '~/registry/explorer/components/list_page/registry_header.vue'; import ImageList from '~/registry/explorer/components/list_page/image_list.vue'; +import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import { createStore } from '~/registry/explorer/stores/'; import { SET_MAIN_LOADING, @@ -54,6 +55,7 @@ describe('List Page', () => { GlEmptyState, GlSprintf, RegistryHeader, + TitleArea, }, mocks: { $toast, diff --git a/spec/frontend/registry/explorer/stubs.js b/spec/frontend/registry/explorer/stubs.js index 8f95fce2867..b6c0ee67757 100644 --- a/spec/frontend/registry/explorer/stubs.js +++ b/spec/frontend/registry/explorer/stubs.js @@ -1,5 +1,5 @@ import RealDeleteModal from '~/registry/explorer/components/details_page/delete_modal.vue'; -import RealListItem from '~/registry/explorer/components/list_item.vue'; +import RealListItem from '~/vue_shared/components/registry/list_item.vue'; export const GlModal = { template: '<div><slot name="modal-title"></slot><slot></slot><slot name="modal-ok"></slot></div>', diff --git a/spec/frontend/registry/shared/components/details_row_spec.js b/spec/frontend/registry/shared/components/details_row_spec.js deleted file mode 100644 index 5ae4e0ab37f..00000000000 --- a/spec/frontend/registry/shared/components/details_row_spec.js +++ /dev/null @@ -1,71 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import { GlIcon } from '@gitlab/ui'; -import component from '~/registry/shared/components/details_row.vue'; - -describe('DetailsRow', () => { - let wrapper; - - const findIcon = () => wrapper.find(GlIcon); - const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]'); - - const mountComponent = props => { - wrapper = shallowMount(component, { - propsData: { - icon: 'clock', - ...props, - }, - slots: { - default: '<div data-testid="default-slot"></div>', - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - it('has a default slot', () => { - mountComponent(); - expect(findDefaultSlot().exists()).toBe(true); - }); - - describe('icon prop', () => { - it('contains an icon', () => { - mountComponent(); - expect(findIcon().exists()).toBe(true); - }); - - it('icon has the correct props', () => { - mountComponent(); - expect(findIcon().props()).toMatchObject({ - name: 'clock', - }); - }); - }); - - describe('padding prop', () => { - it('padding has a default', () => { - mountComponent(); - expect(wrapper.classes('gl-py-2')).toBe(true); - }); - - it('is reflected in the template', () => { - mountComponent({ padding: 'gl-py-4' }); - expect(wrapper.classes('gl-py-4')).toBe(true); - }); - }); - - describe('dashed prop', () => { - const borderClasses = ['gl-border-b-solid', 'gl-border-gray-100', 'gl-border-b-1']; - it('by default component has no border', () => { - mountComponent(); - expect(wrapper.classes).not.toEqual(expect.arrayContaining(borderClasses)); - }); - - it('has a border when dashed is true', () => { - mountComponent({ dashed: true }); - expect(wrapper.classes()).toEqual(expect.arrayContaining(borderClasses)); - }); - }); -}); diff --git a/spec/frontend/registry/shared/mocks.js b/spec/frontend/registry/shared/mocks.js index e33d06e7499..fdef38b6f10 100644 --- a/spec/frontend/registry/shared/mocks.js +++ b/spec/frontend/registry/shared/mocks.js @@ -1,4 +1,3 @@ -// eslint-disable-next-line import/prefer-default-export export const $toast = { show: jest.fn(), }; |