diff options
Diffstat (limited to 'spec/frontend/vue_shared/components/registry/list_item_spec.js')
-rw-r--r-- | spec/frontend/vue_shared/components/registry/list_item_spec.js | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/spec/frontend/vue_shared/components/registry/list_item_spec.js b/spec/frontend/vue_shared/components/registry/list_item_spec.js new file mode 100644 index 00000000000..e2cfdedb4bf --- /dev/null +++ b/spec/frontend/vue_shared/components/registry/list_item_spec.js @@ -0,0 +1,135 @@ +import { GlButton } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import component from '~/vue_shared/components/registry/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; + }); + + describe.each` + slotName | finderFunction + ${'left-primary'} | ${findLeftPrimarySlot} + ${'left-secondary'} | ${findLeftSecondarySlot} + ${'right-primary'} | ${findRightPrimarySlot} + ${'right-secondary'} | ${findRightSecondarySlot} + ${'left-action'} | ${findLeftActionSlot} + ${'right-action'} | ${findRightActionSlot} + `('$slotName slot', ({ finderFunction, slotName }) => { + it('exist when the slot is filled', () => { + mountComponent(); + + expect(finderFunction().exists()).toBe(true); + }); + + it('does not exist when the slot is empty', () => { + mountComponent({}, { [slotName]: '' }); + + expect(finderFunction().exists()).toBe(false); + }); + }); + + 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('borders and selection', () => { + it.each` + first | selected | shouldHave | shouldNotHave + ${true} | ${true} | ${['gl-bg-blue-50', 'gl-border-blue-200']} | ${['gl-border-t-transparent', 'gl-border-t-gray-100']} + ${false} | ${true} | ${['gl-bg-blue-50', 'gl-border-blue-200']} | ${['gl-border-t-transparent', 'gl-border-t-gray-100']} + ${true} | ${false} | ${['gl-border-b-gray-100']} | ${['gl-bg-blue-50', 'gl-border-blue-200']} + ${false} | ${false} | ${['gl-border-b-gray-100']} | ${['gl-bg-blue-50', 'gl-border-blue-200']} + `( + 'when first is $first and selected is $selected', + ({ first, selected, shouldHave, shouldNotHave }) => { + mountComponent({ first, selected }); + + expect(wrapper.classes()).toEqual(expect.arrayContaining(shouldHave)); + + expect(wrapper.classes()).toEqual(expect.not.arrayContaining(shouldNotHave)); + }, + ); + }); +}); |