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/packages_and_registries/harbor_registry')
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_row_spec.js143
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_spec.js75
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/details/details_header_spec.js85
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_header_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_row_spec.js38
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/list/harbor_list_spec.js10
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_header_spec.js52
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js75
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_spec.js66
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/mock_data.js269
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/pages/details_spec.js162
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/pages/index_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/pages/list_spec.js42
-rw-r--r--spec/frontend/packages_and_registries/harbor_registry/pages/tags_spec.js125
14 files changed, 947 insertions, 206 deletions
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_row_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_row_spec.js
new file mode 100644
index 00000000000..a2e5cbdce8b
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_row_spec.js
@@ -0,0 +1,143 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { n__ } from '~/locale';
+import ArtifactsListRow from '~/packages_and_registries/harbor_registry/components/details/artifacts_list_row.vue';
+import RealListItem from '~/vue_shared/components/registry/list_item.vue';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import { harborArtifactsList, defaultConfig } from '../../mock_data';
+
+describe('Harbor artifact list row', () => {
+ let wrapper;
+
+ const ListItem = {
+ ...RealListItem,
+ data() {
+ return {
+ detailsSlots: [],
+ isDetailsShown: true,
+ };
+ },
+ };
+
+ const RouterLinkStub = {
+ props: {
+ to: {
+ type: Object,
+ },
+ },
+ render(createElement) {
+ return createElement('a', {}, this.$slots.default);
+ },
+ };
+
+ const findListItem = () => wrapper.findComponent(ListItem);
+ const findClipboardButton = () => wrapper.findAllComponents(ClipboardButton);
+ const findTimeAgoTooltip = () => wrapper.findComponent(TimeAgoTooltip);
+ const findByTestId = (testId) => wrapper.findByTestId(testId);
+
+ const $route = {
+ params: {
+ project: defaultConfig.harborIntegrationProjectName,
+ image: 'test-repository',
+ },
+ };
+
+ const mountComponent = ({ propsData, config = defaultConfig }) => {
+ wrapper = shallowMountExtended(ArtifactsListRow, {
+ stubs: {
+ GlSprintf,
+ ListItem,
+ 'router-link': RouterLinkStub,
+ },
+ mocks: {
+ $route,
+ },
+ propsData,
+ provide() {
+ return {
+ ...config,
+ };
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('list item', () => {
+ beforeEach(() => {
+ mountComponent({
+ propsData: {
+ artifact: harborArtifactsList[0],
+ },
+ });
+ });
+
+ it('exists', () => {
+ expect(findListItem().exists()).toBe(true);
+ });
+
+ it('has the correct artifact name', () => {
+ expect(findByTestId('name').text()).toBe(harborArtifactsList[0].digest);
+ });
+
+ it('has the correct tags count', () => {
+ const tagsCount = harborArtifactsList[0].tags.length;
+ expect(findByTestId('tags-count').text()).toBe(n__('%d tag', '%d tags', tagsCount));
+ });
+
+ it('has correct digest', () => {
+ expect(findByTestId('digest').text()).toBe('Digest: mock_sh');
+ });
+ describe('time', () => {
+ it('has the correct push time', () => {
+ expect(findByTestId('time').text()).toBe('Published');
+ expect(findTimeAgoTooltip().attributes()).toMatchObject({
+ time: harborArtifactsList[0].pushTime,
+ });
+ });
+ });
+
+ describe('clipboard button', () => {
+ it('exists', () => {
+ expect(findClipboardButton()).toHaveLength(2);
+ });
+
+ it('has the correct props', () => {
+ expect(findClipboardButton().at(0).attributes()).toMatchObject({
+ text: `docker pull demo.harbor.com/test-project/test-repository@${harborArtifactsList[0].digest}`,
+ title: `docker pull demo.harbor.com/test-project/test-repository@${harborArtifactsList[0].digest}`,
+ });
+
+ expect(findClipboardButton().at(1).attributes()).toMatchObject({
+ text: harborArtifactsList[0].digest,
+ title: harborArtifactsList[0].digest,
+ });
+ });
+ });
+
+ describe('size', () => {
+ it('calculated correctly', () => {
+ expect(findByTestId('size').text()).toBe(
+ numberToHumanSize(Number(harborArtifactsList[0].size)),
+ );
+ });
+
+ it('when size is missing', () => {
+ const artifactInfo = harborArtifactsList[0];
+ artifactInfo.size = null;
+
+ mountComponent({
+ propsData: {
+ artifact: artifactInfo,
+ },
+ });
+
+ expect(findByTestId('size').text()).toBe('0 bytes');
+ });
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_spec.js
new file mode 100644
index 00000000000..b9d6dc2679e
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/components/details/artifacts_list_spec.js
@@ -0,0 +1,75 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlEmptyState } from '@gitlab/ui';
+import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue';
+import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+import ArtifactsList from '~/packages_and_registries/harbor_registry/components/details/artifacts_list.vue';
+import ArtifactsListRow from '~/packages_and_registries/harbor_registry/components/details/artifacts_list_row.vue';
+import { defaultConfig, harborArtifactsList } from '../../mock_data';
+
+describe('Harbor artifacts list', () => {
+ let wrapper;
+
+ const findTagsLoader = () => wrapper.findComponent(TagsLoader);
+ const findGlEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findRegistryList = () => wrapper.findComponent(RegistryList);
+ const findArtifactsListRow = () => wrapper.findAllComponents(ArtifactsListRow);
+
+ const mountComponent = ({ propsData, config = defaultConfig }) => {
+ wrapper = shallowMount(ArtifactsList, {
+ propsData,
+ stubs: { RegistryList },
+ provide() {
+ return {
+ ...config,
+ };
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when isLoading is true', () => {
+ beforeEach(() => {
+ mountComponent({
+ propsData: {
+ isLoading: true,
+ pageInfo: {},
+ filter: '',
+ artifacts: [],
+ },
+ });
+ });
+
+ it('show the loader', () => {
+ expect(findTagsLoader().exists()).toBe(true);
+ });
+
+ it('does not show the list', () => {
+ expect(findGlEmptyState().exists()).toBe(false);
+ expect(findRegistryList().exists()).toBe(false);
+ });
+ });
+
+ describe('registry list', () => {
+ beforeEach(() => {
+ mountComponent({
+ propsData: {
+ isLoading: false,
+ pageInfo: {},
+ filter: '',
+ artifacts: harborArtifactsList,
+ },
+ });
+ });
+
+ it('exists', () => {
+ expect(findRegistryList().exists()).toBe(true);
+ });
+
+ it('one artifact row exist', () => {
+ expect(findArtifactsListRow()).toHaveLength(harborArtifactsList.length);
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/details/details_header_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/details/details_header_spec.js
new file mode 100644
index 00000000000..e8cc2b2e22d
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/components/details/details_header_spec.js
@@ -0,0 +1,85 @@
+import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import DetailsHeader from '~/packages_and_registries/harbor_registry/components/details/details_header.vue';
+import TitleArea from '~/vue_shared/components/registry/title_area.vue';
+import { ROOT_IMAGE_TEXT } from '~/packages_and_registries/harbor_registry/constants/index';
+
+describe('Harbor Details Header', () => {
+ let wrapper;
+
+ const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
+ const findTitle = () => findByTestId('title');
+ const findArtifactsCount = () => findByTestId('artifacts-count');
+
+ const mountComponent = ({ propsData }) => {
+ wrapper = shallowMount(DetailsHeader, {
+ propsData,
+ stubs: {
+ TitleArea,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('artifact name', () => {
+ describe('missing image name', () => {
+ beforeEach(() => {
+ mountComponent({ propsData: { imagesDetail: { name: '', artifactCount: 1 } } });
+ });
+
+ it('root image', () => {
+ expect(findTitle().text()).toBe(ROOT_IMAGE_TEXT);
+ });
+ });
+
+ describe('with artifact name present', () => {
+ beforeEach(() => {
+ mountComponent({ propsData: { imagesDetail: { name: 'shao/flinkx', artifactCount: 1 } } });
+ });
+
+ it('shows artifact.name', () => {
+ expect(findTitle().text()).toContain('shao/flinkx');
+ });
+ });
+ });
+
+ describe('metadata items', () => {
+ describe('artifacts count', () => {
+ it('displays "-- artifacts" while loading', async () => {
+ mountComponent({ propsData: { imagesDetail: {} } });
+ await nextTick();
+
+ expect(findArtifactsCount().props('text')).toBe('-- artifacts');
+ });
+
+ it('when there is more than one artifact has the correct text', async () => {
+ mountComponent({ propsData: { imagesDetail: { name: 'shao/flinkx', artifactCount: 10 } } });
+
+ await nextTick();
+
+ expect(findArtifactsCount().props('text')).toBe('10 artifacts');
+ });
+
+ it('when there is one artifact has the correct text', async () => {
+ mountComponent({
+ propsData: { imagesDetail: { name: 'shao/flinkx', artifactCount: 1 } },
+ });
+ await nextTick();
+
+ expect(findArtifactsCount().props('text')).toBe('1 artifact');
+ });
+
+ it('has the correct icon', async () => {
+ mountComponent({
+ propsData: { imagesDetail: { name: 'shao/flinkx', artifactCount: 1 } },
+ });
+ await nextTick();
+
+ expect(findArtifactsCount().props('icon')).toBe('package');
+ });
+ });
+ });
+});
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
index 636f3eeb04a..7a6169d300c 100644
--- 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
@@ -7,14 +7,15 @@ import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import {
HARBOR_REGISTRY_TITLE,
LIST_INTRO_TEXT,
+ HARBOR_REGISTRY_HELP_PAGE_PATH,
} from '~/packages_and_registries/harbor_registry/constants/index';
describe('harbor_list_header', () => {
let wrapper;
- const findTitleArea = () => wrapper.find(TitleArea);
+ const findTitleArea = () => wrapper.findComponent(TitleArea);
const findCommandsSlot = () => wrapper.find('[data-testid="commands-slot"]');
- const findImagesMetaDataItem = () => wrapper.find(MetadataItem);
+ const findImagesMetaDataItem = () => wrapper.findComponent(MetadataItem);
const mountComponent = async (propsData, slots) => {
wrapper = shallowMount(HarborListHeader, {
@@ -77,10 +78,10 @@ describe('harbor_list_header', () => {
describe('info messages', () => {
describe('default message', () => {
it('is correctly bound to title_area props', () => {
- mountComponent({ helpPagePath: 'foo' });
+ mountComponent();
expect(findTitleArea().props('infoMessages')).toEqual([
- { text: LIST_INTRO_TEXT, link: 'foo' },
+ { text: LIST_INTRO_TEXT, link: HARBOR_REGISTRY_HELP_PAGE_PATH },
]);
});
});
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
index 8560c4f78f7..b62d4e8836b 100644
--- 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
@@ -1,25 +1,24 @@
import { shallowMount, RouterLinkStub as RouterLink } from '@vue/test-utils';
-import { GlIcon, GlSprintf, GlSkeletonLoader } from '@gitlab/ui';
+import { GlIcon, 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';
+import { harborImagesList } from '../../mock_data';
describe('Harbor List Row', () => {
let wrapper;
- const [item] = harborListResponse.repositories;
+ const item = harborImagesList[0];
- const findDetailsLink = () => wrapper.find(RouterLink);
+ const findDetailsLink = () => wrapper.findComponent(RouterLink);
const findClipboardButton = () => wrapper.findComponent(ClipboardButton);
- const findTagsCount = () => wrapper.find('[data-testid="tags-count"]');
+ const findArtifactsCount = () => wrapper.find('[data-testid="artifacts-count"]');
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const mountComponent = (props) => {
wrapper = shallowMount(HarborListRow, {
stubs: {
RouterLink,
- GlSprintf,
ListItem,
},
propsData: {
@@ -42,7 +41,8 @@ describe('Harbor List Row', () => {
expect(findDetailsLink().props('to')).toMatchObject({
name: 'details',
params: {
- id: item.id,
+ image: 'nginx',
+ project: 'nginx',
},
});
});
@@ -56,17 +56,17 @@ describe('Harbor List Row', () => {
});
});
- describe('tags count', () => {
+ describe('artifacts count', () => {
it('exists', () => {
mountComponent();
- expect(findTagsCount().exists()).toBe(true);
+ expect(findArtifactsCount().exists()).toBe(true);
});
- it('contains a tag icon', () => {
+ it('contains a package icon', () => {
mountComponent();
- const icon = findTagsCount().find(GlIcon);
+ const icon = findArtifactsCount().findComponent(GlIcon);
expect(icon.exists()).toBe(true);
- expect(icon.props('name')).toBe('tag');
+ expect(icon.props('name')).toBe('package');
});
describe('loading state', () => {
@@ -76,23 +76,23 @@ describe('Harbor List Row', () => {
expect(findSkeletonLoader().exists()).toBe(true);
});
- it('hides the tags count while loading', () => {
+ it('hides the artifacts count while loading', () => {
mountComponent({ metadataLoading: true });
- expect(findTagsCount().exists()).toBe(false);
+ expect(findArtifactsCount().exists()).toBe(false);
});
});
- describe('tags count text', () => {
- it('with one tag in the image', () => {
+ describe('artifacts count text', () => {
+ it('with one artifact in the image', () => {
mountComponent({ item: { ...item, artifactCount: 1 } });
- expect(findTagsCount().text()).toMatchInterpolatedText('1 Tag');
+ expect(findArtifactsCount().text()).toMatchInterpolatedText('1 artifact');
});
- it('with more than one tag in the image', () => {
+ it('with more than one artifact in the image', () => {
mountComponent({ item: { ...item, artifactCount: 3 } });
- expect(findTagsCount().text()).toMatchInterpolatedText('3 Tags');
+ expect(findArtifactsCount().text()).toMatchInterpolatedText('3 artifacts');
});
});
});
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
index f018eff58c9..e7e74a0da58 100644
--- 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
@@ -2,19 +2,19 @@ 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';
+import { harborImagesList } from '../../mock_data';
describe('Harbor List', () => {
let wrapper;
- const findHarborListRow = () => wrapper.findAll(HarborListRow);
+ const findHarborListRow = () => wrapper.findAllComponents(HarborListRow);
const mountComponent = (props) => {
wrapper = shallowMount(HarborList, {
stubs: { RegistryList },
propsData: {
- images: harborListResponse.repositories,
- pageInfo: harborListResponse.pageInfo,
+ images: harborImagesList,
+ pageInfo: {},
...props,
},
});
@@ -28,7 +28,7 @@ describe('Harbor List', () => {
it('contains one list element for each image', () => {
mountComponent();
- expect(findHarborListRow().length).toBe(harborListResponse.repositories.length);
+ expect(findHarborListRow().length).toBe(harborImagesList.length);
});
it('passes down the metadataLoading prop', () => {
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_header_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_header_spec.js
new file mode 100644
index 00000000000..5e299a269e3
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_header_spec.js
@@ -0,0 +1,52 @@
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import TagsHeader from '~/packages_and_registries/harbor_registry/components/tags/tags_header.vue';
+import TitleArea from '~/vue_shared/components/registry/title_area.vue';
+import { mockArtifactDetail, MOCK_SHA_DIGEST } from '../../mock_data';
+
+describe('Harbor Tags Header', () => {
+ let wrapper;
+
+ const findTitle = () => wrapper.findByTestId('title');
+ const findTagsCount = () => wrapper.findByTestId('tags-count');
+
+ const mountComponent = ({ propsData }) => {
+ wrapper = shallowMountExtended(TagsHeader, {
+ propsData,
+ stubs: {
+ TitleArea,
+ },
+ });
+ };
+
+ const mockPageInfo = {
+ page: 1,
+ perPage: 20,
+ total: 1,
+ totalPages: 1,
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ beforeEach(() => {
+ mountComponent({
+ propsData: { artifactDetail: mockArtifactDetail, pageInfo: mockPageInfo, tagsLoading: false },
+ });
+ });
+
+ describe('tags title', () => {
+ it('should be artifact digest', () => {
+ expect(findTitle().text()).toBe(`sha256:${MOCK_SHA_DIGEST}`);
+ });
+ });
+
+ describe('tags count', () => {
+ it('would has the correct text', async () => {
+ await nextTick();
+
+ expect(findTagsCount().props('text')).toBe('1 tag');
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js
new file mode 100644
index 00000000000..6fe3dabc603
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_row_spec.js
@@ -0,0 +1,75 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import ListItem from '~/vue_shared/components/registry/list_item.vue';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import TagsListRow from '~/packages_and_registries/harbor_registry/components/tags/tags_list_row.vue';
+import { defaultConfig, harborTagsList } from '../../mock_data';
+
+describe('Harbor tag list row', () => {
+ let wrapper;
+
+ const findListItem = () => wrapper.find(ListItem);
+ const findClipboardButton = () => wrapper.find(ClipboardButton);
+ const findByTestId = (testId) => wrapper.findByTestId(testId);
+
+ const $route = {
+ params: {
+ project: defaultConfig.harborIntegrationProjectName,
+ image: 'test-repository',
+ },
+ };
+
+ const mountComponent = ({ propsData, config = defaultConfig }) => {
+ wrapper = shallowMountExtended(TagsListRow, {
+ stubs: {
+ ListItem,
+ GlSprintf,
+ },
+ propsData,
+ mocks: {
+ $route,
+ },
+ provide() {
+ return {
+ ...config,
+ };
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('list item', () => {
+ beforeEach(() => {
+ mountComponent({
+ propsData: {
+ tag: harborTagsList[0],
+ },
+ });
+ });
+
+ it('exists', () => {
+ expect(findListItem().exists()).toBe(true);
+ });
+
+ it('has the correct tag name', () => {
+ expect(findByTestId('name').text()).toBe(harborTagsList[0].name);
+ });
+
+ describe(' clipboard button', () => {
+ it('exists', () => {
+ expect(findClipboardButton().exists()).toBe(true);
+ });
+
+ it('has the correct props', () => {
+ const pullCommand = `docker pull demo.harbor.com/test-project/test-repository:${harborTagsList[0].name}`;
+ expect(findClipboardButton().attributes()).toMatchObject({
+ text: pullCommand,
+ title: pullCommand,
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_spec.js b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_spec.js
new file mode 100644
index 00000000000..6bcf6611d07
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/components/tags/tags_list_spec.js
@@ -0,0 +1,66 @@
+import { shallowMount } from '@vue/test-utils';
+import TagsList from '~/packages_and_registries/harbor_registry/components/tags/tags_list.vue';
+import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue';
+import TagsListRow from '~/packages_and_registries/harbor_registry/components/tags/tags_list_row.vue';
+import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+import { defaultConfig, harborTagsResponse } from '../../mock_data';
+
+describe('Harbor Tags List', () => {
+ let wrapper;
+
+ const findTagsLoader = () => wrapper.find(TagsLoader);
+ const findTagsListRows = () => wrapper.findAllComponents(TagsListRow);
+ const findRegistryList = () => wrapper.find(RegistryList);
+
+ const mountComponent = ({ propsData, config = defaultConfig }) => {
+ wrapper = shallowMount(TagsList, {
+ propsData,
+ stubs: { RegistryList },
+ provide() {
+ return {
+ ...config,
+ };
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when isLoading is true', () => {
+ beforeEach(() => {
+ mountComponent({
+ propsData: {
+ isLoading: true,
+ pageInfo: {},
+ tags: [],
+ },
+ });
+ });
+
+ it('show the loader', () => {
+ expect(findTagsLoader().exists()).toBe(true);
+ });
+ });
+
+ describe('tags list', () => {
+ beforeEach(() => {
+ mountComponent({
+ propsData: {
+ isLoading: false,
+ pageInfo: {},
+ tags: harborTagsResponse,
+ },
+ });
+ });
+
+ it('should render correctly', () => {
+ expect(findRegistryList().exists()).toBe(true);
+ });
+
+ it('one tag row exists', () => {
+ expect(findTagsListRows()).toHaveLength(harborTagsResponse.length);
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/harbor_registry/mock_data.js b/spec/frontend/packages_and_registries/harbor_registry/mock_data.js
index 85399c22e79..b8989b6092e 100644
--- a/spec/frontend/packages_and_registries/harbor_registry/mock_data.js
+++ b/spec/frontend/packages_and_registries/harbor_registry/mock_data.js
@@ -1,175 +1,114 @@
-export const harborListResponse = {
- repositories: [
- {
- artifactCount: 1,
- creationTime: '2022-03-02T06:35:53.205Z',
- id: 25,
- name: 'shao/flinkx',
- projectId: 21,
- pullCount: 0,
- updateTime: '2022-03-02T06:35:53.205Z',
- location: 'demo.harbor.com/gitlab-cn/build/cng-images/gitlab-kas',
- },
- {
- artifactCount: 1,
- creationTime: '2022-03-02T06:35:53.205Z',
- id: 26,
- name: 'shao/flinkx1',
- projectId: 21,
- pullCount: 0,
- updateTime: '2022-03-02T06:35:53.205Z',
- location: 'demo.harbor.com/gitlab-cn/build/cng-images/gitlab-kas',
- },
- {
- artifactCount: 1,
- creationTime: '2022-03-02T06:35:53.205Z',
- id: 27,
- name: 'shao/flinkx2',
- projectId: 21,
- pullCount: 0,
- updateTime: '2022-03-02T06:35:53.205Z',
- location: 'demo.harbor.com/gitlab-cn/build/cng-images/gitlab-kas',
- },
- ],
- totalCount: 3,
- pageInfo: {
- hasNextPage: false,
- hasPreviousPage: false,
- },
+export const harborImageDetailEmptyResponse = {
+ data: null,
};
-export const harborTagsResponse = {
- tags: [
- {
- digest: 'sha256:7f386a1844faf341353e1c20f2f39f11f397604fedc475435d13f756eeb235d1',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:02310e655103823920157bc4410ea361dc638bc2cda59667d2cb1f2a988e264c',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:02310e655103823920157bc4410ea361dc638bc2cda59667d2cb1f2a988e264c',
- name: '02310e655103823920157bc4410ea361dc638bc2cda59667d2cb1f2a988e264c',
- revision: 'f53bde3d44699e04e11cf15fb415046a0913e2623d878d89bc21adb2cbda5255',
- shortRevision: 'f53bde3d4',
- createdAt: '2022-03-02T23:59:05+00:00',
- totalSize: '6623124',
- },
- {
- digest: 'sha256:4554416b84c4568fe93086620b637064ed029737aabe7308b96d50e3d9d92ed7',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:02deb4dddf177212b50e883d5e4f6c03731fad1a18cd27261736cd9dbba79160',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:02deb4dddf177212b50e883d5e4f6c03731fad1a18cd27261736cd9dbba79160',
- name: '02deb4dddf177212b50e883d5e4f6c03731fad1a18cd27261736cd9dbba79160',
- revision: 'e1fe52d8bab66d71bd54a6b8784d3b9edbc68adbd6ea87f5fa44d9974144ef9e',
- shortRevision: 'e1fe52d8b',
- createdAt: '2022-02-10T01:09:56+00:00',
- totalSize: '920760',
- },
- {
- digest: 'sha256:14f37b60e52b9ce0e9f8f7094b311d265384798592f783487c30aaa3d58e6345',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:03bc5971bab1e849ba52a20a31e7273053f22b2ddb1d04bd6b77d53a2635727a',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:03bc5971bab1e849ba52a20a31e7273053f22b2ddb1d04bd6b77d53a2635727a',
- name: '03bc5971bab1e849ba52a20a31e7273053f22b2ddb1d04bd6b77d53a2635727a',
- revision: 'c72770c6eb93c421bc496964b4bffc742b1ec2e642cdab876be7afda1856029f',
- shortRevision: 'c72770c6e',
- createdAt: '2021-12-22T04:48:48+00:00',
- totalSize: '48609053',
- },
- {
- digest: 'sha256:e925e3b8277ea23f387ed5fba5e78280cfac7cfb261a78cf046becf7b6a3faae',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:03f495bc5714bff78bb14293320d336afdf47fd47ddff0c3c5f09f8da86d5d19',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:03f495bc5714bff78bb14293320d336afdf47fd47ddff0c3c5f09f8da86d5d19',
- name: '03f495bc5714bff78bb14293320d336afdf47fd47ddff0c3c5f09f8da86d5d19',
- revision: '1ac2a43194f4e15166abdf3f26e6ec92215240490b9cac834d63de1a3d87494a',
- shortRevision: '1ac2a4319',
- createdAt: '2022-03-09T11:02:27+00:00',
- totalSize: '35141894',
- },
- {
- digest: 'sha256:7d8303fd5c077787a8c879f8f66b69e2b5605f48ccd3f286e236fb0749fcc1ca',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:05a4e58231e54b70aab2d6f22ba4fbe10e48aa4ddcbfef11c5662241c2ae4fda',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:05a4e58231e54b70aab2d6f22ba4fbe10e48aa4ddcbfef11c5662241c2ae4fda',
- name: '05a4e58231e54b70aab2d6f22ba4fbe10e48aa4ddcbfef11c5662241c2ae4fda',
- revision: 'cf8fee086701016e1a84e6824f0c896951fef4cce9d4745459558b87eec3232c',
- shortRevision: 'cf8fee086',
- createdAt: '2022-01-21T11:31:43+00:00',
- totalSize: '48716070',
- },
- {
- digest: 'sha256:b33611cefe20e4a41a6e0dce356a5d7ef3c177ea7536a58652f5b3a4f2f83549',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:093d2746876997723541aec8b88687a4cdb3b5bbb0279c5089b7891317741a9a',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:093d2746876997723541aec8b88687a4cdb3b5bbb0279c5089b7891317741a9a',
- name: '093d2746876997723541aec8b88687a4cdb3b5bbb0279c5089b7891317741a9a',
- revision: '1a4b48198b13d55242c5164e64d41c4e9f75b5d9506bc6e0efc1534dd0dd1f15',
- shortRevision: '1a4b48198',
- createdAt: '2022-01-21T11:31:51+00:00',
- totalSize: '6623127',
- },
- {
- digest: 'sha256:d25c3c020e2dbd4711a67b9fe308f4cbb7b0bb21815e722a02f91c570dc5d519',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:09698b3fae81dfd6e02554dbc82930f304a6356c8f541c80e8598a42aed985f7',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:09698b3fae81dfd6e02554dbc82930f304a6356c8f541c80e8598a42aed985f7',
- name: '09698b3fae81dfd6e02554dbc82930f304a6356c8f541c80e8598a42aed985f7',
- revision: '03e2e2777dde01c30469ee8c710973dd08a7a4f70494d7dc1583c24b525d7f61',
- shortRevision: '03e2e2777',
- createdAt: '2022-03-02T23:58:20+00:00',
- totalSize: '911377',
- },
- {
- digest: 'sha256:fb760e4d2184e9e8e39d6917534d4610fe01009734698a5653b2de1391ba28f4',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:09b830c3eaf80d547f3b523d8e242a2c411085c349dab86c520f36c7b7644f95',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:09b830c3eaf80d547f3b523d8e242a2c411085c349dab86c520f36c7b7644f95',
- name: '09b830c3eaf80d547f3b523d8e242a2c411085c349dab86c520f36c7b7644f95',
- revision: '350e78d60646bf6967244448c6aaa14d21ecb9a0c6cf87e9ff0361cbe59b9012',
- shortRevision: '350e78d60',
- createdAt: '2022-01-19T13:49:14+00:00',
- totalSize: '48710241',
- },
- {
- digest: 'sha256:407250f380cea92729cbc038c420e74900f53b852e11edc6404fe75a0fd2c402',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:0d03504a17b467eafc8c96bde70af26c74bd459a32b7eb2dd189dd6b3c121557',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:0d03504a17b467eafc8c96bde70af26c74bd459a32b7eb2dd189dd6b3c121557',
- name: '0d03504a17b467eafc8c96bde70af26c74bd459a32b7eb2dd189dd6b3c121557',
- revision: '76038370b7f3904364891457c4a6a234897255e6b9f45d0a852bf3a7e5257e18',
- shortRevision: '76038370b',
- createdAt: '2022-01-24T12:56:22+00:00',
- totalSize: '280065',
- },
- {
- digest: 'sha256:ada87f25218542951ce6720c27f3d0758e90c2540bd129f5cfb9e15b31e07b07',
- location:
- 'registry.gitlab.com/gitlab-org/gitlab/gitlab-ee-qa/cache:0eb20a4a7cac2ebea821d420b3279654fe550fd8502f1785c1927aa84e5949eb',
- path:
- 'gitlab-org/gitlab/gitlab-ee-qa/cache:0eb20a4a7cac2ebea821d420b3279654fe550fd8502f1785c1927aa84e5949eb',
- name: '0eb20a4a7cac2ebea821d420b3279654fe550fd8502f1785c1927aa84e5949eb',
- revision: '3d4b49a7bbb36c48bb721f4d0e76e7950bec3878ee29cdfdd6da39f575d6d37f',
- shortRevision: '3d4b49a7b',
- createdAt: '2022-02-17T17:37:52+00:00',
- totalSize: '48655767',
- },
- ],
- totalCount: 100,
- pageInfo: {
- hasNextPage: false,
- hasPreviousPage: false,
+export const MOCK_SHA_DIGEST = 'mock_sha_digest_value';
+
+export const harborImageDetailResponse = {
+ artifactCount: 10,
+ creationTime: '2022-03-02T06:35:53.205Z',
+ id: 25,
+ name: 'shao/flinkx',
+ projectId: 21,
+ pullCount: 0,
+ updateTime: '2022-03-02T06:35:53.205Z',
+ location: 'demo.harbor.com/gitlab-cn/build/cng-images/gitlab-kas',
+};
+
+export const harborArtifactsResponse = [
+ {
+ id: 1,
+ digest: `sha256:${MOCK_SHA_DIGEST}`,
+ size: 773928,
+ push_time: '2022-05-19T15:54:47.821Z',
+ tags: ['latest'],
+ },
+];
+
+export const harborArtifactsList = [
+ {
+ id: 1,
+ digest: `sha256:${MOCK_SHA_DIGEST}`,
+ size: 773928,
+ pushTime: '2022-05-19T15:54:47.821Z',
+ tags: ['latest'],
+ },
+];
+
+export const harborTagsResponse = [
+ {
+ repository_id: 4,
+ artifact_id: 5,
+ id: 4,
+ name: 'latest',
+ pull_time: '0001-01-01T00:00:00.000Z',
+ push_time: '2022-05-27T18:21:27.903Z',
+ signed: false,
+ immutable: false,
+ },
+];
+
+export const harborTagsList = [
+ {
+ repositoryId: 4,
+ artifactId: 5,
+ id: 4,
+ name: 'latest',
+ pullTime: '0001-01-01T00:00:00.000Z',
+ pushTime: '2022-05-27T18:21:27.903Z',
+ signed: false,
+ immutable: false,
},
+];
+
+export const defaultConfig = {
+ noContainersImage: 'noContainersImage',
+ repositoryUrl: 'demo.harbor.com',
+ harborIntegrationProjectName: 'test-project',
+ projectName: 'Flight',
+ endpoint: '/flightjs/Flight/-/harbor/repositories',
+ connectionError: false,
+ invalidPathError: false,
+ isGroupPage: false,
+ containersErrorImage: 'containersErrorImage',
};
+export const defaultFullPath = 'flightjs/Flight';
+
+export const harborImagesResponse = [
+ {
+ id: 1,
+ name: 'nginx/nginx',
+ artifact_count: 1,
+ creation_time: '2022-05-29T10:07:16.812Z',
+ update_time: '2022-05-29T10:07:16.812Z',
+ project_id: 4,
+ pull_count: 0,
+ location: 'https://demo.goharbor.io/harbor/projects/4/repositories/nginx',
+ },
+];
+
+export const harborImagesList = [
+ {
+ id: 1,
+ name: 'nginx/nginx',
+ artifactCount: 1,
+ creationTime: '2022-05-29T10:07:16.812Z',
+ updateTime: '2022-05-29T10:07:16.812Z',
+ projectId: 4,
+ pullCount: 0,
+ location: 'https://demo.goharbor.io/harbor/projects/4/repositories/nginx',
+ },
+];
+
export const dockerCommands = {
dockerBuildCommand: 'foofoo',
dockerPushCommand: 'barbar',
dockerLoginCommand: 'bazbaz',
};
+
+export const mockArtifactDetail = {
+ project: 'test-project',
+ image: 'test-repository',
+ digest: `sha256:${MOCK_SHA_DIGEST}`,
+};
diff --git a/spec/frontend/packages_and_registries/harbor_registry/pages/details_spec.js b/spec/frontend/packages_and_registries/harbor_registry/pages/details_spec.js
new file mode 100644
index 00000000000..8fd50bea280
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/pages/details_spec.js
@@ -0,0 +1,162 @@
+import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import { GlFilteredSearchToken } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import HarborDetailsPage from '~/packages_and_registries/harbor_registry/pages/details.vue';
+import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue';
+import ArtifactsList from '~/packages_and_registries/harbor_registry/components/details/artifacts_list.vue';
+import waitForPromises from 'helpers/wait_for_promises';
+import DetailsHeader from '~/packages_and_registries/harbor_registry/components/details/details_header.vue';
+import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
+import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import {
+ NAME_SORT_FIELD,
+ TOKEN_TYPE_TAG_NAME,
+} from '~/packages_and_registries/harbor_registry/constants/index';
+import { harborArtifactsResponse, harborArtifactsList, defaultConfig } from '../mock_data';
+
+let mockHarborArtifactsResponse;
+
+jest.mock('~/rest_api', () => ({
+ getHarborArtifacts: () => mockHarborArtifactsResponse,
+}));
+
+describe('Harbor Details Page', () => {
+ let wrapper;
+
+ const findTagsLoader = () => wrapper.findComponent(TagsLoader);
+ const findArtifactsList = () => wrapper.findComponent(ArtifactsList);
+ const findDetailsHeader = () => wrapper.findComponent(DetailsHeader);
+ const findPersistedSearch = () => wrapper.findComponent(PersistedSearch);
+
+ const waitForHarborDetailRequest = async () => {
+ await waitForPromises();
+ await nextTick();
+ };
+
+ const $route = {
+ params: {
+ project: 'test-project',
+ image: 'test-repository',
+ },
+ };
+
+ const breadCrumbState = {
+ updateName: jest.fn(),
+ updateHref: jest.fn(),
+ };
+
+ const defaultHeaders = {
+ 'x-page': '1',
+ 'X-Per-Page': '20',
+ 'X-TOTAL': '1',
+ 'X-Total-Pages': '1',
+ };
+
+ const mountComponent = ({ config = defaultConfig } = {}) => {
+ wrapper = shallowMount(HarborDetailsPage, {
+ mocks: {
+ $route,
+ },
+ provide() {
+ return {
+ breadCrumbState,
+ ...config,
+ };
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mockHarborArtifactsResponse = Promise.resolve({
+ data: harborArtifactsResponse,
+ headers: defaultHeaders,
+ });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when isLoading is true', () => {
+ it('shows the loader', () => {
+ mountComponent();
+
+ expect(findTagsLoader().exists()).toBe(true);
+ });
+
+ it('does not show the list', () => {
+ mountComponent();
+
+ expect(findArtifactsList().exists()).toBe(false);
+ });
+ });
+
+ describe('artifacts list', () => {
+ it('exists', async () => {
+ mountComponent();
+
+ findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] });
+ await waitForHarborDetailRequest();
+
+ expect(findArtifactsList().exists()).toBe(true);
+ });
+
+ it('has the correct props bound', async () => {
+ mountComponent();
+
+ findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] });
+ await waitForHarborDetailRequest();
+
+ expect(findArtifactsList().props()).toMatchObject({
+ isLoading: false,
+ filter: '',
+ artifacts: harborArtifactsList,
+ pageInfo: {
+ page: 1,
+ perPage: 20,
+ total: 1,
+ totalPages: 1,
+ },
+ });
+ });
+ });
+
+ describe('persisted search', () => {
+ it('has the correct props', () => {
+ mountComponent();
+
+ expect(findPersistedSearch().props()).toMatchObject({
+ sortableFields: [NAME_SORT_FIELD],
+ defaultOrder: NAME_SORT_FIELD.orderBy,
+ defaultSort: 'asc',
+ tokens: [
+ {
+ type: TOKEN_TYPE_TAG_NAME,
+ icon: 'tag',
+ title: s__('HarborRegistry|Tag'),
+ unique: true,
+ token: GlFilteredSearchToken,
+ operators: OPERATOR_IS_ONLY,
+ },
+ ],
+ });
+ });
+ });
+
+ describe('header', () => {
+ it('has the correct props', async () => {
+ mountComponent();
+
+ findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] });
+ await waitForHarborDetailRequest();
+
+ expect(findDetailsHeader().props()).toMatchObject({
+ imagesDetail: {
+ name: 'test-project/test-repository',
+ artifactCount: 1,
+ },
+ });
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/harbor_registry/pages/index_spec.js b/spec/frontend/packages_and_registries/harbor_registry/pages/index_spec.js
index 55fc8066f65..942cf9bad2c 100644
--- a/spec/frontend/packages_and_registries/harbor_registry/pages/index_spec.js
+++ b/spec/frontend/packages_and_registries/harbor_registry/pages/index_spec.js
@@ -4,7 +4,7 @@ import component from '~/packages_and_registries/harbor_registry/pages/index.vue
describe('List Page', () => {
let wrapper;
- const findRouterView = () => wrapper.find({ ref: 'router-view' });
+ const findRouterView = () => wrapper.findComponent({ ref: 'router-view' });
const mountComponent = () => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/packages_and_registries/harbor_registry/pages/list_spec.js b/spec/frontend/packages_and_registries/harbor_registry/pages/list_spec.js
index 61ee36a2794..97d30e6fe99 100644
--- a/spec/frontend/packages_and_registries/harbor_registry/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/harbor_registry/pages/list_spec.js
@@ -5,15 +5,14 @@ import HarborListHeader from '~/packages_and_registries/harbor_registry/componen
import HarborRegistryList from '~/packages_and_registries/harbor_registry/pages/list.vue';
import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import waitForPromises from 'helpers/wait_for_promises';
-// import { harborListResponse } from '~/packages_and_registries/harbor_registry/mock_api.js';
import HarborList from '~/packages_and_registries/harbor_registry/components/list/harbor_list.vue';
import CliCommands from '~/packages_and_registries/shared/components/cli_commands.vue';
import { SORT_FIELDS } from '~/packages_and_registries/harbor_registry/constants/index';
-import { harborListResponse, dockerCommands } from '../mock_data';
+import { harborImagesResponse, defaultConfig, harborImagesList } from '../mock_data';
let mockHarborListResponse;
-jest.mock('~/packages_and_registries/harbor_registry/mock_api.js', () => ({
- harborListResponse: () => mockHarborListResponse,
+jest.mock('~/rest_api', () => ({
+ getHarborRepositoriesList: () => mockHarborListResponse,
}));
describe('Harbor List Page', () => {
@@ -24,34 +23,43 @@ describe('Harbor List Page', () => {
await nextTick();
};
- beforeEach(() => {
- mockHarborListResponse = Promise.resolve(harborListResponse);
- });
-
const findHarborListHeader = () => wrapper.findComponent(HarborListHeader);
const findPersistedSearch = () => wrapper.findComponent(PersistedSearch);
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findHarborList = () => wrapper.findComponent(HarborList);
const findCliCommands = () => wrapper.findComponent(CliCommands);
+ const defaultHeaders = {
+ 'x-page': '1',
+ 'X-Per-Page': '20',
+ 'X-TOTAL': '1',
+ 'X-Total-Pages': '1',
+ };
+
const fireFirstSortUpdate = () => {
findPersistedSearch().vm.$emit('update', { sort: 'UPDATED_DESC', filters: [] });
};
- const mountComponent = ({ config = { isGroupPage: false } } = {}) => {
+ const mountComponent = ({ config = defaultConfig } = {}) => {
wrapper = shallowMount(HarborRegistryList, {
stubs: {
HarborListHeader,
},
provide() {
return {
- config,
- ...dockerCommands,
+ ...config,
};
},
});
};
+ beforeEach(() => {
+ mockHarborListResponse = Promise.resolve({
+ data: harborImagesResponse,
+ headers: defaultHeaders,
+ });
+ });
+
afterEach(() => {
wrapper.destroy();
});
@@ -64,7 +72,7 @@ describe('Harbor List Page', () => {
expect(findHarborListHeader().exists()).toBe(true);
expect(findHarborListHeader().props()).toMatchObject({
- imagesCount: 3,
+ imagesCount: 1,
metadataLoading: false,
});
});
@@ -117,6 +125,16 @@ describe('Harbor List Page', () => {
await nextTick();
expect(findHarborList().exists()).toBe(true);
+ expect(findHarborList().props()).toMatchObject({
+ images: harborImagesList,
+ metadataLoading: false,
+ pageInfo: {
+ page: 1,
+ perPage: 20,
+ total: 1,
+ totalPages: 1,
+ },
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/harbor_registry/pages/tags_spec.js b/spec/frontend/packages_and_registries/harbor_registry/pages/tags_spec.js
new file mode 100644
index 00000000000..7e0f05e736b
--- /dev/null
+++ b/spec/frontend/packages_and_registries/harbor_registry/pages/tags_spec.js
@@ -0,0 +1,125 @@
+import { nextTick } from 'vue';
+import { shallowMount } from '@vue/test-utils';
+import HarborTagsPage from '~/packages_and_registries/harbor_registry/pages/harbor_tags.vue';
+import TagsHeader from '~/packages_and_registries/harbor_registry/components/tags/tags_header.vue';
+import TagsList from '~/packages_and_registries/harbor_registry/components/tags/tags_list.vue';
+import waitForPromises from 'helpers/wait_for_promises';
+import { defaultConfig, harborTagsResponse, mockArtifactDetail } from '../mock_data';
+
+let mockHarborTagsResponse;
+
+jest.mock('~/rest_api', () => ({
+ getHarborTags: () => mockHarborTagsResponse,
+}));
+
+describe('Harbor Tags page', () => {
+ let wrapper;
+
+ const findTagsHeader = () => wrapper.find(TagsHeader);
+ const findTagsList = () => wrapper.find(TagsList);
+
+ const waitForHarborTagsRequest = async () => {
+ await waitForPromises();
+ await nextTick();
+ };
+
+ const breadCrumbState = {
+ updateName: jest.fn(),
+ updateHref: jest.fn(),
+ };
+
+ const $route = {
+ params: mockArtifactDetail,
+ };
+
+ const defaultHeaders = {
+ 'x-page': '1',
+ 'X-Per-Page': '20',
+ 'X-TOTAL': '1',
+ 'X-Total-Pages': '1',
+ };
+
+ const mountComponent = ({ endpoint = defaultConfig.endpoint } = {}) => {
+ wrapper = shallowMount(HarborTagsPage, {
+ mocks: {
+ $route,
+ },
+ provide() {
+ return {
+ breadCrumbState,
+ endpoint,
+ };
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mockHarborTagsResponse = Promise.resolve({
+ data: harborTagsResponse,
+ headers: defaultHeaders,
+ });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('contains tags header', () => {
+ mountComponent();
+
+ expect(findTagsHeader().exists()).toBe(true);
+ });
+
+ it('contains tags list', () => {
+ mountComponent();
+
+ expect(findTagsList().exists()).toBe(true);
+ });
+
+ describe('header', () => {
+ it('has the correct props', async () => {
+ mountComponent();
+
+ await waitForHarborTagsRequest();
+ expect(findTagsHeader().props()).toMatchObject({
+ artifactDetail: mockArtifactDetail,
+ pageInfo: {
+ page: 1,
+ perPage: 20,
+ total: 1,
+ totalPages: 1,
+ },
+ tagsLoading: false,
+ });
+ });
+ });
+
+ describe('list', () => {
+ it('has the correct props', async () => {
+ mountComponent();
+
+ await waitForHarborTagsRequest();
+ expect(findTagsList().props()).toMatchObject({
+ tags: [
+ {
+ repositoryId: 4,
+ artifactId: 5,
+ id: 4,
+ name: 'latest',
+ pullTime: '0001-01-01T00:00:00.000Z',
+ pushTime: '2022-05-27T18:21:27.903Z',
+ signed: false,
+ immutable: false,
+ },
+ ],
+ isLoading: false,
+ pageInfo: {
+ page: 1,
+ perPage: 20,
+ total: 1,
+ totalPages: 1,
+ },
+ });
+ });
+ });
+});