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')
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js76
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js54
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js21
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js100
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js19
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap5
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap8
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js8
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap14
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap5
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap42
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap14
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap14
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap24
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js8
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js23
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js30
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js28
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js18
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js22
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap10
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js23
-rw-r--r--spec/frontend/packages_and_registries/package_registry/mock_data.js11
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap8
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/details_spec.js (renamed from spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js)38
-rw-r--r--spec/frontend/packages_and_registries/shared/components/__snapshots__/publish_method_spec.js.snap (renamed from spec/frontend/packages_and_registries/shared/__snapshots__/publish_method_spec.js.snap)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/__snapshots__/registry_breadcrumb_spec.js.snap (renamed from spec/frontend/packages_and_registries/container_registry/explorer/components/__snapshots__/registry_breadcrumb_spec.js.snap)38
-rw-r--r--spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js (renamed from spec/frontend/packages_and_registries/shared/package_icon_and_name_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/package_path_spec.js (renamed from spec/frontend/packages_and_registries/shared/package_path_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/package_tags_spec.js (renamed from spec/frontend/packages_and_registries/shared/package_tags_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/packages_list_loader_spec.js (renamed from spec/frontend/packages_and_registries/shared/packages_list_loader_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js145
-rw-r--r--spec/frontend/packages_and_registries/shared/components/publish_method_spec.js (renamed from spec/frontend/packages_and_registries/shared/publish_method_spec.js)0
-rw-r--r--spec/frontend/packages_and_registries/shared/components/registry_breadcrumb_spec.js (renamed from spec/frontend/packages_and_registries/container_registry/explorer/components/registry_breadcrumb_spec.js)2
37 files changed, 558 insertions, 256 deletions
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
index f06300efa29..5278e730ec9 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
@@ -1,7 +1,6 @@
-import { GlDropdownItem, GlIcon } from '@gitlab/ui';
+import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
-import { GlDropdown } from 'jest/packages_and_registries/container_registry/explorer/stubs';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -51,6 +50,7 @@ describe('Details Header', () => {
const findCleanup = () => findByTestId('cleanup');
const findDeleteButton = () => wrapper.findComponent(GlDropdownItem);
const findInfoIcon = () => wrapper.findComponent(GlIcon);
+ const findMenu = () => wrapper.findComponent(GlDropdown);
const waitForMetadataItems = async () => {
// Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available
@@ -139,51 +139,53 @@ describe('Details Header', () => {
});
});
- describe('delete button', () => {
- it('exists', () => {
- mountComponent();
+ describe('menu', () => {
+ it.each`
+ canDelete | disabled | isVisible
+ ${true} | ${false} | ${true}
+ ${true} | ${true} | ${false}
+ ${false} | ${false} | ${false}
+ ${false} | ${true} | ${false}
+ `(
+ 'when canDelete is $canDelete and disabled is $disabled is $isVisible that the menu is visible',
+ ({ canDelete, disabled, isVisible }) => {
+ mountComponent({ propsData: { image: { ...defaultImage, canDelete }, disabled } });
- expect(findDeleteButton().exists()).toBe(true);
- });
+ expect(findMenu().exists()).toBe(isVisible);
+ },
+ );
- it('has the correct text', () => {
- mountComponent();
+ describe('delete button', () => {
+ it('exists', () => {
+ mountComponent();
- expect(findDeleteButton().text()).toBe('Delete image repository');
- });
+ expect(findDeleteButton().exists()).toBe(true);
+ });
- it('has the correct props', () => {
- mountComponent();
+ it('has the correct text', () => {
+ mountComponent();
- expect(findDeleteButton().attributes()).toMatchObject(
- expect.objectContaining({
- variant: 'danger',
- }),
- );
- });
+ expect(findDeleteButton().text()).toBe('Delete image repository');
+ });
- it('emits the correct event', () => {
- mountComponent();
+ it('has the correct props', () => {
+ mountComponent();
- findDeleteButton().vm.$emit('click');
+ expect(findDeleteButton().attributes()).toMatchObject(
+ expect.objectContaining({
+ variant: 'danger',
+ }),
+ );
+ });
- expect(wrapper.emitted('delete')).toEqual([[]]);
- });
+ it('emits the correct event', () => {
+ mountComponent();
- it.each`
- canDelete | disabled | isDisabled
- ${true} | ${false} | ${undefined}
- ${true} | ${true} | ${'true'}
- ${false} | ${false} | ${'true'}
- ${false} | ${true} | ${'true'}
- `(
- 'when canDelete is $canDelete and disabled is $disabled is $isDisabled that the button is disabled',
- ({ canDelete, disabled, isDisabled }) => {
- mountComponent({ propsData: { image: { ...defaultImage, canDelete }, disabled } });
+ findDeleteButton().vm.$emit('click');
- expect(findDeleteButton().attributes('disabled')).toBe(isDisabled);
- },
- );
+ expect(wrapper.emitted('delete')).toEqual([[]]);
+ });
+ });
});
describe('metadata items', () => {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js
deleted file mode 100644
index f14284e9efe..00000000000
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { GlEmptyState } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import component from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
-import {
- NO_TAGS_TITLE,
- NO_TAGS_MESSAGE,
- MISSING_OR_DELETED_IMAGE_TITLE,
- MISSING_OR_DELETED_IMAGE_MESSAGE,
-} from '~/packages_and_registries/container_registry/explorer/constants';
-
-describe('EmptyTagsState component', () => {
- let wrapper;
-
- const findEmptyState = () => wrapper.find(GlEmptyState);
-
- const mountComponent = (propsData) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlEmptyState,
- },
- propsData,
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- it('contains gl-empty-state', () => {
- mountComponent();
- expect(findEmptyState().exists()).toBe(true);
- });
-
- it.each`
- isEmptyImage | title | description
- ${false} | ${NO_TAGS_TITLE} | ${NO_TAGS_MESSAGE}
- ${true} | ${MISSING_OR_DELETED_IMAGE_TITLE} | ${MISSING_OR_DELETED_IMAGE_MESSAGE}
- `(
- 'when isEmptyImage is $isEmptyImage has the correct props',
- ({ isEmptyImage, title, description }) => {
- mountComponent({
- noContainersImage: 'foo',
- isEmptyImage,
- });
-
- expect(findEmptyState().props()).toMatchObject({
- title,
- description,
- svgPath: 'foo',
- });
- },
- );
-});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
index 00b1d03b7c2..057312828ff 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js
@@ -75,16 +75,19 @@ describe('tags list row', () => {
});
it.each`
- digest | disabled
- ${'foo'} | ${true}
- ${null} | ${false}
- ${null} | ${true}
- ${'foo'} | ${true}
- `('is disabled when the digest $digest and disabled is $disabled', ({ digest, disabled }) => {
- mountComponent({ tag: { ...tag, digest }, disabled });
+ digest | disabled | isDisabled
+ ${'foo'} | ${true} | ${'true'}
+ ${null} | ${true} | ${'true'}
+ ${null} | ${false} | ${undefined}
+ ${'foo'} | ${false} | ${undefined}
+ `(
+ 'disabled attribute is set to $isDisabled when the digest $digest and disabled is $disabled',
+ ({ digest, disabled, isDisabled }) => {
+ mountComponent({ tag: { ...tag, digest }, disabled });
- expect(findCheckbox().attributes('disabled')).toBe('true');
- });
+ expect(findCheckbox().attributes('disabled')).toBe(isDisabled);
+ },
+ );
it('is wired to the selected prop', () => {
mountComponent({ ...defaultProps, selected: true });
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
index 56f12e2f0bb..0dcf988c814 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
@@ -1,16 +1,25 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { GlEmptyState } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { stripTypenames } from 'helpers/graphql_helpers';
-import EmptyTagsState from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
+
import component from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue';
import TagsListRow from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue';
import TagsLoader from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_loader.vue';
import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import getContainerRepositoryTagsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql';
-import { GRAPHQL_PAGE_SIZE } from '~/packages_and_registries/container_registry/explorer/constants/index';
+import {
+ GRAPHQL_PAGE_SIZE,
+ NO_TAGS_TITLE,
+ NO_TAGS_MESSAGE,
+ NO_TAGS_MATCHING_FILTERS_TITLE,
+ NO_TAGS_MATCHING_FILTERS_DESCRIPTION,
+} from '~/packages_and_registries/container_registry/explorer/constants/index';
+import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import { tagsMock, imageTagsMock, tagsPageInfo } from '../../mock_data';
const localVue = createLocalVue();
@@ -21,11 +30,20 @@ describe('Tags List', () => {
let resolver;
const tags = [...tagsMock];
+ const defaultConfig = {
+ noContainersImage: 'noContainersImage',
+ };
+
+ const findPersistedSearch = () => wrapper.findComponent(PersistedSearch);
const findTagsListRow = () => wrapper.findAllComponents(TagsListRow);
const findRegistryList = () => wrapper.findComponent(RegistryList);
- const findEmptyState = () => wrapper.findComponent(EmptyTagsState);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findTagsLoader = () => wrapper.findComponent(TagsLoader);
+ const fireFirstSortUpdate = () => {
+ findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] });
+ };
+
const waitForApolloRequestRender = async () => {
await waitForPromises();
await nextTick();
@@ -44,7 +62,7 @@ describe('Tags List', () => {
stubs: { RegistryList },
provide() {
return {
- config: {},
+ config: defaultConfig,
};
},
});
@@ -61,10 +79,23 @@ describe('Tags List', () => {
describe('registry list', () => {
beforeEach(() => {
mountComponent();
-
+ fireFirstSortUpdate();
return waitForApolloRequestRender();
});
+ it('has a persisted search', () => {
+ expect(findPersistedSearch().props()).toMatchObject({
+ defaultOrder: 'NAME',
+ defaultSort: 'asc',
+ sortableFields: [
+ {
+ label: 'Name',
+ orderBy: 'NAME',
+ },
+ ],
+ });
+ });
+
it('binds the correct props', () => {
expect(findRegistryList().props()).toMatchObject({
title: '2 tags',
@@ -75,11 +106,13 @@ describe('Tags List', () => {
});
describe('events', () => {
- it('prev-page fetch the previous page', () => {
+ it('prev-page fetch the previous page', async () => {
findRegistryList().vm.$emit('prev-page');
expect(resolver).toHaveBeenCalledWith({
first: null,
+ name: '',
+ sort: 'NAME_ASC',
before: tagsPageInfo.startCursor,
last: GRAPHQL_PAGE_SIZE,
id: '1',
@@ -92,6 +125,8 @@ describe('Tags List', () => {
expect(resolver).toHaveBeenCalledWith({
after: tagsPageInfo.endCursor,
first: GRAPHQL_PAGE_SIZE,
+ name: '',
+ sort: 'NAME_ASC',
id: '1',
});
});
@@ -108,6 +143,7 @@ describe('Tags List', () => {
describe('list rows', () => {
it('one row exist for each tag', async () => {
mountComponent();
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -116,6 +152,7 @@ describe('Tags List', () => {
it('the correct props are bound to it', async () => {
mountComponent({ propsData: { disabled: true, id: 1 } });
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -130,7 +167,7 @@ describe('Tags List', () => {
describe('events', () => {
it('select event update the selected items', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findTagsListRow().at(0).vm.$emit('select');
@@ -142,7 +179,7 @@ describe('Tags List', () => {
it('delete event emit a delete event', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findTagsListRow().at(0).vm.$emit('delete');
@@ -154,32 +191,45 @@ describe('Tags List', () => {
describe('when the list of tags is empty', () => {
beforeEach(() => {
resolver = jest.fn().mockResolvedValue(imageTagsMock([]));
- });
-
- it('has the empty state', async () => {
mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findEmptyState().exists()).toBe(true);
+ fireFirstSortUpdate();
+ return waitForApolloRequestRender();
});
- it('does not show the loader', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
+ it('does not show the loader', () => {
expect(findTagsLoader().exists()).toBe(false);
});
- it('does not show the list', async () => {
- mountComponent();
+ it('does not show the list', () => {
+ expect(findRegistryList().exists()).toBe(false);
+ });
- await waitForApolloRequestRender();
+ describe('empty state', () => {
+ it('default empty state', () => {
+ expect(findEmptyState().props()).toMatchObject({
+ svgPath: defaultConfig.noContainersImage,
+ title: NO_TAGS_TITLE,
+ description: NO_TAGS_MESSAGE,
+ });
+ });
- expect(findRegistryList().exists()).toBe(false);
+ it('when filtered shows a filtered message', async () => {
+ findPersistedSearch().vm.$emit('update', {
+ sort: 'NAME_ASC',
+ filters: [{ type: FILTERED_SEARCH_TERM, value: { data: 'foo' } }],
+ });
+
+ await waitForApolloRequestRender();
+
+ expect(findEmptyState().props()).toMatchObject({
+ svgPath: defaultConfig.noContainersImage,
+ title: NO_TAGS_MATCHING_FILTERS_TITLE,
+ description: NO_TAGS_MATCHING_FILTERS_DESCRIPTION,
+ });
+ });
});
});
+
describe('loading state', () => {
it.each`
isImageLoading | queryExecuting | loadingVisible
@@ -191,7 +241,7 @@ describe('Tags List', () => {
'when the isImageLoading is $isImageLoading, and is $queryExecuting that the query is still executing is $loadingVisible that the loader is shown',
async ({ isImageLoading, queryExecuting, loadingVisible }) => {
mountComponent({ propsData: { isImageLoading, isMobile: false, id: 1 } });
-
+ fireFirstSortUpdate();
if (!queryExecuting) {
await waitForApolloRequestRender();
}
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
index 9b821ba8ef3..7992bead60a 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
@@ -1,4 +1,4 @@
-import { GlKeysetPagination } from '@gitlab/ui';
+import { GlKeysetPagination, GlEmptyState } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
@@ -8,7 +8,6 @@ import axios from '~/lib/utils/axios_utils';
import DeleteImage from '~/packages_and_registries/container_registry/explorer/components/delete_image.vue';
import DeleteAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue';
import DetailsHeader from '~/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue';
-import EmptyTagsState from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
import PartialCleanupAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert.vue';
import StatusAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/status_alert.vue';
import TagsList from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue';
@@ -20,6 +19,8 @@ import {
ALERT_DANGER_IMAGE,
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
ROOT_IMAGE_TEXT,
+ MISSING_OR_DELETED_IMAGE_TITLE,
+ MISSING_OR_DELETED_IMAGE_MESSAGE,
} from '~/packages_and_registries/container_registry/explorer/constants';
import deleteContainerRepositoryTagsMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql';
import getContainerRepositoryDetailsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_details.query.graphql';
@@ -50,7 +51,7 @@ describe('Details Page', () => {
const findTagsList = () => wrapper.find(TagsList);
const findDeleteAlert = () => wrapper.find(DeleteAlert);
const findDetailsHeader = () => wrapper.find(DetailsHeader);
- const findEmptyState = () => wrapper.find(EmptyTagsState);
+ const findEmptyState = () => wrapper.find(GlEmptyState);
const findPartialCleanupAlert = () => wrapper.find(PartialCleanupAlert);
const findStatusAlert = () => wrapper.find(StatusAlert);
const findDeleteImage = () => wrapper.find(DeleteImage);
@@ -61,6 +62,10 @@ describe('Details Page', () => {
updateName: jest.fn(),
};
+ const defaultConfig = {
+ noContainersImage: 'noContainersImage',
+ };
+
const cleanTags = tagsMock.map((t) => {
const result = { ...t };
// eslint-disable-next-line no-underscore-dangle
@@ -78,7 +83,7 @@ describe('Details Page', () => {
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock),
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock)),
options,
- config = {},
+ config = defaultConfig,
} = {}) => {
localVue.use(VueApollo);
@@ -154,7 +159,11 @@ describe('Details Page', () => {
await waitForApolloRequestRender();
- expect(findEmptyState().exists()).toBe(true);
+ expect(findEmptyState().props()).toMatchObject({
+ description: MISSING_OR_DELETED_IMAGE_MESSAGE,
+ svgPath: defaultConfig.noContainersImage,
+ title: MISSING_OR_DELETED_IMAGE_TITLE,
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
index 881d441e116..f95564e3fad 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/__snapshots__/file_sha_spec.js.snap
@@ -15,11 +15,14 @@ exports[`FileSha renders 1`] = `
foo
<gl-button-stub
- aria-label="Copy this value"
+ aria-label="Copy SHA"
+ aria-live="polite"
buttontextclasses=""
category="tertiary"
+ data-clipboard-handle-tooltip="false"
data-clipboard-text="foo"
icon="copy-to-clipboard"
+ id="clipboard-button-1"
size="small"
title="Copy SHA"
variant="default"
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
index 9ce590bfb51..d7caa8ca2d8 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/file_sha_spec.js
@@ -4,6 +4,8 @@ import FileSha from '~/packages_and_registries/infrastructure_registry/details/c
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+jest.mock('lodash/uniqueId', () => (prefix) => (prefix ? `${prefix}1` : 1));
+
describe('FileSha', () => {
let wrapper;
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
index 99a7b8e427a..7cdf21dde46 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
@@ -10,10 +10,10 @@ exports[`packages_list_app renders 1`] = `
<div>
<section
- class="row empty-state text-center"
+ class="gl-display-flex empty-state gl-text-center gl-flex-direction-column"
>
<div
- class="col-12"
+ class="gl-max-w-full"
>
<div
class="svg-250 svg-content"
@@ -28,10 +28,10 @@ exports[`packages_list_app renders 1`] = `
</div>
<div
- class="col-12"
+ class="gl-max-w-full gl-m-auto"
>
<div
- class="text-content gl-mx-auto gl-my-0 gl-p-5"
+ class="gl-mx-auto gl-my-0 gl-p-5"
>
<h1
class="gl-font-size-h-display gl-line-height-36 h4"
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
index 2fb76b98925..26569f20e94 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
@@ -134,6 +134,8 @@ describe('packages_list', () => {
});
it('deleteItemConfirmation resets itemToBeDeleted', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted: 1 });
wrapper.vm.deleteItemConfirmation();
expect(wrapper.vm.itemToBeDeleted).toEqual(null);
@@ -141,6 +143,8 @@ describe('packages_list', () => {
it('deleteItemConfirmation emit package:delete', () => {
const itemToBeDeleted = { id: 2 };
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted });
wrapper.vm.deleteItemConfirmation();
return wrapper.vm.$nextTick(() => {
@@ -149,6 +153,8 @@ describe('packages_list', () => {
});
it('deleteItemCanceled resets itemToBeDeleted', () => {
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted: 1 });
wrapper.vm.deleteItemCanceled();
expect(wrapper.vm.itemToBeDeleted).toEqual(null);
@@ -194,6 +200,8 @@ describe('packages_list', () => {
beforeEach(() => {
mountComponent();
eventSpy = jest.spyOn(Tracking, 'event');
+ // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
+ // eslint-disable-next-line no-restricted-syntax
wrapper.setData({ itemToBeDeleted: { package_type: 'conan' } });
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap
index e9f80d5f512..b3d0d88be4d 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/conan_installation_spec.js.snap
@@ -23,14 +23,18 @@ exports[`ConanInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy Conan Setup Command"
- instruction="conan remote add gitlab conanPath"
+ instruction="conan remote add gitlab http://gdk.test:3000/api/v4/projects/1/packages/conan"
label="Add Conan Remote"
trackingaction="copy_conan_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the Conan registry,
+ <gl-link-stub
+ href="/help/user/packages/conan_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap
index 881d441e116..f95564e3fad 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/file_sha_spec.js.snap
@@ -15,11 +15,14 @@ exports[`FileSha renders 1`] = `
foo
<gl-button-stub
- aria-label="Copy this value"
+ aria-label="Copy SHA"
+ aria-live="polite"
buttontextclasses=""
category="tertiary"
+ data-clipboard-handle-tooltip="false"
data-clipboard-text="foo"
icon="copy-to-clipboard"
+ id="clipboard-button-1"
size="small"
title="Copy SHA"
variant="default"
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap
index 4865b8205ab..67f1906f6fd 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/maven_installation_spec.js.snap
@@ -19,7 +19,7 @@ exports[`MavenInstallation groovy renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy add Gradle Groovy DSL repository command"
instruction="maven {
- url 'mavenPath'
+ url 'http://gdk.test:3000/api/v4/projects/1/packages/maven'
}"
label="Add Gradle Groovy DSL repository command"
multiline="true"
@@ -47,7 +47,7 @@ exports[`MavenInstallation kotlin renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy add Gradle Kotlin DSL repository command"
- instruction="maven(\\"mavenPath\\")"
+ instruction="maven(\\"http://gdk.test:3000/api/v4/projects/1/packages/maven\\")"
label="Add Gradle Kotlin DSL repository command"
multiline="true"
trackingaction="copy_kotlin_add_to_source_command"
@@ -64,9 +64,15 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
/>
<p>
- <gl-sprintf-stub
- message="Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
- />
+ Copy and paste this inside your
+ <code>
+ pom.xml
+ </code>
+
+ <code>
+ dependencies
+ </code>
+ block.
</p>
<code-instruction-stub
@@ -97,9 +103,11 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
</h3>
<p>
- <gl-sprintf-stub
- message="If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
- />
+ If you haven't already done so, you will need to add the below to your
+ <code>
+ pom.xml
+ </code>
+ file.
</p>
<code-instruction-stub
@@ -107,19 +115,19 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
instruction="<repositories>
<repository>
<id>gitlab-maven</id>
- <url>mavenPath</url>
+ <url>http://gdk.test:3000/api/v4/projects/1/packages/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
- <url>mavenPath</url>
+ <url>http://gdk.test:3000/api/v4/projects/1/packages/maven</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
- <url>mavenPath</url>
+ <url>http://gdk.test:3000/api/v4/projects/1/packages/maven</url>
</snapshotRepository>
</distributionManagement>"
label=""
@@ -127,9 +135,13 @@ exports[`MavenInstallation maven renders all the messages 1`] = `
trackingaction="copy_maven_setup_xml"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the Maven registry,
+ <gl-link-stub
+ href="/help/user/packages/maven_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap
index d5649e39561..4520ae9c328 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/npm_installation_spec.js.snap
@@ -32,14 +32,18 @@ exports[`NpmInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy npm setup command"
- instruction="echo @gitlab-org:registry=npmPath/ >> .npmrc"
+ instruction="echo @gitlab-org:registry=npmInstanceUrl/ >> .npmrc"
label=""
trackingaction="copy_npm_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
- />
+ You may also need to setup authentication using an auth token.
+ <gl-link-stub
+ href="/help/user/packages/npm_registry/index"
+ target="_blank"
+ >
+ See the documentation
+ </gl-link-stub>
+ to find out more.
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap
index 29ddd7b77ed..92930a6309a 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/nuget_installation_spec.js.snap
@@ -23,14 +23,18 @@ exports[`NugetInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy NuGet Setup Command"
- instruction="nuget source Add -Name \\"GitLab\\" -Source \\"nugetPath\\" -UserName <your_username> -Password <your_token>"
+ instruction="nuget source Add -Name \\"GitLab\\" -Source \\"http://gdk.test:3000/api/v4/projects/1/packages/nuget/index.json\\" -UserName <your_username> -Password <your_token>"
label="Add NuGet Source"
trackingaction="copy_nuget_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the NuGet registry,
+ <gl-link-stub
+ href="/help/user/packages/nuget_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
index 158bbbc3463..06ae8645101 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
@@ -10,7 +10,7 @@ exports[`PypiInstallation renders all the messages 1`] = `
<code-instruction-stub
copytext="Copy Pip command"
data-testid="pip-command"
- instruction="pip install @gitlab-org/package-15 --extra-index-url pypiPath"
+ instruction="pip install @gitlab-org/package-15 --extra-index-url http://__token__:<your_personal_token>@gdk.test:3000/api/v4/projects/1/packages/pypi/simple"
label="Pip Command"
trackingaction="copy_pip_install_command"
trackinglabel="code_instruction"
@@ -23,16 +23,18 @@ exports[`PypiInstallation renders all the messages 1`] = `
</h3>
<p>
- <gl-sprintf-stub
- message="If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
- />
+ If you haven't already done so, you will need to add the below to your
+ <code>
+ .pypirc
+ </code>
+ file.
</p>
<code-instruction-stub
copytext="Copy .pypirc content"
data-testid="pypi-setup-content"
instruction="[gitlab]
-repository = pypiSetupPath
+repository = http://gdk.test:3000/api/v4/projects/1/packages/pypi
username = __token__
password = <your personal access token>"
label=""
@@ -40,9 +42,13 @@ password = <your personal access token>"
trackingaction="copy_pypi_setup_command"
trackinglabel="code_instruction"
/>
-
- <gl-sprintf-stub
- message="For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
- />
+ For more information on the PyPi registry,
+ <gl-link-stub
+ href="/help/user/packages/pypi_repository/index"
+ target="_blank"
+ >
+ see the documentation
+ </gl-link-stub>
+ .
</div>
`;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js
index aedf20e873a..0aba8f7efc7 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/composer_installation_spec.js
@@ -7,6 +7,7 @@ import {
TRACKING_ACTION_COPY_COMPOSER_REGISTRY_INCLUDE_COMMAND,
TRACKING_ACTION_COPY_COMPOSER_PACKAGE_INCLUDE_COMMAND,
PACKAGE_TYPE_COMPOSER,
+ COMPOSER_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_COMPOSER };
@@ -24,9 +25,6 @@ describe('ComposerInstallation', () => {
function createComponent(groupListUrl = 'groupListUrl') {
wrapper = shallowMountExtended(ComposerInstallation, {
provide: {
- composerHelpPath: 'composerHelpPath',
- composerConfigRepositoryName: 'composerConfigRepositoryName',
- composerPath: 'composerPath',
groupListUrl,
},
propsData: { packageEntity },
@@ -61,7 +59,7 @@ describe('ComposerInstallation', () => {
const registryIncludeCommand = findRegistryInclude();
expect(registryIncludeCommand.exists()).toBe(true);
expect(registryIncludeCommand.props()).toMatchObject({
- instruction: `composer config repositories.composerConfigRepositoryName '{"type": "composer", "url": "composerPath"}'`,
+ instruction: `composer config repositories.${packageEntity.composerConfigRepositoryUrl} '{"type": "composer", "url": "${packageEntity.composerUrl}"}'`,
copyText: 'Copy registry include',
trackingAction: TRACKING_ACTION_COPY_COMPOSER_REGISTRY_INCLUDE_COMMAND,
});
@@ -96,7 +94,7 @@ describe('ComposerInstallation', () => {
'For more information on Composer packages in GitLab, see the documentation.',
);
expect(findHelpLink().attributes()).toMatchObject({
- href: 'composerHelpPath',
+ href: COMPOSER_HELP_PATH,
target: '_blank',
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js
index 6b642cc21b7..bf9425def9a 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/conan_installation_spec.js
@@ -1,8 +1,12 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { packageData } from 'jest/packages_and_registries/package_registry/mock_data';
import ConanInstallation from '~/packages_and_registries/package_registry/components/details/conan_installation.vue';
import InstallationTitle from '~/packages_and_registries/package_registry/components/details/installation_title.vue';
-import { PACKAGE_TYPE_CONAN } from '~/packages_and_registries/package_registry/constants';
+import {
+ PACKAGE_TYPE_CONAN,
+ CONAN_HELP_PATH,
+} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_CONAN };
@@ -12,16 +16,16 @@ describe('ConanInstallation', () => {
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent() {
wrapper = shallowMountExtended(ConanInstallation, {
- provide: {
- conanHelpPath: 'conanHelpPath',
- conanPath: 'conanPath',
- },
propsData: {
packageEntity,
},
+ stubs: {
+ GlSprintf,
+ },
});
}
@@ -58,8 +62,15 @@ describe('ConanInstallation', () => {
describe('setup commands', () => {
it('renders the correct command', () => {
expect(findCodeInstructions().at(1).props('instruction')).toBe(
- 'conan remote add gitlab conanPath',
+ `conan remote add gitlab ${packageEntity.conanUrl}`,
);
});
+
+ it('has a link to the docs', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: CONAN_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js
index ebfbbe5b864..feed7a7c46c 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/file_sha_spec.js
@@ -4,6 +4,8 @@ import FileSha from '~/packages_and_registries/package_registry/components/detai
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
+jest.mock('lodash/uniqueId', () => (prefix) => (prefix ? `${prefix}1` : 1));
+
describe('FileSha', () => {
let wrapper;
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js
index eed7e903833..fc60039db30 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/maven_installation_spec.js
@@ -1,3 +1,4 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -16,6 +17,7 @@ import {
TRACKING_ACTION_COPY_KOTLIN_INSTALL_COMMAND,
TRACKING_ACTION_COPY_KOTLIN_ADD_TO_SOURCE_COMMAND,
PACKAGE_TYPE_MAVEN,
+ MAVEN_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
@@ -28,9 +30,6 @@ describe('MavenInstallation', () => {
metadata: mavenMetadata(),
};
- const mavenHelpPath = 'mavenHelpPath';
- const mavenPath = 'mavenPath';
-
const xmlCodeBlock = `<dependency>
<groupId>appGroup</groupId>
<artifactId>appName</artifactId>
@@ -40,43 +39,43 @@ describe('MavenInstallation', () => {
const mavenSetupXml = `<repositories>
<repository>
<id>gitlab-maven</id>
- <url>${mavenPath}</url>
+ <url>${packageEntity.mavenUrl}</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
- <url>${mavenPath}</url>
+ <url>${packageEntity.mavenUrl}</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
- <url>${mavenPath}</url>
+ <url>${packageEntity.mavenUrl}</url>
</snapshotRepository>
</distributionManagement>`;
const gradleGroovyInstallCommandText = `implementation 'appGroup:appName:appVersion'`;
const gradleGroovyAddSourceCommandText = `maven {
- url '${mavenPath}'
+ url '${packageEntity.mavenUrl}'
}`;
const gradleKotlinInstallCommandText = `implementation("appGroup:appName:appVersion")`;
- const gradleKotlinAddSourceCommandText = `maven("${mavenPath}")`;
+ const gradleKotlinAddSourceCommandText = `maven("${packageEntity.mavenUrl}")`;
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent({ data = {} } = {}) {
wrapper = shallowMountExtended(MavenInstallation, {
- provide: {
- mavenHelpPath,
- mavenPath,
- },
propsData: {
packageEntity,
},
data() {
return data;
},
+ stubs: {
+ GlSprintf,
+ },
});
}
@@ -148,6 +147,13 @@ describe('MavenInstallation', () => {
trackingAction: TRACKING_ACTION_COPY_MAVEN_SETUP,
});
});
+
+ it('has a setup link', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: MAVEN_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js
index b89410ede13..8c0e2d948ca 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/npm_installation_spec.js
@@ -1,4 +1,4 @@
-import { GlFormRadioGroup } from '@gitlab/ui';
+import { GlLink, GlSprintf, GlFormRadioGroup } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -15,6 +15,7 @@ import {
YARN_PACKAGE_MANAGER,
PROJECT_PACKAGE_ENDPOINT_TYPE,
INSTANCE_PACKAGE_ENDPOINT_TYPE,
+ NPM_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
@@ -29,13 +30,12 @@ describe('NpmInstallation', () => {
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
const findEndPointTypeSector = () => wrapper.findComponent(GlFormRadioGroup);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent({ data = {} } = {}) {
wrapper = shallowMountExtended(NpmInstallation, {
provide: {
- npmHelpPath: 'npmHelpPath',
- npmPath: 'npmPath',
- npmProjectPath: 'npmProjectPath',
+ npmInstanceUrl: 'npmInstanceUrl',
},
propsData: {
packageEntity,
@@ -43,6 +43,7 @@ describe('NpmInstallation', () => {
data() {
return data;
},
+ stubs: { GlSprintf },
});
}
@@ -58,6 +59,13 @@ describe('NpmInstallation', () => {
expect(wrapper.element).toMatchSnapshot();
});
+ it('has a setup link', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: NPM_HELP_PATH,
+ target: '_blank',
+ });
+ });
+
describe('endpoint type selector', () => {
it('has the endpoint type selector', () => {
expect(findEndPointTypeSector().exists()).toBe(true);
@@ -109,7 +117,7 @@ describe('NpmInstallation', () => {
it('renders the correct setup command', () => {
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: 'echo @gitlab-org:registry=npmPath/ >> .npmrc',
+ instruction: 'echo @gitlab-org:registry=npmInstanceUrl/ >> .npmrc',
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
@@ -121,7 +129,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: `echo @gitlab-org:registry=npmProjectPath/ >> .npmrc`,
+ instruction: `echo @gitlab-org:registry=${packageEntity.npmUrl}/ >> .npmrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
@@ -131,7 +139,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: `echo @gitlab-org:registry=npmPath/ >> .npmrc`,
+ instruction: `echo @gitlab-org:registry=npmInstanceUrl/ >> .npmrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_NPM_SETUP_COMMAND,
});
@@ -153,7 +161,7 @@ describe('NpmInstallation', () => {
it('renders the correct registry command', () => {
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: 'echo \\"@gitlab-org:registry\\" \\"npmPath/\\" >> .yarnrc',
+ instruction: 'echo \\"@gitlab-org:registry\\" \\"npmInstanceUrl/\\" >> .yarnrc',
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
@@ -165,7 +173,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: `echo \\"@gitlab-org:registry\\" \\"npmProjectPath/\\" >> .yarnrc`,
+ instruction: `echo \\"@gitlab-org:registry\\" \\"${packageEntity.npmUrl}/\\" >> .yarnrc`,
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
@@ -175,7 +183,7 @@ describe('NpmInstallation', () => {
await nextTick();
expect(findCodeInstructions().at(1).props()).toMatchObject({
- instruction: 'echo \\"@gitlab-org:registry\\" \\"npmPath/\\" >> .yarnrc',
+ instruction: 'echo \\"@gitlab-org:registry\\" \\"npmInstanceUrl/\\" >> .yarnrc',
multiline: false,
trackingAction: TRACKING_ACTION_COPY_YARN_SETUP_COMMAND,
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js
index c48a3f07299..d324d43258c 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js
@@ -1,3 +1,4 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { packageData } from 'jest/packages_and_registries/package_registry/mock_data';
import InstallationTitle from '~/packages_and_registries/package_registry/components/details/installation_title.vue';
@@ -6,6 +7,7 @@ import {
TRACKING_ACTION_COPY_NUGET_INSTALL_COMMAND,
TRACKING_ACTION_COPY_NUGET_SETUP_COMMAND,
PACKAGE_TYPE_NUGET,
+ NUGET_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
@@ -15,21 +17,18 @@ describe('NugetInstallation', () => {
let wrapper;
const nugetInstallationCommandStr = 'nuget install @gitlab-org/package-15 -Source "GitLab"';
- const nugetSetupCommandStr =
- 'nuget source Add -Name "GitLab" -Source "nugetPath" -UserName <your_username> -Password <your_token>';
+ const nugetSetupCommandStr = `nuget source Add -Name "GitLab" -Source "${packageEntity.nugetUrl}" -UserName <your_username> -Password <your_token>`;
const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent() {
wrapper = shallowMountExtended(NugetInstallation, {
- provide: {
- nugetHelpPath: 'nugetHelpPath',
- nugetPath: 'nugetPath',
- },
propsData: {
packageEntity,
},
+ stubs: { GlSprintf },
});
}
@@ -71,5 +70,12 @@ describe('NugetInstallation', () => {
trackingAction: TRACKING_ACTION_COPY_NUGET_SETUP_COMMAND,
});
});
+
+ it('it has docs link', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: NUGET_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
index 042b2026199..f8a4ba8f3bc 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js
@@ -28,8 +28,8 @@ describe('Package Files', () => {
const createComponent = ({ packageFiles = [file], canDelete = true } = {}) => {
wrapper = mountExtended(PackageFiles, {
- provide: { canDelete },
propsData: {
+ canDelete,
packageFiles,
},
stubs: {
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js
index 410c1b65348..f2fef6436a6 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/pypi_installation_spec.js
@@ -1,3 +1,4 @@
+import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { packageData } from 'jest/packages_and_registries/package_registry/mock_data';
import InstallationTitle from '~/packages_and_registries/package_registry/components/details/installation_title.vue';
@@ -6,6 +7,7 @@ import {
PACKAGE_TYPE_PYPI,
TRACKING_ACTION_COPY_PIP_INSTALL_COMMAND,
TRACKING_ACTION_COPY_PYPI_SETUP_COMMAND,
+ PYPI_HELP_PATH,
} from '~/packages_and_registries/package_registry/constants';
const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_PYPI };
@@ -13,9 +15,9 @@ const packageEntity = { ...packageData(), packageType: PACKAGE_TYPE_PYPI };
describe('PypiInstallation', () => {
let wrapper;
- const pipCommandStr = 'pip install @gitlab-org/package-15 --extra-index-url pypiPath';
+ const pipCommandStr = `pip install @gitlab-org/package-15 --extra-index-url ${packageEntity.pypiUrl}`;
const pypiSetupStr = `[gitlab]
-repository = pypiSetupPath
+repository = ${packageEntity.pypiSetupUrl}
username = __token__
password = <your personal access token>`;
@@ -23,17 +25,16 @@ password = <your personal access token>`;
const setupInstruction = () => wrapper.findByTestId('pypi-setup-content');
const findInstallationTitle = () => wrapper.findComponent(InstallationTitle);
+ const findSetupDocsLink = () => wrapper.findComponent(GlLink);
function createComponent() {
wrapper = shallowMountExtended(PypiInstallation, {
- provide: {
- pypiHelpPath: 'pypiHelpPath',
- pypiPath: 'pypiPath',
- pypiSetupPath: 'pypiSetupPath',
- },
propsData: {
packageEntity,
},
+ stubs: {
+ GlSprintf,
+ },
});
}
@@ -76,5 +77,12 @@ password = <your personal access token>`;
trackingAction: TRACKING_ACTION_COPY_PYPI_SETUP_COMMAND,
});
});
+
+ it('has a link to the docs', () => {
+ expect(findSetupDocsLink().attributes()).toMatchObject({
+ href: PYPI_HELP_PATH,
+ target: '_blank',
+ });
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap
index 165ee962417..18a99f70756 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap
@@ -22,16 +22,20 @@ exports[`packages_list_row renders 1`] = `
<div
class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0"
>
- <gl-link-stub
+ <router-link-stub
+ ariacurrentvalue="page"
class="gl-text-body gl-min-w-0"
data-qa-selector="package_link"
- href="http://gdk.test:3000/gitlab-org/gitlab-test/-/packages/111"
+ data-testid="details-link"
+ event="click"
+ tag="a"
+ to="[object Object]"
>
<gl-truncate-stub
position="end"
text="@gitlab-org/package-15"
/>
- </gl-link-stub>
+ </router-link-stub>
<!---->
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
index 292667ec47c..9467a613b2a 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
@@ -1,7 +1,11 @@
-import { GlLink, GlSprintf } from '@gitlab/ui';
+import { GlSprintf } from '@gitlab/ui';
+import { createLocalVue } from '@vue/test-utils';
+import VueRouter from 'vue-router';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+
import PackagesListRow from '~/packages_and_registries/package_registry/components/list/package_list_row.vue';
import PackagePath from '~/packages_and_registries/shared/components/package_path.vue';
import PackageTags from '~/packages_and_registries/shared/components/package_tags.vue';
@@ -13,6 +17,9 @@ import { PACKAGE_ERROR_STATUS } from '~/packages_and_registries/package_registry
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import { packageData, packagePipelines, packageProject, packageTags } from '../../mock_data';
+const localVue = createLocalVue();
+localVue.use(VueRouter);
+
describe('packages_list_row', () => {
let wrapper;
@@ -28,7 +35,7 @@ describe('packages_list_row', () => {
const findDeleteButton = () => wrapper.findByTestId('action-delete');
const findPackageIconAndName = () => wrapper.find(PackageIconAndName);
const findListItem = () => wrapper.findComponent(ListItem);
- const findPackageLink = () => wrapper.findComponent(GlLink);
+ const findPackageLink = () => wrapper.findByTestId('details-link');
const findWarningIcon = () => wrapper.findByTestId('warning-icon');
const findLeftSecondaryInfos = () => wrapper.findByTestId('left-secondary-infos');
const findPublishMethod = () => wrapper.findComponent(PublishMethod);
@@ -40,6 +47,7 @@ describe('packages_list_row', () => {
provide = defaultProvide,
} = {}) => {
wrapper = shallowMountExtended(PackagesListRow, {
+ localVue,
provide,
stubs: {
ListItem,
@@ -63,6 +71,15 @@ describe('packages_list_row', () => {
expect(wrapper.element).toMatchSnapshot();
});
+ it('has a link to navigate to the details page', () => {
+ mountComponent();
+
+ expect(findPackageLink().props()).toMatchObject({
+ event: 'click',
+ to: { name: 'details', params: { id: getIdFromGraphQLId(packageWithoutTags.id) } },
+ });
+ });
+
describe('tags', () => {
it('renders package tags when a package has tags', () => {
mountComponent({ packageEntity: packageWithTags });
@@ -120,7 +137,7 @@ describe('packages_list_row', () => {
});
it('details link is disabled', () => {
- expect(findPackageLink().attributes('disabled')).toBe('true');
+ expect(findPackageLink().props('event')).toBe('');
});
it('has a warning icon', () => {
diff --git a/spec/frontend/packages_and_registries/package_registry/mock_data.js b/spec/frontend/packages_and_registries/package_registry/mock_data.js
index 4c23b52b8a2..c6a59f20998 100644
--- a/spec/frontend/packages_and_registries/package_registry/mock_data.js
+++ b/spec/frontend/packages_and_registries/package_registry/mock_data.js
@@ -120,12 +120,22 @@ export const packageVersions = () => [
export const packageData = (extend) => ({
id: 'gid://gitlab/Packages::Package/111',
+ canDestroy: true,
name: '@gitlab-org/package-15',
packageType: 'NPM',
version: '1.0.0',
createdAt: '2020-08-17T14:23:32Z',
updatedAt: '2020-08-17T14:23:32Z',
status: 'DEFAULT',
+ mavenUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/maven',
+ npmUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/npm',
+ nugetUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/nuget/index.json',
+ composerConfigRepositoryUrl: 'gdk.test/22',
+ composerUrl: 'http://gdk.test:3000/api/v4/group/22/-/packages/composer/packages.json',
+ conanUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/conan',
+ pypiUrl:
+ 'http://__token__:<your_personal_token>@gdk.test:3000/api/v4/projects/1/packages/pypi/simple',
+ pypiSetupUrl: 'http://gdk.test:3000/api/v4/projects/1/packages/pypi',
...extend,
});
@@ -185,6 +195,7 @@ export const packageDetailsQuery = (extendPackage) => ({
project: {
id: '1',
path: 'projectPath',
+ name: 'gitlab-test',
},
tags: {
nodes: packageTags(),
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap
index dbe3c70c3cb..ed96abe24b1 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/pages/__snapshots__/list_spec.js.snap
@@ -11,10 +11,10 @@ exports[`PackagesListApp renders 1`] = `
<div>
<section
- class="row empty-state text-center"
+ class="gl-display-flex empty-state gl-text-center gl-flex-direction-column"
>
<div
- class="col-12"
+ class="gl-max-w-full"
>
<div
class="svg-250 svg-content"
@@ -29,10 +29,10 @@ exports[`PackagesListApp renders 1`] = `
</div>
<div
- class="col-12"
+ class="gl-max-w-full gl-m-auto"
>
<div
- class="text-content gl-mx-auto gl-my-0 gl-p-5"
+ class="gl-mx-auto gl-my-0 gl-p-5"
>
<h1
class="gl-font-size-h-display gl-line-height-36 h4"
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
index 0bea84693f6..637e2edf3be 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
@@ -9,7 +9,7 @@ import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import AdditionalMetadata from '~/packages_and_registries/package_registry/components/details/additional_metadata.vue';
-import PackagesApp from '~/packages_and_registries/package_registry/components/details/app.vue';
+import PackagesApp from '~/packages_and_registries/package_registry/pages/details.vue';
import DependencyRow from '~/packages_and_registries/package_registry/components/details/dependency_row.vue';
import InstallationCommands from '~/packages_and_registries/package_registry/components/details/installation_commands.vue';
import PackageFiles from '~/packages_and_registries/package_registry/components/details/package_files.vue';
@@ -36,7 +36,7 @@ import {
packageFiles,
packageDestroyFileMutation,
packageDestroyFileMutationError,
-} from '../../mock_data';
+} from '../mock_data';
jest.mock('~/flash');
useMockLocationHelper();
@@ -47,21 +47,22 @@ describe('PackagesApp', () => {
let wrapper;
let apolloProvider;
+ const breadCrumbState = {
+ updateName: jest.fn(),
+ };
+
const provide = {
packageId: '111',
- titleComponent: 'PackageTitle',
- projectName: 'projectName',
- canDelete: 'canDelete',
- svgPath: 'svgPath',
- npmPath: 'npmPath',
- npmHelpPath: 'npmHelpPath',
+ emptyListIllustration: 'svgPath',
projectListUrl: 'projectListUrl',
groupListUrl: 'groupListUrl',
+ breadCrumbState,
};
function createComponent({
resolver = jest.fn().mockResolvedValue(packageDetailsQuery()),
fileDeleteMutationResolver = jest.fn().mockResolvedValue(packageDestroyFileMutation()),
+ routeId = '1',
} = {}) {
localVue.use(VueApollo);
@@ -87,6 +88,13 @@ describe('PackagesApp', () => {
GlTabs,
GlTab,
},
+ mocks: {
+ $route: {
+ params: {
+ id: routeId,
+ },
+ },
+ },
});
}
@@ -149,7 +157,7 @@ describe('PackagesApp', () => {
expect(findPackageHistory().exists()).toBe(true);
expect(findPackageHistory().props()).toMatchObject({
packageEntity: expect.objectContaining(packageData()),
- projectName: provide.projectName,
+ projectName: packageDetailsQuery().data.package.project.name,
});
});
@@ -175,9 +183,18 @@ describe('PackagesApp', () => {
});
});
+ it('calls the appropriate function to set the breadcrumbState', async () => {
+ const { name, version } = packageData();
+ createComponent();
+
+ await waitForPromises();
+
+ expect(breadCrumbState.updateName).toHaveBeenCalledWith(`${name} v ${version}`);
+ });
+
describe('delete package', () => {
const originalReferrer = document.referrer;
- const setReferrer = (value = provide.projectName) => {
+ const setReferrer = (value = packageDetailsQuery().data.package.project.name) => {
Object.defineProperty(document, 'referrer', {
value,
configurable: true,
@@ -244,6 +261,7 @@ describe('PackagesApp', () => {
expect(findPackageFiles().exists()).toBe(true);
expect(findPackageFiles().props('packageFiles')[0]).toMatchObject(expectedFile);
+ expect(findPackageFiles().props('canDelete')).toBe(packageData().canDestroy);
});
it('does not render the package files table when the package is composer', async () => {
diff --git a/spec/frontend/packages_and_registries/shared/__snapshots__/publish_method_spec.js.snap b/spec/frontend/packages_and_registries/shared/components/__snapshots__/publish_method_spec.js.snap
index 5f243799bae..5f243799bae 100644
--- a/spec/frontend/packages_and_registries/shared/__snapshots__/publish_method_spec.js.snap
+++ b/spec/frontend/packages_and_registries/shared/components/__snapshots__/publish_method_spec.js.snap
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/__snapshots__/registry_breadcrumb_spec.js.snap b/spec/frontend/packages_and_registries/shared/components/__snapshots__/registry_breadcrumb_spec.js.snap
index 7044c1285d8..ceae8eebaef 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/__snapshots__/registry_breadcrumb_spec.js.snap
+++ b/spec/frontend/packages_and_registries/shared/components/__snapshots__/registry_breadcrumb_spec.js.snap
@@ -1,7 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
-<div
+<nav
+ aria-label="Breadcrumb"
class="gl-breadcrumbs"
>
@@ -24,19 +25,25 @@ exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
class="gl-breadcrumb-separator"
data-testid="separator"
>
- <svg
- aria-hidden="true"
- class="gl-icon s8"
- data-testid="angle-right-icon"
- role="img"
+ <span
+ class="gl-mx-n5"
>
- <use
- href="#angle-right"
- />
- </svg>
+ <svg
+ aria-hidden="true"
+ class="gl-icon s8"
+ data-testid="angle-right-icon"
+ role="img"
+ >
+ <use
+ href="#angle-right"
+ />
+ </svg>
+ </span>
</span>
</a>
</li>
+
+ <!---->
<li
class="breadcrumb-item gl-breadcrumb-item"
>
@@ -52,12 +59,15 @@ exports[`Registry Breadcrumb when is not rootRoute renders 1`] = `
<!---->
</a>
</li>
+
+ <!---->
</ol>
-</div>
+</nav>
`;
exports[`Registry Breadcrumb when is rootRoute renders 1`] = `
-<div
+<nav
+ aria-label="Breadcrumb"
class="gl-breadcrumbs"
>
@@ -79,6 +89,8 @@ exports[`Registry Breadcrumb when is rootRoute renders 1`] = `
<!---->
</a>
</li>
+
+ <!---->
</ol>
-</div>
+</nav>
`;
diff --git a/spec/frontend/packages_and_registries/shared/package_icon_and_name_spec.js b/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js
index d6d1970cb12..d6d1970cb12 100644
--- a/spec/frontend/packages_and_registries/shared/package_icon_and_name_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/package_path_spec.js b/spec/frontend/packages_and_registries/shared/components/package_path_spec.js
index 93425d4f399..93425d4f399 100644
--- a/spec/frontend/packages_and_registries/shared/package_path_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/package_path_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/package_tags_spec.js b/spec/frontend/packages_and_registries/shared/components/package_tags_spec.js
index 33e96c0775e..33e96c0775e 100644
--- a/spec/frontend/packages_and_registries/shared/package_tags_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/package_tags_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/packages_list_loader_spec.js b/spec/frontend/packages_and_registries/shared/components/packages_list_loader_spec.js
index 0005162e0bb..0005162e0bb 100644
--- a/spec/frontend/packages_and_registries/shared/packages_list_loader_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/packages_list_loader_spec.js
diff --git a/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js b/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js
new file mode 100644
index 00000000000..bd492a5ae8f
--- /dev/null
+++ b/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js
@@ -0,0 +1,145 @@
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import component from '~/packages_and_registries/shared/components/persisted_search.vue';
+import UrlSync from '~/vue_shared/components/url_sync.vue';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
+import { getQueryParams, extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
+
+jest.mock('~/packages_and_registries/shared/utils');
+
+useMockLocationHelper();
+
+describe('Persisted Search', () => {
+ let wrapper;
+
+ const defaultQueryParamsMock = {
+ filters: ['foo'],
+ sorting: { sort: 'desc', orderBy: 'test' },
+ };
+
+ const defaultProps = {
+ sortableFields: [
+ { orderBy: 'test', label: 'test' },
+ { orderBy: 'foo', label: 'foo' },
+ ],
+ defaultOrder: 'test',
+ defaultSort: 'asc',
+ };
+
+ const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
+ const findUrlSync = () => wrapper.findComponent(UrlSync);
+
+ const mountComponent = (propsData = defaultProps) => {
+ wrapper = shallowMountExtended(component, {
+ propsData,
+ stubs: {
+ UrlSync,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ extractFilterAndSorting.mockReturnValue(defaultQueryParamsMock);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('has a registry search component', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ expect(findRegistrySearch().exists()).toBe(true);
+ });
+
+ it('registry search is mounted after mount', async () => {
+ mountComponent();
+
+ expect(findRegistrySearch().exists()).toBe(false);
+ });
+
+ it('has a UrlSync component', () => {
+ mountComponent();
+
+ expect(findUrlSync().exists()).toBe(true);
+ });
+
+ it('on sorting:changed emits update event and update internal sort', async () => {
+ const payload = { sort: 'desc', orderBy: 'test' };
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('sorting:changed', payload);
+
+ await nextTick();
+
+ expect(findRegistrySearch().props('sorting')).toMatchObject(payload);
+
+ // there is always a first call on mounted that emits up default values
+ expect(wrapper.emitted('update')[1]).toEqual([
+ {
+ filters: ['foo'],
+ sort: 'TEST_DESC',
+ },
+ ]);
+ });
+
+ it('on filter:changed updates the filters', async () => {
+ const payload = ['foo'];
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('filter:changed', payload);
+
+ await nextTick();
+
+ expect(findRegistrySearch().props('filter')).toEqual(['foo']);
+ });
+
+ it('on filter:submit emits update event', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('filter:submit');
+
+ expect(wrapper.emitted('update')[1]).toEqual([
+ {
+ filters: ['foo'],
+ sort: 'TEST_DESC',
+ },
+ ]);
+ });
+
+ it('on query:changed calls updateQuery from UrlSync', async () => {
+ jest.spyOn(UrlSync.methods, 'updateQuery').mockImplementation(() => {});
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('query:changed');
+
+ expect(UrlSync.methods.updateQuery).toHaveBeenCalled();
+ });
+
+ it('sets the component sorting and filtering based on the querystring', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ expect(getQueryParams).toHaveBeenCalled();
+
+ expect(findRegistrySearch().props()).toMatchObject({
+ filter: defaultQueryParamsMock.filters,
+ sorting: defaultQueryParamsMock.sorting,
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/shared/publish_method_spec.js b/spec/frontend/packages_and_registries/shared/components/publish_method_spec.js
index fa8f8f7641a..fa8f8f7641a 100644
--- a/spec/frontend/packages_and_registries/shared/publish_method_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/publish_method_spec.js
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/registry_breadcrumb_spec.js b/spec/frontend/packages_and_registries/shared/components/registry_breadcrumb_spec.js
index e5a8438f23f..6dfe116c285 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/registry_breadcrumb_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/registry_breadcrumb_spec.js
@@ -1,6 +1,6 @@
import { mount } from '@vue/test-utils';
-import component from '~/packages_and_registries/container_registry/explorer/components/registry_breadcrumb.vue';
+import component from '~/packages_and_registries/shared/components/registry_breadcrumb.vue';
describe('Registry Breadcrumb', () => {
let wrapper;