diff options
Diffstat (limited to 'spec/frontend/packages_and_registries/harbor_registry/components')
3 files changed, 226 insertions, 0 deletions
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_header_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_header_spec.js new file mode 100644 index 00000000000..636f3eeb04a --- /dev/null +++ b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_header_spec.js @@ -0,0 +1,88 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlSprintf } from '@gitlab/ui'; +import { nextTick } from 'vue'; +import TitleArea from '~/vue_shared/components/registry/title_area.vue'; +import HarborListHeader from '~/packages_and_registries/harbor_registry/components/list/harbor_list_header.vue'; +import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue'; +import { + HARBOR_REGISTRY_TITLE, + LIST_INTRO_TEXT, +} from '~/packages_and_registries/harbor_registry/constants/index'; + +describe('harbor_list_header', () => { + let wrapper; + + const findTitleArea = () => wrapper.find(TitleArea); + const findCommandsSlot = () => wrapper.find('[data-testid="commands-slot"]'); + const findImagesMetaDataItem = () => wrapper.find(MetadataItem); + + const mountComponent = async (propsData, slots) => { + wrapper = shallowMount(HarborListHeader, { + stubs: { + GlSprintf, + TitleArea, + }, + propsData, + slots, + }); + await nextTick(); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('header', () => { + it('has a title', () => { + mountComponent({ metadataLoading: true }); + + expect(findTitleArea().props()).toMatchObject({ + title: HARBOR_REGISTRY_TITLE, + metadataLoading: true, + }); + }); + + it('has a commands slot', () => { + mountComponent(null, { commands: '<div data-testid="commands-slot">baz</div>' }); + + expect(findCommandsSlot().text()).toBe('baz'); + }); + + describe('sub header parts', () => { + describe('images count', () => { + it('exists', async () => { + await mountComponent({ imagesCount: 1 }); + + expect(findImagesMetaDataItem().exists()).toBe(true); + }); + + it('when there is one image', async () => { + await mountComponent({ imagesCount: 1 }); + + expect(findImagesMetaDataItem().props()).toMatchObject({ + text: '1 Image repository', + icon: 'container-image', + }); + }); + + it('when there is more than one image', async () => { + await mountComponent({ imagesCount: 3 }); + + expect(findImagesMetaDataItem().props('text')).toBe('3 Image repositories'); + }); + }); + }); + }); + + describe('info messages', () => { + describe('default message', () => { + it('is correctly bound to title_area props', () => { + mountComponent({ helpPagePath: 'foo' }); + + expect(findTitleArea().props('infoMessages')).toEqual([ + { text: LIST_INTRO_TEXT, link: 'foo' }, + ]); + }); + }); + }); +}); diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_row_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_row_spec.js new file mode 100644 index 00000000000..8560c4f78f7 --- /dev/null +++ b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_row_spec.js @@ -0,0 +1,99 @@ +import { shallowMount, RouterLinkStub as RouterLink } from '@vue/test-utils'; +import { GlIcon, GlSprintf, GlSkeletonLoader } from '@gitlab/ui'; + +import HarborListRow from '~/packages_and_registries/harbor_registry/components/list/harbor_list_row.vue'; +import ListItem from '~/vue_shared/components/registry/list_item.vue'; +import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import { harborListResponse } from '../../mock_data'; + +describe('Harbor List Row', () => { + let wrapper; + const [item] = harborListResponse.repositories; + + const findDetailsLink = () => wrapper.find(RouterLink); + const findClipboardButton = () => wrapper.findComponent(ClipboardButton); + const findTagsCount = () => wrapper.find('[data-testid="tags-count"]'); + const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader); + + const mountComponent = (props) => { + wrapper = shallowMount(HarborListRow, { + stubs: { + RouterLink, + GlSprintf, + ListItem, + }, + propsData: { + item, + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('image title and path', () => { + it('contains a link to the details page', () => { + mountComponent(); + + const link = findDetailsLink(); + expect(link.text()).toBe(item.name); + expect(findDetailsLink().props('to')).toMatchObject({ + name: 'details', + params: { + id: item.id, + }, + }); + }); + + it('contains a clipboard button', () => { + mountComponent(); + const button = findClipboardButton(); + expect(button.exists()).toBe(true); + expect(button.props('text')).toBe(item.location); + expect(button.props('title')).toBe(item.location); + }); + }); + + describe('tags count', () => { + it('exists', () => { + mountComponent(); + expect(findTagsCount().exists()).toBe(true); + }); + + it('contains a tag icon', () => { + mountComponent(); + const icon = findTagsCount().find(GlIcon); + expect(icon.exists()).toBe(true); + expect(icon.props('name')).toBe('tag'); + }); + + describe('loading state', () => { + it('shows a loader when metadataLoading is true', () => { + mountComponent({ metadataLoading: true }); + + expect(findSkeletonLoader().exists()).toBe(true); + }); + + it('hides the tags count while loading', () => { + mountComponent({ metadataLoading: true }); + + expect(findTagsCount().exists()).toBe(false); + }); + }); + + describe('tags count text', () => { + it('with one tag in the image', () => { + mountComponent({ item: { ...item, artifactCount: 1 } }); + + expect(findTagsCount().text()).toMatchInterpolatedText('1 Tag'); + }); + it('with more than one tag in the image', () => { + mountComponent({ item: { ...item, artifactCount: 3 } }); + + expect(findTagsCount().text()).toMatchInterpolatedText('3 Tags'); + }); + }); + }); +}); diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js new file mode 100644 index 00000000000..f018eff58c9 --- /dev/null +++ b/spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js @@ -0,0 +1,39 @@ +import { shallowMount } from '@vue/test-utils'; +import HarborList from '~/packages_and_registries/harbor_registry/components/list/harbor_list.vue'; +import HarborListRow from '~/packages_and_registries/harbor_registry/components/list/harbor_list_row.vue'; +import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue'; +import { harborListResponse } from '../../mock_data'; + +describe('Harbor List', () => { + let wrapper; + + const findHarborListRow = () => wrapper.findAll(HarborListRow); + + const mountComponent = (props) => { + wrapper = shallowMount(HarborList, { + stubs: { RegistryList }, + propsData: { + images: harborListResponse.repositories, + pageInfo: harborListResponse.pageInfo, + ...props, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + describe('list', () => { + it('contains one list element for each image', () => { + mountComponent(); + + expect(findHarborListRow().length).toBe(harborListResponse.repositories.length); + }); + + it('passes down the metadataLoading prop', () => { + mountComponent({ metadataLoading: true }); + expect(findHarborListRow().at(0).props('metadataLoading')).toBe(true); + }); + }); +}); |