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/delete_button_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/status_alert_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cleanup_status_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js20
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/index_spec.js2
-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
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js8
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js10
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/shared/__snapshots__/package_list_row_spec.js.snap2
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/shared/infrastructure_icon_and_name_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/nuget_installation_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js6
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js8
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/details_spec.js14
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/__snapshots__/settings_titles_spec.js.snap18
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/duplicates_settings_spec.js143
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/exceptions_input_spec.js108
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/generic_settings_spec.js54
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/maven_settings_spec.js54
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js115
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/settings_titles_spec.js35
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/cleanup_image_tags_spec.js164
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_form_spec.js109
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_spec.js64
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/expiration_dropdown_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/expiration_input_spec.js6
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/expiration_run_text_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/expiration_toggle_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/packages_cleanup_policy_form_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js96
-rw-r--r--spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js (renamed from spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cli_commands_spec.js)6
-rw-r--r--spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js2
61 files changed, 1522 insertions, 753 deletions
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/delete_button_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/delete_button_spec.js
index ad67128502a..ff11c8843bb 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/delete_button_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/delete_button_spec.js
@@ -11,8 +11,8 @@ describe('delete_button', () => {
tooltipTitle: 'Bar tooltipTitle',
};
- const findButton = () => wrapper.find(GlButton);
- const findTooltip = () => wrapper.find(GlTooltip);
+ const findButton = () => wrapper.findComponent(GlButton);
+ const findTooltip = () => wrapper.findComponent(GlTooltip);
const mountComponent = (props) => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js
index 9680e273add..4a026f35822 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js
@@ -13,8 +13,8 @@ import {
describe('Delete alert', () => {
let wrapper;
- const findAlert = () => wrapper.find(GlAlert);
- const findLink = () => wrapper.find(GlLink);
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findLink = () => wrapper.findComponent(GlLink);
const mountComponent = (propsData) => {
wrapper = shallowMount(component, { stubs: { GlSprintf }, propsData });
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 9982286c625..b37edac83f7 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
@@ -120,7 +120,7 @@ describe('Details Header', () => {
return waitForPromises();
});
- it('shows image.name ', () => {
+ it('shows image.name', () => {
expect(findTitle().text()).toContain('foo');
});
@@ -289,7 +289,7 @@ describe('Details Header', () => {
);
});
- describe('visibility and updated at ', () => {
+ describe('visibility and updated at', () => {
it('has last updated text', async () => {
mountComponent();
await waitForMetadataItems();
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert_spec.js
index 1a27481a828..ce5ecfe4608 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert_spec.js
@@ -9,7 +9,7 @@ import {
describe('Partial Cleanup alert', () => {
let wrapper;
- const findAlert = () => wrapper.find(GlAlert);
+ const findAlert = () => wrapper.findComponent(GlAlert);
const findRunLink = () => wrapper.find('[data-testid="run-link"');
const findHelpLink = () => wrapper.find('[data-testid="help-link"');
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/status_alert_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/status_alert_spec.js
index a11b102d9a6..d83a5099bcd 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/status_alert_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/status_alert_spec.js
@@ -14,8 +14,8 @@ import {
describe('Status Alert', () => {
let wrapper;
- const findLink = () => wrapper.find(GlLink);
- const findAlert = () => wrapper.find(GlAlert);
+ const findLink = () => wrapper.findComponent(GlLink);
+ const findAlert = () => wrapper.findComponent(GlAlert);
const findMessage = () => wrapper.find('[data-testid="message"]');
const mountComponent = (propsData) => {
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 84f01f10f21..96c670eaad2 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
@@ -32,7 +32,7 @@ describe('tags list row', () => {
const findShortRevision = () => wrapper.find('[data-testid="digest"]');
const findClipboardButton = () => wrapper.findComponent(ClipboardButton);
const findTimeAgoTooltip = () => wrapper.findComponent(TimeAgoTooltip);
- const findDetailsRows = () => wrapper.findAll(DetailsRow);
+ const findDetailsRows = () => wrapper.findAllComponents(DetailsRow);
const findPublishedDateDetail = () => wrapper.find('[data-testid="published-date-detail"]');
const findManifestDetail = () => wrapper.find('[data-testid="manifest-detail"]');
const findConfigurationDetail = () => wrapper.find('[data-testid="configuration-detail"]');
@@ -359,7 +359,7 @@ describe('tags list row', () => {
mountComponent();
await nextTick();
- expect(finderFunction().find(ClipboardButton).exists()).toBe(clipboard);
+ expect(finderFunction().findComponent(ClipboardButton).exists()).toBe(clipboard);
});
it('is disabled when the component is disabled', async () => {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js
index e5df260a260..88e79c513bc 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_loader_spec.js
@@ -5,7 +5,7 @@ import { GlSkeletonLoader } from '../../stubs';
describe('TagsLoader component', () => {
let wrapper;
- const findGlSkeletonLoaders = () => wrapper.findAll(GlSkeletonLoader);
+ const findGlSkeletonLoaders = () => wrapper.findAllComponents(GlSkeletonLoader);
const mountComponent = () => {
wrapper = shallowMount(component, {
@@ -25,7 +25,7 @@ describe('TagsLoader component', () => {
wrapper = null;
});
- it('produces the correct amount of loaders ', () => {
+ it('produces the correct amount of loaders', () => {
mountComponent();
expect(findGlSkeletonLoaders().length).toBe(1);
});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cleanup_status_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cleanup_status_spec.js
index 61503d0f3bf..535faebdd4e 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cleanup_status_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cleanup_status_spec.js
@@ -16,7 +16,7 @@ describe('cleanup_status', () => {
let wrapper;
const findMainIcon = () => wrapper.findByTestId('main-icon');
- const findMainIconName = () => wrapper.findByTestId('main-icon').find(GlIcon);
+ const findMainIconName = () => wrapper.findByTestId('main-icon').findComponent(GlIcon);
const findExtraInfoIcon = () => wrapper.findByTestId('extra-info');
const findPopover = () => wrapper.findComponent(GlPopover);
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js
index d12933526bc..0b59fe2d8ce 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js
@@ -233,7 +233,7 @@ describe('Image List Row', () => {
it('contains a tag icon', () => {
mountComponent();
- const icon = findTagsCount().find(GlIcon);
+ const icon = findTagsCount().findComponent(GlIcon);
expect(icon.exists()).toBe(true);
expect(icon.props('name')).toBe('tag');
});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js
index e0119954ed4..042b8383571 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_spec.js
@@ -8,8 +8,8 @@ import { imagesListResponse, pageInfo as defaultPageInfo } from '../../mock_data
describe('Image List', () => {
let wrapper;
- const findRow = () => wrapper.findAll(ImageListRow);
- const findPagination = () => wrapper.find(GlKeysetPagination);
+ const findRow = () => wrapper.findAllComponents(ImageListRow);
+ const findPagination = () => wrapper.findComponent(GlKeysetPagination);
const mountComponent = (props) => {
wrapper = shallowMount(Component, {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
index a006de9f00c..e6d81d4a28f 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
@@ -17,7 +17,7 @@ jest.mock('~/lib/utils/datetime_utility', () => ({
describe('registry_header', () => {
let wrapper;
- const findTitleArea = () => wrapper.find(TitleArea);
+ const findTitleArea = () => wrapper.findComponent(TitleArea);
const findCommandsSlot = () => wrapper.find('[data-testid="commands-slot"]');
const findImagesCountSubHeader = () => wrapper.find('[data-testid="images-count"]');
const findExpirationPolicySubHeader = () => wrapper.find('[data-testid="expiration-policy"]');
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 1d161888a4d..ee6470a9df8 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
@@ -45,16 +45,16 @@ describe('Details Page', () => {
let wrapper;
let apolloProvider;
- const findDeleteModal = () => wrapper.find(DeleteModal);
- const findPagination = () => wrapper.find(GlKeysetPagination);
- const findTagsLoader = () => wrapper.find(TagsLoader);
- const findTagsList = () => wrapper.find(TagsList);
- const findDeleteAlert = () => wrapper.find(DeleteAlert);
- const findDetailsHeader = () => wrapper.find(DetailsHeader);
- const findEmptyState = () => wrapper.find(GlEmptyState);
- const findPartialCleanupAlert = () => wrapper.find(PartialCleanupAlert);
- const findStatusAlert = () => wrapper.find(StatusAlert);
- const findDeleteImage = () => wrapper.find(DeleteImage);
+ const findDeleteModal = () => wrapper.findComponent(DeleteModal);
+ const findPagination = () => wrapper.findComponent(GlKeysetPagination);
+ const findTagsLoader = () => wrapper.findComponent(TagsLoader);
+ const findTagsList = () => wrapper.findComponent(TagsList);
+ const findDeleteAlert = () => wrapper.findComponent(DeleteAlert);
+ const findDetailsHeader = () => wrapper.findComponent(DetailsHeader);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findPartialCleanupAlert = () => wrapper.findComponent(PartialCleanupAlert);
+ const findStatusAlert = () => wrapper.findComponent(StatusAlert);
+ const findDeleteImage = () => wrapper.findComponent(DeleteImage);
const routeId = 1;
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/index_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/index_spec.js
index 5f4cb8969bc..add772d27ef 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/index_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/index_spec.js
@@ -4,7 +4,7 @@ import component from '~/packages_and_registries/container_registry/explorer/pag
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/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,
+ },
+ });
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
index 69c78e64e22..e74375b7705 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
@@ -76,8 +76,8 @@ describe('PackagesApp', () => {
const packageTitle = () => wrapper.findComponent(TerraformTitle);
const emptyState = () => wrapper.findComponent(GlEmptyState);
const deleteButton = () => wrapper.find('.js-delete-button');
- const findDeleteModal = () => wrapper.find({ ref: 'deleteModal' });
- const findDeleteFileModal = () => wrapper.find({ ref: 'deleteFileModal' });
+ const findDeleteModal = () => wrapper.findComponent({ ref: 'deleteModal' });
+ const findDeleteFileModal = () => wrapper.findComponent({ ref: 'deleteFileModal' });
const versionsTab = () => wrapper.find('.js-versions-tab > a');
const packagesLoader = () => wrapper.findComponent(PackagesListLoader);
const packagesVersionRows = () => wrapper.findAllComponents(PackageListRow);
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js
index 95de2f0bb0b..b76d7c2b57b 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_files_spec.js
@@ -17,8 +17,8 @@ describe('Package Files', () => {
const findFirstRowDownloadLink = () => findFirstRow().find('[data-testid="download-link"]');
const findFirstRowCommitLink = () => findFirstRow().find('[data-testid="commit-link"]');
const findSecondRowCommitLink = () => findSecondRow().find('[data-testid="commit-link"]');
- const findFirstRowFileIcon = () => findFirstRow().find(FileIcon);
- const findFirstRowCreatedAt = () => findFirstRow().find(TimeAgoTooltip);
+ const findFirstRowFileIcon = () => findFirstRow().findComponent(FileIcon);
+ const findFirstRowCreatedAt = () => findFirstRow().findComponent(TimeAgoTooltip);
const findFirstActionMenu = () => findFirstRow().findComponent(GlDropdown);
const findActionMenuDelete = () => findFirstActionMenu().find('[data-testid="delete-file"]');
const findFirstToggleDetailsButton = () => findFirstRow().findComponent(GlButton);
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js
index f10f05f4a0d..c6b5138639e 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/package_history_spec.js
@@ -36,8 +36,8 @@ describe('Package History', () => {
});
const findHistoryElement = (testId) => wrapper.find(`[data-testid="${testId}"]`);
- const findElementLink = (container) => container.find(GlLink);
- const findElementTimeAgo = (container) => container.find(TimeAgoTooltip);
+ const findElementLink = (container) => container.findComponent(GlLink);
+ const findElementTimeAgo = (container) => container.findComponent(TimeAgoTooltip);
const findTitle = () => wrapper.find('[data-testid="title"]');
const findTimeline = () => wrapper.find('[data-testid="timeline"]');
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js
index 72d08d5683b..93d013bb458 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_title_spec.js
@@ -7,8 +7,8 @@ describe('Infrastructure Title', () => {
let wrapper;
let store;
- const findTitleArea = () => wrapper.find(TitleArea);
- const findMetadataItem = () => wrapper.find(MetadataItem);
+ const findTitleArea = () => wrapper.findComponent(TitleArea);
+ const findMetadataItem = () => wrapper.findComponent(MetadataItem);
const exampleProps = { helpUrl: 'http://example.gitlab.com/help' };
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js
index 31616e0b2f5..db1d3f3f633 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js
@@ -31,9 +31,9 @@ describe('packages_list_app', () => {
const GlLoadingIcon = { name: 'gl-loading-icon', template: '<div>loading</div>' };
const emptyListHelpUrl = 'helpUrl';
- const findEmptyState = () => wrapper.find(GlEmptyState);
- const findListComponent = () => wrapper.find(PackageList);
- const findInfrastructureSearch = () => wrapper.find(InfrastructureSearch);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findListComponent = () => wrapper.findComponent(PackageList);
+ const findInfrastructureSearch = () => wrapper.findComponent(InfrastructureSearch);
const createStore = ({ filter = [], packageCount = 0 } = {}) => {
store = new Vuex.Store({
@@ -151,7 +151,7 @@ describe('packages_list_app', () => {
describe('empty state', () => {
it('generate the correct empty list link', () => {
- const link = findListComponent().find(GlLink);
+ const link = findListComponent().findComponent(GlLink);
expect(link.attributes('href')).toBe(emptyListHelpUrl);
expect(link.text()).toBe('publish and share your packages');
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 fed82653016..fb5ee4e6884 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
@@ -20,11 +20,11 @@ describe('packages_list', () => {
const EmptySlotStub = { name: 'empty-slot-stub', template: '<div>bar</div>' };
- const findPackagesListLoader = () => wrapper.find(PackagesListLoader);
- const findPackageListPagination = () => wrapper.find(GlPagination);
- const findPackageListDeleteModal = () => wrapper.find(GlModal);
- const findEmptySlot = () => wrapper.find(EmptySlotStub);
- const findPackagesListRow = () => wrapper.find(PackagesListRow);
+ const findPackagesListLoader = () => wrapper.findComponent(PackagesListLoader);
+ const findPackageListPagination = () => wrapper.findComponent(GlPagination);
+ const findPackageListDeleteModal = () => wrapper.findComponent(GlModal);
+ const findEmptySlot = () => wrapper.findComponent(EmptySlotStub);
+ const findPackagesListRow = () => wrapper.findComponent(PackagesListRow);
const createStore = (isGroupPage, packages, isLoading) => {
const state = {
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/__snapshots__/package_list_row_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/__snapshots__/package_list_row_spec.js.snap
index 67c3b8b795a..91824dee5b0 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/__snapshots__/package_list_row_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/__snapshots__/package_list_row_spec.js.snap
@@ -3,7 +3,7 @@
exports[`packages_list_row renders 1`] = `
<div
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
- data-qa-selector="package_row"
+ data-testid="package-row"
>
<div
class="gl-display-flex gl-align-items-center gl-py-3"
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/infrastructure_icon_and_name_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/infrastructure_icon_and_name_spec.js
index abb0d23b6e4..db90bb4c25f 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/infrastructure_icon_and_name_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/shared/infrastructure_icon_and_name_spec.js
@@ -5,7 +5,7 @@ import InfrastructureIconAndName from '~/packages_and_registries/infrastructure_
describe('InfrastructureIconAndName', () => {
let wrapper;
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const mountComponent = () => {
wrapper = shallowMount(InfrastructureIconAndName, {});
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 d324d43258c..9449c40c7c6 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
@@ -71,7 +71,7 @@ describe('NugetInstallation', () => {
});
});
- it('it has docs link', () => {
+ 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/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 031afa62890..5be05ddf629 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
@@ -3,7 +3,7 @@
exports[`packages_list_row renders 1`] = `
<div
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
- data-qa-selector="package_row"
+ data-testid="package-row"
>
<div
class="gl-display-flex gl-align-items-center gl-py-3"
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 eb1e76377ff..b5a512b8806 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
@@ -30,10 +30,10 @@ describe('packages_list_row', () => {
const packageWithTags = { ...packageWithoutTags, tags: { nodes: packageTags() } };
const packageCannotDestroy = { ...packageData(), canDestroy: false };
- const findPackageTags = () => wrapper.find(PackageTags);
- const findPackagePath = () => wrapper.find(PackagePath);
+ const findPackageTags = () => wrapper.findComponent(PackageTags);
+ const findPackagePath = () => wrapper.findComponent(PackagePath);
const findDeleteDropdown = () => wrapper.findByTestId('action-delete');
- const findPackageIconAndName = () => wrapper.find(PackageIconAndName);
+ const findPackageIconAndName = () => wrapper.findComponent(PackageIconAndName);
const findPackageLink = () => wrapper.findByTestId('details-link');
const findWarningIcon = () => wrapper.findByTestId('warning-icon');
const findLeftSecondaryInfos = () => wrapper.findByTestId('left-secondary-infos');
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js
index 660f00a2b31..3e3607a361c 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js
@@ -190,7 +190,7 @@ describe('packages_list', () => {
});
});
- describe('pagination ', () => {
+ describe('pagination', () => {
beforeEach(() => {
mountComponent({ pageInfo: { hasPreviousPage: true } });
});
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js
index 23e5c7330d5..b47515e15c3 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js
@@ -7,8 +7,8 @@ describe('PackageTitle', () => {
let wrapper;
let store;
- const findTitleArea = () => wrapper.find(TitleArea);
- const findMetadataItem = () => wrapper.find(MetadataItem);
+ const findTitleArea = () => wrapper.findComponent(TitleArea);
+ const findMetadataItem = () => wrapper.findComponent(MetadataItem);
const mountComponent = (propsData = { helpUrl: 'foo' }) => {
wrapper = shallowMount(PackageTitle, {
diff --git a/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js b/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
index d0c111bae2d..8f3c8667c47 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js
@@ -6,8 +6,8 @@ import { PACKAGE_TYPES } from '~/packages_and_registries/package_registry/consta
describe('packages_filter', () => {
let wrapper;
- const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
- const findFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
+ const findFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
+ const findFilteredSearchSuggestions = () => wrapper.findAllComponents(GlFilteredSearchSuggestion);
const mountComponent = ({ attrs, listeners } = {}) => {
wrapper = shallowMount(component, {
@@ -24,13 +24,13 @@ describe('packages_filter', () => {
wrapper = null;
});
- it('it binds all of his attrs to filtered search token', () => {
+ it('binds all of his attrs to filtered search token', () => {
mountComponent({ attrs: { foo: 'bar' } });
expect(findFilteredSearchToken().attributes('foo')).toBe('bar');
});
- it('it binds all of his events to filtered search token', () => {
+ it('binds all of his events to filtered search token', () => {
const clickListener = jest.fn();
mountComponent({ listeners: { click: clickListener } });
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
index de78e6bb87b..83158d1cc5e 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
@@ -178,7 +178,7 @@ describe('PackagesApp', () => {
${PACKAGE_TYPE_PYPI} | ${true}
${PACKAGE_TYPE_NPM} | ${false}
`(
- `It is $visible that the component is visible when the package is $packageType`,
+ `is $visible that the component is visible when the package is $packageType`,
async ({ packageType, visible }) => {
createComponent({
resolver: jest.fn().mockResolvedValue(
@@ -328,8 +328,8 @@ describe('PackagesApp', () => {
findPackageFiles().vm.$emit('delete-files', [fileToDelete]);
- expect(showDeletePackageSpy).not.toBeCalled();
- expect(showDeleteFileSpy).toBeCalled();
+ expect(showDeletePackageSpy).not.toHaveBeenCalled();
+ expect(showDeleteFileSpy).toHaveBeenCalled();
});
it('when its the only file opens delete package confirmation modal', async () => {
@@ -357,8 +357,8 @@ describe('PackagesApp', () => {
findPackageFiles().vm.$emit('delete-files', [fileToDelete]);
- expect(showDeletePackageSpy).toBeCalled();
- expect(showDeleteFileSpy).not.toBeCalled();
+ expect(showDeletePackageSpy).toHaveBeenCalled();
+ expect(showDeleteFileSpy).not.toHaveBeenCalled();
});
it('confirming on the modal sets the loading state', async () => {
@@ -443,7 +443,7 @@ describe('PackagesApp', () => {
findPackageFiles().vm.$emit('delete-files', packageFiles());
- expect(showDeleteFilesSpy).toBeCalled();
+ expect(showDeleteFilesSpy).toHaveBeenCalled();
});
it('confirming on the modal sets the loading state', async () => {
@@ -532,7 +532,7 @@ describe('PackagesApp', () => {
findPackageFiles().vm.$emit('delete-files', packageFiles());
- expect(showDeletePackageSpy).toBeCalled();
+ expect(showDeletePackageSpy).toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/packages_and_registries/settings/group/components/__snapshots__/settings_titles_spec.js.snap b/spec/frontend/packages_and_registries/settings/group/components/__snapshots__/settings_titles_spec.js.snap
deleted file mode 100644
index 5b56cb7f74e..00000000000
--- a/spec/frontend/packages_and_registries/settings/group/components/__snapshots__/settings_titles_spec.js.snap
+++ /dev/null
@@ -1,18 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`settings_titles renders properly 1`] = `
-<div>
- <h5
- class="gl-border-b-solid gl-border-b-1 gl-border-gray-200 gl-pb-3"
- >
-
- foo
-
- </h5>
-
- <p>
- bar
- </p>
-
-</div>
-`;
diff --git a/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js
index 9d4c7f4737b..796d89231f4 100644
--- a/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js
+++ b/spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js
@@ -169,7 +169,7 @@ describe('DependencyProxySettings', () => {
toggleName | toggleFinder | localErrorMock | optimisticResponse
${'enable proxy'} | ${findEnableProxyToggle} | ${dependencyProxySettingMutationMock} | ${updateGroupDependencyProxySettingsOptimisticResponse}
${'enable ttl policies'} | ${findEnableTtlPoliciesToggle} | ${dependencyProxyUpdateTllPolicyMutationMock} | ${updateDependencyProxyImageTtlGroupPolicyOptimisticResponse}
- `('$toggleName settings update ', ({ optimisticResponse, toggleFinder, localErrorMock }) => {
+ `('$toggleName settings update', ({ optimisticResponse, toggleFinder, localErrorMock }) => {
describe('success state', () => {
it('emits a success event', async () => {
mountComponent();
diff --git a/spec/frontend/packages_and_registries/settings/group/components/duplicates_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/duplicates_settings_spec.js
deleted file mode 100644
index 3eecdeb5b1f..00000000000
--- a/spec/frontend/packages_and_registries/settings/group/components/duplicates_settings_spec.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import { GlSprintf, GlToggle, GlFormGroup, GlFormInput } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import component from '~/packages_and_registries/settings/group/components/duplicates_settings.vue';
-
-import {
- DUPLICATES_TOGGLE_LABEL,
- DUPLICATES_SETTING_EXCEPTION_TITLE,
- DUPLICATES_SETTINGS_EXCEPTION_LEGEND,
-} from '~/packages_and_registries/settings/group/constants';
-
-describe('Duplicates Settings', () => {
- let wrapper;
-
- const defaultProps = {
- duplicatesAllowed: false,
- duplicateExceptionRegex: 'foo',
- modelNames: {
- allowed: 'allowedModel',
- exception: 'exceptionModel',
- },
- };
-
- const mountComponent = (propsData = defaultProps) => {
- wrapper = shallowMount(component, {
- propsData,
- stubs: {
- GlSprintf,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- const findToggle = () => wrapper.findComponent(GlToggle);
-
- const findInputGroup = () => wrapper.findComponent(GlFormGroup);
- const findInput = () => wrapper.findComponent(GlFormInput);
-
- it('has a toggle', () => {
- mountComponent();
-
- expect(findToggle().exists()).toBe(true);
- expect(findToggle().props()).toMatchObject({
- label: DUPLICATES_TOGGLE_LABEL,
- value: !defaultProps.duplicatesAllowed,
- });
- });
-
- it('toggle emits an update event', () => {
- mountComponent();
-
- findToggle().vm.$emit('change', false);
-
- expect(wrapper.emitted('update')).toStrictEqual([
- [{ [defaultProps.modelNames.allowed]: true }],
- ]);
- });
-
- describe('when the duplicates are disabled', () => {
- it('shows a form group with an input field', () => {
- mountComponent();
-
- expect(findInputGroup().exists()).toBe(true);
-
- expect(findInputGroup().attributes()).toMatchObject({
- 'label-for': 'maven-duplicated-settings-regex-input',
- label: DUPLICATES_SETTING_EXCEPTION_TITLE,
- description: DUPLICATES_SETTINGS_EXCEPTION_LEGEND,
- });
- });
-
- it('shows an input field', () => {
- mountComponent();
-
- expect(findInput().exists()).toBe(true);
-
- expect(findInput().attributes()).toMatchObject({
- id: 'maven-duplicated-settings-regex-input',
- value: defaultProps.duplicateExceptionRegex,
- });
- });
-
- it('input change event emits an update event', () => {
- mountComponent();
-
- findInput().vm.$emit('change', 'bar');
-
- expect(wrapper.emitted('update')).toStrictEqual([
- [{ [defaultProps.modelNames.exception]: 'bar' }],
- ]);
- });
-
- describe('valid state', () => {
- it('form group has correct props', () => {
- mountComponent();
-
- expect(findInputGroup().attributes()).toMatchObject({
- state: 'true',
- 'invalid-feedback': '',
- });
- });
- });
-
- describe('invalid state', () => {
- it('form group has correct props', () => {
- const propsWithError = {
- ...defaultProps,
- duplicateExceptionRegexError: 'some error string',
- };
-
- mountComponent(propsWithError);
-
- expect(findInputGroup().attributes()).toMatchObject({
- 'invalid-feedback': propsWithError.duplicateExceptionRegexError,
- });
- });
- });
- });
-
- describe('when the duplicates are enabled', () => {
- it('hides the form input group', () => {
- mountComponent({ ...defaultProps, duplicatesAllowed: true });
-
- expect(findInputGroup().exists()).toBe(false);
- });
- });
-
- describe('loading', () => {
- beforeEach(() => {
- mountComponent({ ...defaultProps, loading: true });
- });
-
- it('disables the enable toggle', () => {
- expect(findToggle().props('disabled')).toBe(true);
- });
-
- it('disables the form input', () => {
- expect(findInput().attributes('disabled')).toBe('true');
- });
- });
-});
diff --git a/spec/frontend/packages_and_registries/settings/group/components/exceptions_input_spec.js b/spec/frontend/packages_and_registries/settings/group/components/exceptions_input_spec.js
new file mode 100644
index 00000000000..86f14961690
--- /dev/null
+++ b/spec/frontend/packages_and_registries/settings/group/components/exceptions_input_spec.js
@@ -0,0 +1,108 @@
+import { GlSprintf, GlFormGroup, GlFormInput } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import component from '~/packages_and_registries/settings/group/components/exceptions_input.vue';
+
+import { DUPLICATES_SETTING_EXCEPTION_TITLE } from '~/packages_and_registries/settings/group/constants';
+
+describe('Exceptions Input', () => {
+ let wrapper;
+
+ const defaultProps = {
+ duplicatesAllowed: false,
+ duplicateExceptionRegex: 'foo',
+ id: 'maven-duplicated-settings-regex-input',
+ name: 'exceptionModel',
+ };
+
+ const mountComponent = (propsData = defaultProps) => {
+ wrapper = shallowMount(component, {
+ propsData,
+ stubs: {
+ GlSprintf,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findInputGroup = () => wrapper.findComponent(GlFormGroup);
+ const findInput = () => wrapper.findComponent(GlFormInput);
+
+ it('shows a form group with an input field', () => {
+ mountComponent();
+
+ expect(findInputGroup().exists()).toBe(true);
+
+ expect(findInputGroup().attributes()).toMatchObject({
+ 'label-for': defaultProps.id,
+ label: DUPLICATES_SETTING_EXCEPTION_TITLE,
+ 'label-sr-only': '',
+ });
+ });
+
+ it('shows an input field', () => {
+ mountComponent();
+
+ expect(findInput().exists()).toBe(true);
+
+ expect(findInput().attributes()).toMatchObject({
+ id: 'maven-duplicated-settings-regex-input',
+ value: defaultProps.duplicateExceptionRegex,
+ });
+ });
+
+ it('input change event emits an update event', () => {
+ mountComponent();
+
+ findInput().vm.$emit('change', 'bar');
+
+ expect(wrapper.emitted('update')).toStrictEqual([[{ [defaultProps.name]: 'bar' }]]);
+ });
+
+ describe('valid state', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('form group has correct props', () => {
+ expect(findInputGroup().attributes('input-feedback')).toBeUndefined();
+ });
+
+ it('form input has correct props', () => {
+ expect(findInput().attributes('state')).toBe('true');
+ });
+ });
+
+ describe('invalid state', () => {
+ const propsWithError = {
+ ...defaultProps,
+ duplicateExceptionRegexError: 'some error string',
+ };
+
+ beforeEach(() => {
+ mountComponent(propsWithError);
+ });
+
+ it('form group has correct props', () => {
+ expect(findInputGroup().attributes('invalid-feedback')).toBe(
+ propsWithError.duplicateExceptionRegexError,
+ );
+ });
+
+ it('form input has correct props', () => {
+ expect(findInput().attributes('state')).toBeUndefined();
+ });
+ });
+
+ describe('loading', () => {
+ beforeEach(() => {
+ mountComponent({ ...defaultProps, loading: true });
+ });
+
+ it('disables the form input', () => {
+ expect(findInput().attributes('disabled')).toBe('true');
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/settings/group/components/generic_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/generic_settings_spec.js
deleted file mode 100644
index 4eafeedd55e..00000000000
--- a/spec/frontend/packages_and_registries/settings/group/components/generic_settings_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import GenericSettings from '~/packages_and_registries/settings/group/components/generic_settings.vue';
-import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
-
-describe('generic_settings', () => {
- let wrapper;
-
- const mountComponent = () => {
- wrapper = shallowMount(GenericSettings, {
- scopedSlots: {
- default: '<div data-testid="default-slot">{{props.modelNames}}</div>',
- },
- });
- };
-
- const findSettingsTitle = () => wrapper.findComponent(SettingsTitles);
- const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('title component', () => {
- it('has a title component', () => {
- mountComponent();
-
- expect(findSettingsTitle().exists()).toBe(true);
- });
-
- it('passes the correct props', () => {
- mountComponent();
-
- expect(findSettingsTitle().props()).toMatchObject({
- title: 'Generic',
- subTitle: 'Settings for Generic packages',
- });
- });
- });
-
- describe('default slot', () => {
- it('accept a default slots', () => {
- mountComponent();
-
- expect(findDefaultSlot().exists()).toBe(true);
- });
-
- it('binds model names', () => {
- mountComponent();
-
- expect(findDefaultSlot().text()).toContain('genericDuplicatesAllowed');
- expect(findDefaultSlot().text()).toContain('genericDuplicateExceptionRegex');
- });
- });
-});
diff --git a/spec/frontend/packages_and_registries/settings/group/components/maven_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/maven_settings_spec.js
deleted file mode 100644
index 22644b97b43..00000000000
--- a/spec/frontend/packages_and_registries/settings/group/components/maven_settings_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import MavenSettings from '~/packages_and_registries/settings/group/components/maven_settings.vue';
-import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
-
-describe('maven_settings', () => {
- let wrapper;
-
- const mountComponent = () => {
- wrapper = shallowMount(MavenSettings, {
- scopedSlots: {
- default: '<div data-testid="default-slot">{{props.modelNames}}</div>',
- },
- });
- };
-
- const findSettingsTitle = () => wrapper.findComponent(SettingsTitles);
- const findDefaultSlot = () => wrapper.find('[data-testid="default-slot"]');
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('title component', () => {
- it('has a title component', () => {
- mountComponent();
-
- expect(findSettingsTitle().exists()).toBe(true);
- });
-
- it('passes the correct props', () => {
- mountComponent();
-
- expect(findSettingsTitle().props()).toMatchObject({
- title: 'Maven',
- subTitle: 'Settings for Maven packages',
- });
- });
- });
-
- describe('default slot', () => {
- it('accept a default slots', () => {
- mountComponent();
-
- expect(findDefaultSlot().exists()).toBe(true);
- });
-
- it('binds model names', () => {
- mountComponent();
-
- expect(findDefaultSlot().text()).toContain('mavenDuplicatesAllowed');
- expect(findDefaultSlot().text()).toContain('mavenDuplicateExceptionRegex');
- });
- });
-});
diff --git a/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js b/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
index 274930ce668..13eba39ec8c 100644
--- a/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
+++ b/spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
@@ -1,13 +1,13 @@
import Vue, { nextTick } from 'vue';
+import { GlToggle } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import DuplicatesSettings from '~/packages_and_registries/settings/group/components/duplicates_settings.vue';
-import GenericSettings from '~/packages_and_registries/settings/group/components/generic_settings.vue';
+import ExceptionsInput from '~/packages_and_registries/settings/group/components/exceptions_input.vue';
import component from '~/packages_and_registries/settings/group/components/packages_settings.vue';
-import MavenSettings from '~/packages_and_registries/settings/group/components/maven_settings.vue';
import {
+ DUPLICATES_TOGGLE_LABEL,
PACKAGE_SETTINGS_HEADER,
PACKAGE_SETTINGS_DESCRIPTION,
} from '~/packages_and_registries/settings/group/constants';
@@ -35,6 +35,7 @@ describe('Packages Settings', () => {
};
const mountComponent = ({
+ mountFn = shallowMountExtended,
mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock()),
} = {}) => {
Vue.use(VueApollo);
@@ -43,7 +44,7 @@ describe('Packages Settings', () => {
apolloProvider = createMockApollo(requestHandlers);
- wrapper = shallowMountExtended(component, {
+ wrapper = mountFn(component, {
apolloProvider,
provide: defaultProvide,
propsData: {
@@ -51,8 +52,6 @@ describe('Packages Settings', () => {
},
stubs: {
SettingsBlock,
- MavenSettings,
- GenericSettings,
},
});
};
@@ -63,11 +62,15 @@ describe('Packages Settings', () => {
const findSettingsBlock = () => wrapper.findComponent(SettingsBlock);
const findDescription = () => wrapper.findByTestId('description');
- const findMavenSettings = () => wrapper.findComponent(MavenSettings);
- const findMavenDuplicatedSettings = () => findMavenSettings().findComponent(DuplicatesSettings);
- const findGenericSettings = () => wrapper.findComponent(GenericSettings);
- const findGenericDuplicatedSettings = () =>
- findGenericSettings().findComponent(DuplicatesSettings);
+ const findMavenSettings = () => wrapper.findByTestId('maven-settings');
+ const findGenericSettings = () => wrapper.findByTestId('generic-settings');
+
+ const findMavenDuplicatedSettingsToggle = () => findMavenSettings().findComponent(GlToggle);
+ const findGenericDuplicatedSettingsToggle = () => findGenericSettings().findComponent(GlToggle);
+ const findMavenDuplicatedSettingsExceptionsInput = () =>
+ findMavenSettings().findComponent(ExceptionsInput);
+ const findGenericDuplicatedSettingsExceptionsInput = () =>
+ findGenericSettings().findComponent(ExceptionsInput);
const fillApolloCache = () => {
apolloProvider.defaultClient.cache.writeQuery({
@@ -80,7 +83,7 @@ describe('Packages Settings', () => {
};
const emitMavenSettingsUpdate = (override) => {
- findMavenDuplicatedSettings().vm.$emit('update', {
+ findGenericDuplicatedSettingsExceptionsInput().vm.$emit('update', {
mavenDuplicateExceptionRegex: ')',
...override,
});
@@ -106,27 +109,46 @@ describe('Packages Settings', () => {
describe('maven settings', () => {
it('exists', () => {
- mountComponent();
+ mountComponent({ mountFn: mountExtended });
+
+ expect(findMavenSettings().find('td').text()).toBe('Maven');
+ });
+
+ it('renders toggle', () => {
+ mountComponent({ mountFn: mountExtended });
- expect(findMavenSettings().exists()).toBe(true);
+ const { mavenDuplicatesAllowed } = packageSettings();
+
+ expect(findMavenDuplicatedSettingsToggle().exists()).toBe(true);
+
+ expect(findMavenDuplicatedSettingsToggle().props()).toMatchObject({
+ label: DUPLICATES_TOGGLE_LABEL,
+ value: mavenDuplicatesAllowed,
+ disabled: false,
+ labelPosition: 'hidden',
+ });
});
- it('assigns duplication allowness and exception props', async () => {
- mountComponent();
+ it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
+ mountComponent({ mountFn: mountExtended });
const { mavenDuplicatesAllowed, mavenDuplicateExceptionRegex } = packageSettings();
- expect(findMavenDuplicatedSettings().props()).toMatchObject({
+ expect(findMavenDuplicatedSettingsExceptionsInput().exists()).toBe(true);
+
+ expect(findMavenDuplicatedSettingsExceptionsInput().props()).toMatchObject({
duplicatesAllowed: mavenDuplicatesAllowed,
duplicateExceptionRegex: mavenDuplicateExceptionRegex,
duplicateExceptionRegexError: '',
loading: false,
+ name: 'mavenDuplicateExceptionRegex',
+ id: 'maven-duplicated-settings-regex-input',
});
});
it('on update event calls the mutation', () => {
const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock());
- mountComponent({ mutationResolver });
+ mountComponent({ mountFn: mountExtended, mutationResolver });
fillApolloCache();
@@ -140,31 +162,47 @@ describe('Packages Settings', () => {
describe('generic settings', () => {
it('exists', () => {
- mountComponent();
+ mountComponent({ mountFn: mountExtended });
- expect(findGenericSettings().exists()).toBe(true);
+ expect(findGenericSettings().find('td').text()).toBe('Generic');
});
- it('assigns duplication allowness and exception props', async () => {
- mountComponent();
+ it('renders toggle', () => {
+ mountComponent({ mountFn: mountExtended });
+
+ const { genericDuplicatesAllowed } = packageSettings();
+
+ expect(findGenericDuplicatedSettingsToggle().exists()).toBe(true);
+ expect(findGenericDuplicatedSettingsToggle().props()).toMatchObject({
+ label: DUPLICATES_TOGGLE_LABEL,
+ value: genericDuplicatesAllowed,
+ disabled: false,
+ labelPosition: 'hidden',
+ });
+ });
+
+ it('renders ExceptionsInput and assigns duplication allowness and exception props', async () => {
+ mountComponent({ mountFn: mountExtended });
const { genericDuplicatesAllowed, genericDuplicateExceptionRegex } = packageSettings();
- expect(findGenericDuplicatedSettings().props()).toMatchObject({
+ expect(findGenericDuplicatedSettingsExceptionsInput().props()).toMatchObject({
duplicatesAllowed: genericDuplicatesAllowed,
duplicateExceptionRegex: genericDuplicateExceptionRegex,
duplicateExceptionRegexError: '',
loading: false,
+ name: 'genericDuplicateExceptionRegex',
+ id: 'generic-duplicated-settings-regex-input',
});
});
it('on update event calls the mutation', async () => {
const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock());
- mountComponent({ mutationResolver });
+ mountComponent({ mountFn: mountExtended, mutationResolver });
fillApolloCache();
- findMavenDuplicatedSettings().vm.$emit('update', {
+ findGenericDuplicatedSettingsExceptionsInput().vm.$emit('update', {
genericDuplicateExceptionRegex: ')',
});
@@ -176,9 +214,11 @@ describe('Packages Settings', () => {
describe('settings update', () => {
describe('success state', () => {
- it('emits a success event', async () => {
- mountComponent();
+ beforeEach(() => {
+ mountComponent({ mountFn: mountExtended });
+ });
+ it('emits a success event', async () => {
fillApolloCache();
emitMavenSettingsUpdate();
@@ -189,11 +229,12 @@ describe('Packages Settings', () => {
it('has an optimistic response', () => {
const mavenDuplicateExceptionRegex = 'latest[main]something';
- mountComponent();
fillApolloCache();
- expect(findMavenDuplicatedSettings().props('duplicateExceptionRegex')).toBe('');
+ expect(
+ findGenericDuplicatedSettingsExceptionsInput().props('duplicateExceptionRegex'),
+ ).toBe('');
emitMavenSettingsUpdate({ mavenDuplicateExceptionRegex });
@@ -209,7 +250,7 @@ describe('Packages Settings', () => {
// note this is a complex test that covers all the path around errors that are shown in the form
// it's one single it case, due to the expensive preparation and execution
const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationErrorMock);
- mountComponent({ mutationResolver });
+ mountComponent({ mountFn: mountExtended, mutationResolver });
fillApolloCache();
@@ -218,9 +259,9 @@ describe('Packages Settings', () => {
await waitForPromises();
// errors are bound to the component
- expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe(
- groupPackageSettingsMutationErrorMock.errors[0].extensions.problems[0].message,
- );
+ expect(
+ findMavenDuplicatedSettingsExceptionsInput().props('duplicateExceptionRegexError'),
+ ).toBe(groupPackageSettingsMutationErrorMock.errors[0].extensions.problems[0].message);
// general error message is shown
@@ -231,7 +272,9 @@ describe('Packages Settings', () => {
await nextTick();
// errors are reset on mutation call
- expect(findMavenDuplicatedSettings().props('duplicateExceptionRegexError')).toBe('');
+ expect(
+ findMavenDuplicatedSettingsExceptionsInput().props('duplicateExceptionRegexError'),
+ ).toBe('');
});
it.each`
@@ -239,7 +282,7 @@ describe('Packages Settings', () => {
${'local'} | ${jest.fn().mockResolvedValue(groupPackageSettingsMutationMock({ errors: ['foo'] }))}
${'network'} | ${jest.fn().mockRejectedValue()}
`('mutation payload with $type error', async ({ mutationResolver }) => {
- mountComponent({ mutationResolver });
+ mountComponent({ mountFn: mountExtended, mutationResolver });
fillApolloCache();
emitMavenSettingsUpdate();
diff --git a/spec/frontend/packages_and_registries/settings/group/components/settings_titles_spec.js b/spec/frontend/packages_and_registries/settings/group/components/settings_titles_spec.js
deleted file mode 100644
index fcfad4b42b8..00000000000
--- a/spec/frontend/packages_and_registries/settings/group/components/settings_titles_spec.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import SettingsTitles from '~/packages_and_registries/settings/group/components/settings_titles.vue';
-
-describe('settings_titles', () => {
- let wrapper;
-
- const defaultProps = {
- title: 'foo',
- subTitle: 'bar',
- };
-
- const mountComponent = (propsData = defaultProps) => {
- wrapper = shallowMount(SettingsTitles, {
- propsData,
- });
- };
-
- const findSubTitle = () => wrapper.find('p');
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('renders properly', () => {
- mountComponent();
-
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('does not render the subtitle paragraph when no subtitle is passed', () => {
- mountComponent({ title: defaultProps.title });
-
- expect(findSubTitle().exists()).toBe(false);
- });
-});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/cleanup_image_tags_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/cleanup_image_tags_spec.js
new file mode 100644
index 00000000000..8b60f31512b
--- /dev/null
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/cleanup_image_tags_spec.js
@@ -0,0 +1,164 @@
+import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import component from '~/packages_and_registries/settings/project/components/cleanup_image_tags.vue';
+import ContainerExpirationPolicyForm from '~/packages_and_registries/settings/project/components/container_expiration_policy_form.vue';
+import {
+ CONTAINER_CLEANUP_POLICY_TITLE,
+ CONTAINER_CLEANUP_POLICY_DESCRIPTION,
+ FETCH_SETTINGS_ERROR_MESSAGE,
+ UNAVAILABLE_FEATURE_INTRO_TEXT,
+ UNAVAILABLE_USER_FEATURE_TEXT,
+} from '~/packages_and_registries/settings/project/constants';
+import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql';
+
+import {
+ expirationPolicyPayload,
+ emptyExpirationPolicyPayload,
+ containerExpirationPolicyData,
+} from '../mock_data';
+
+describe('Cleanup image tags project settings', () => {
+ let wrapper;
+ let fakeApollo;
+
+ const defaultProvidedValues = {
+ projectPath: 'path',
+ isAdmin: false,
+ adminSettingsPath: 'settingsPath',
+ enableHistoricEntries: false,
+ helpPagePath: 'helpPagePath',
+ showCleanupPolicyLink: false,
+ };
+
+ const findFormComponent = () => wrapper.findComponent(ContainerExpirationPolicyForm);
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findTitle = () => wrapper.findByTestId('title');
+ const findDescription = () => wrapper.findByTestId('description');
+
+ const mountComponent = (provide = defaultProvidedValues, config) => {
+ wrapper = shallowMountExtended(component, {
+ stubs: {
+ GlSprintf,
+ },
+ provide,
+ ...config,
+ });
+ };
+
+ const mountComponentWithApollo = ({ provide = defaultProvidedValues, resolver } = {}) => {
+ Vue.use(VueApollo);
+
+ const requestHandlers = [[expirationPolicyQuery, resolver]];
+
+ fakeApollo = createMockApollo(requestHandlers);
+ mountComponent(provide, {
+ apolloProvider: fakeApollo,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('isEdited status', () => {
+ it.each`
+ description | apiResponse | workingCopy | result
+ ${'empty response and no changes from user'} | ${emptyExpirationPolicyPayload()} | ${{}} | ${false}
+ ${'empty response and changes from user'} | ${emptyExpirationPolicyPayload()} | ${{ enabled: true }} | ${true}
+ ${'response and no changes'} | ${expirationPolicyPayload()} | ${containerExpirationPolicyData()} | ${false}
+ ${'response and changes'} | ${expirationPolicyPayload()} | ${{ ...containerExpirationPolicyData(), nameRegex: '12345' }} | ${true}
+ ${'response and empty'} | ${expirationPolicyPayload()} | ${{}} | ${true}
+ `('$description', async ({ apiResponse, workingCopy, result }) => {
+ mountComponentWithApollo({
+ provide: { ...defaultProvidedValues, enableHistoricEntries: true },
+ resolver: jest.fn().mockResolvedValue(apiResponse),
+ });
+ await waitForPromises();
+
+ findFormComponent().vm.$emit('input', workingCopy);
+
+ await waitForPromises();
+
+ expect(findFormComponent().props('isEdited')).toBe(result);
+ });
+ });
+
+ it('renders the setting form', async () => {
+ mountComponentWithApollo({
+ resolver: jest.fn().mockResolvedValue(expirationPolicyPayload()),
+ });
+ await waitForPromises();
+
+ expect(findFormComponent().exists()).toBe(true);
+ expect(findTitle().text()).toMatchInterpolatedText(CONTAINER_CLEANUP_POLICY_TITLE);
+ expect(findDescription().text()).toMatchInterpolatedText(CONTAINER_CLEANUP_POLICY_DESCRIPTION);
+ });
+
+ describe('the form is disabled', () => {
+ it('hides the form', () => {
+ mountComponent();
+
+ expect(findFormComponent().exists()).toBe(false);
+ });
+
+ it('shows an alert', () => {
+ mountComponent();
+
+ const text = findAlert().text();
+ expect(text).toContain(UNAVAILABLE_FEATURE_INTRO_TEXT);
+ expect(text).toContain(UNAVAILABLE_USER_FEATURE_TEXT);
+ });
+
+ describe('an admin is visiting the page', () => {
+ it('shows the admin part of the alert message', () => {
+ mountComponent({ ...defaultProvidedValues, isAdmin: true });
+
+ const sprintf = findAlert().findComponent(GlSprintf);
+ expect(sprintf.text()).toBe('administration settings');
+ expect(sprintf.findComponent(GlLink).attributes('href')).toBe(
+ defaultProvidedValues.adminSettingsPath,
+ );
+ });
+ });
+ });
+
+ describe('fetchSettingsError', () => {
+ beforeEach(async () => {
+ mountComponentWithApollo({
+ resolver: jest.fn().mockRejectedValue(new Error('GraphQL error')),
+ });
+ await waitForPromises();
+ });
+
+ it('hides the form', () => {
+ expect(findFormComponent().exists()).toBe(false);
+ });
+
+ it('shows an alert', () => {
+ expect(findAlert().html()).toContain(FETCH_SETTINGS_ERROR_MESSAGE);
+ });
+ });
+
+ describe('empty API response', () => {
+ it.each`
+ enableHistoricEntries | isShown
+ ${true} | ${true}
+ ${false} | ${false}
+ `('is $isShown that the form is shown', async ({ enableHistoricEntries, isShown }) => {
+ mountComponentWithApollo({
+ provide: {
+ ...defaultProvidedValues,
+ enableHistoricEntries,
+ },
+ resolver: jest.fn().mockResolvedValue(emptyExpirationPolicyPayload()),
+ });
+ await waitForPromises();
+
+ expect(findFormComponent().exists()).toBe(isShown);
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_form_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_form_spec.js
index ca44e77e694..8e08864bdb8 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_form_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_form_spec.js
@@ -2,13 +2,11 @@ import { shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Vue, { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { GlCard, GlLoadingIcon } from 'jest/packages_and_registries/shared/stubs';
import component from '~/packages_and_registries/settings/project/components/container_expiration_policy_form.vue';
-import {
- UPDATE_SETTINGS_ERROR_MESSAGE,
- UPDATE_SETTINGS_SUCCESS_MESSAGE,
-} from '~/packages_and_registries/settings/project/constants';
+import { UPDATE_SETTINGS_ERROR_MESSAGE } from '~/packages_and_registries/settings/project/constants';
import updateContainerExpirationPolicyMutation from '~/packages_and_registries/settings/project/graphql/mutations/update_container_expiration_policy.mutation.graphql';
import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql';
import Tracking from '~/tracking';
@@ -20,6 +18,7 @@ describe('Container Expiration Policy Settings Form', () => {
const defaultProvidedValues = {
projectPath: 'path',
+ projectSettingsPath: 'settings-path',
};
const {
@@ -36,7 +35,7 @@ describe('Container Expiration Policy Settings Form', () => {
label: 'docker_container_retention_and_expiration_policies',
};
- const findForm = () => wrapper.find({ ref: 'form-element' });
+ const findForm = () => wrapper.find('form');
const findCancelButton = () => wrapper.find('[data-testid="cancel-button"');
const findSaveButton = () => wrapper.find('[data-testid="save-button"');
@@ -208,7 +207,9 @@ describe('Container Expiration Policy Settings Form', () => {
});
it('validation event updates buttons disabled state', async () => {
- mountComponent();
+ mountComponent({
+ props: { ...defaultProps, isEdited: true },
+ });
expect(findSaveButton().props('disabled')).toBe(false);
@@ -229,52 +230,22 @@ describe('Container Expiration Policy Settings Form', () => {
});
describe('form', () => {
- describe('form reset event', () => {
- it('calls the appropriate function', () => {
- mountComponent();
-
- findForm().trigger('reset');
-
- expect(wrapper.emitted('reset')).toEqual([[]]);
- });
-
- it('tracks the reset event', () => {
- mountComponent();
-
- findForm().trigger('reset');
-
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'reset_form', trackingPayload);
- });
-
- it('resets the errors objects', async () => {
- mountComponent({
- data: { apiErrors: { nameRegex: 'bar' }, localErrors: { nameRegexKeep: false } },
- });
-
- findForm().trigger('reset');
-
- await nextTick();
+ describe('form submit event', () => {
+ useMockLocationHelper();
- expect(findKeepRegexInput().props('error')).toBe('');
- expect(findRemoveRegexInput().props('error')).toBe('');
- expect(findSaveButton().props('disabled')).toBe(false);
- });
- });
-
- describe('form submit event ', () => {
it('save has type submit', () => {
mountComponent();
expect(findSaveButton().attributes('type')).toBe('submit');
});
- it('dispatches the correct apollo mutation', () => {
+ it('dispatches the correct apollo mutation', async () => {
const mutationResolver = jest.fn().mockResolvedValue(expirationPolicyMutationPayload());
mountComponentWithApollo({
mutationResolver,
});
- findForm().trigger('submit');
+ await submitForm();
expect(mutationResolver).toHaveBeenCalled();
});
@@ -286,9 +257,7 @@ describe('Container Expiration Policy Settings Form', () => {
queryPayload: expirationPolicyPayload({ keepN: null, cadence: null, olderThan: null }),
});
- await waitForPromises();
-
- findForm().trigger('submit');
+ await submitForm();
expect(mutationResolver).toHaveBeenCalledWith({
input: {
@@ -303,24 +272,26 @@ describe('Container Expiration Policy Settings Form', () => {
});
});
- it('tracks the submit event', () => {
+ it('tracks the submit event', async () => {
mountComponentWithApollo({
mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()),
});
- findForm().trigger('submit');
+ await submitForm();
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'submit_form', trackingPayload);
});
- it('show a success toast when submit succeed', async () => {
+ it('redirects to package and registry project settings page when submitted successfully', async () => {
mountComponentWithApollo({
mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()),
});
await submitForm();
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE);
+ expect(window.location.href.endsWith('settings-path?showSetupSuccessAlert=true')).toBe(
+ true,
+ );
});
describe('when submit fails', () => {
@@ -348,6 +319,7 @@ describe('Container Expiration Policy Settings Form', () => {
await submitForm();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE);
+ expect(window.location.href).toBeUndefined();
});
it('parses the error messages', async () => {
@@ -375,24 +347,24 @@ describe('Container Expiration Policy Settings Form', () => {
describe('form actions', () => {
describe('cancel button', () => {
- it('has type reset', () => {
+ it('links to project package and registry settings path', () => {
mountComponent();
- expect(findCancelButton().attributes('type')).toBe('reset');
+ expect(findCancelButton().attributes('href')).toBe(
+ defaultProvidedValues.projectSettingsPath,
+ );
});
it.each`
- isLoading | isEdited | mutationLoading
- ${true} | ${true} | ${true}
- ${false} | ${true} | ${true}
- ${false} | ${false} | ${true}
- ${true} | ${false} | ${false}
- ${false} | ${false} | ${false}
+ isLoading | mutationLoading
+ ${true} | ${true}
+ ${false} | ${true}
+ ${true} | ${false}
`(
- 'when isLoading is $isLoading, isEdited is $isEdited and mutationLoading is $mutationLoading is disabled',
- ({ isEdited, isLoading, mutationLoading }) => {
+ 'is disabled when isLoading is $isLoading and mutationLoading is $mutationLoading',
+ ({ isLoading, mutationLoading }) => {
mountComponent({
- props: { ...defaultProps, isEdited, isLoading },
+ props: { ...defaultProps, isLoading },
data: { mutationLoading },
});
@@ -409,18 +381,19 @@ describe('Container Expiration Policy Settings Form', () => {
});
it.each`
- isLoading | localErrors | mutationLoading
- ${true} | ${{}} | ${true}
- ${true} | ${{}} | ${false}
- ${false} | ${{}} | ${true}
- ${false} | ${{ foo: false }} | ${true}
- ${true} | ${{ foo: false }} | ${false}
- ${false} | ${{ foo: false }} | ${false}
+ isLoading | isEdited | localErrors | mutationLoading
+ ${true} | ${false} | ${{}} | ${true}
+ ${true} | ${false} | ${{}} | ${false}
+ ${false} | ${false} | ${{}} | ${true}
+ ${false} | ${false} | ${{}} | ${false}
+ ${false} | ${false} | ${{ foo: false }} | ${true}
+ ${true} | ${false} | ${{ foo: false }} | ${false}
+ ${false} | ${false} | ${{ foo: false }} | ${false}
`(
- 'when isLoading is $isLoading, localErrors is $localErrors and mutationLoading is $mutationLoading is disabled',
- ({ localErrors, isLoading, mutationLoading }) => {
+ 'is disabled when isLoading is $isLoading, isEdited is $isEdited, localErrors is $localErrors and mutationLoading is $mutationLoading',
+ ({ localErrors, isEdited, isLoading, mutationLoading }) => {
mountComponent({
- props: { ...defaultProps, isLoading },
+ props: { ...defaultProps, isEdited, isLoading },
data: { mutationLoading, localErrors },
});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_spec.js
index d83c717da6a..35baeaeac61 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/container_expiration_policy_spec.js
@@ -1,12 +1,14 @@
-import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { GlAlert, GlSprintf, GlLink, GlCard } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import component from '~/packages_and_registries/settings/project/components/container_expiration_policy.vue';
-import ContainerExpirationPolicyForm from '~/packages_and_registries/settings/project/components/container_expiration_policy_form.vue';
import {
+ CONTAINER_CLEANUP_POLICY_EDIT_RULES,
+ CONTAINER_CLEANUP_POLICY_SET_RULES,
+ CONTAINER_CLEANUP_POLICY_RULES_DESCRIPTION,
FETCH_SETTINGS_ERROR_MESSAGE,
UNAVAILABLE_FEATURE_INTRO_TEXT,
UNAVAILABLE_USER_FEATURE_TEXT,
@@ -14,11 +16,7 @@ import {
import expirationPolicyQuery from '~/packages_and_registries/settings/project/graphql/queries/get_expiration_policy.query.graphql';
import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
-import {
- expirationPolicyPayload,
- emptyExpirationPolicyPayload,
- containerExpirationPolicyData,
-} from '../mock_data';
+import { expirationPolicyPayload, emptyExpirationPolicyPayload } from '../mock_data';
describe('Container expiration policy project settings', () => {
let wrapper;
@@ -28,17 +26,19 @@ describe('Container expiration policy project settings', () => {
projectPath: 'path',
isAdmin: false,
adminSettingsPath: 'settingsPath',
+ cleanupSettingsPath: 'cleanupSettingsPath',
enableHistoricEntries: false,
helpPagePath: 'helpPagePath',
- showCleanupPolicyLink: false,
};
- const findFormComponent = () => wrapper.find(ContainerExpirationPolicyForm);
- const findAlert = () => wrapper.find(GlAlert);
- const findSettingsBlock = () => wrapper.find(SettingsBlock);
+ const findFormComponent = () => wrapper.findComponent(GlCard);
+ const findDescription = () => wrapper.findByTestId('description');
+ const findButton = () => wrapper.findByTestId('rules-button');
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findSettingsBlock = () => wrapper.findComponent(SettingsBlock);
const mountComponent = (provide = defaultProvidedValues, config) => {
- wrapper = shallowMount(component, {
+ wrapper = shallowMountExtended(component, {
stubs: {
GlSprintf,
SettingsBlock,
@@ -63,37 +63,19 @@ describe('Container expiration policy project settings', () => {
wrapper.destroy();
});
- describe('isEdited status', () => {
- it.each`
- description | apiResponse | workingCopy | result
- ${'empty response and no changes from user'} | ${emptyExpirationPolicyPayload()} | ${{}} | ${false}
- ${'empty response and changes from user'} | ${emptyExpirationPolicyPayload()} | ${{ enabled: true }} | ${true}
- ${'response and no changes'} | ${expirationPolicyPayload()} | ${containerExpirationPolicyData()} | ${false}
- ${'response and changes'} | ${expirationPolicyPayload()} | ${{ ...containerExpirationPolicyData(), nameRegex: '12345' }} | ${true}
- ${'response and empty'} | ${expirationPolicyPayload()} | ${{}} | ${true}
- `('$description', async ({ apiResponse, workingCopy, result }) => {
- mountComponentWithApollo({
- provide: { ...defaultProvidedValues, enableHistoricEntries: true },
- resolver: jest.fn().mockResolvedValue(apiResponse),
- });
- await waitForPromises();
-
- findFormComponent().vm.$emit('input', workingCopy);
-
- await waitForPromises();
-
- expect(findFormComponent().props('isEdited')).toBe(result);
- });
- });
-
it('renders the setting form', async () => {
mountComponentWithApollo({
resolver: jest.fn().mockResolvedValue(expirationPolicyPayload()),
});
await waitForPromises();
- expect(findFormComponent().exists()).toBe(true);
expect(findSettingsBlock().exists()).toBe(true);
+ expect(findFormComponent().exists()).toBe(true);
+ expect(findDescription().text()).toMatchInterpolatedText(
+ CONTAINER_CLEANUP_POLICY_RULES_DESCRIPTION,
+ );
+ expect(findButton().text()).toMatchInterpolatedText(CONTAINER_CLEANUP_POLICY_EDIT_RULES);
+ expect(findButton().attributes('href')).toBe(defaultProvidedValues.cleanupSettingsPath);
});
describe('the form is disabled', () => {
@@ -115,9 +97,9 @@ describe('Container expiration policy project settings', () => {
it('shows the admin part of the alert message', () => {
mountComponent({ ...defaultProvidedValues, isAdmin: true });
- const sprintf = findAlert().find(GlSprintf);
+ const sprintf = findAlert().findComponent(GlSprintf);
expect(sprintf.text()).toBe('administration settings');
- expect(sprintf.find(GlLink).attributes('href')).toBe(
+ expect(sprintf.findComponent(GlLink).attributes('href')).toBe(
defaultProvidedValues.adminSettingsPath,
);
});
@@ -157,6 +139,10 @@ describe('Container expiration policy project settings', () => {
await waitForPromises();
expect(findFormComponent().exists()).toBe(isShown);
+ if (isShown) {
+ expect(findButton().text()).toMatchInterpolatedText(CONTAINER_CLEANUP_POLICY_SET_RULES);
+ expect(findButton().attributes('href')).toBe(defaultProvidedValues.cleanupSettingsPath);
+ }
});
});
});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_dropdown_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_dropdown_spec.js
index 8b99ac6b06c..ae41fdf65e0 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_dropdown_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_dropdown_spec.js
@@ -14,8 +14,8 @@ describe('ExpirationDropdown', () => {
],
};
- const findFormSelect = () => wrapper.find(GlFormSelect);
- const findFormGroup = () => wrapper.find(GlFormGroup);
+ const findFormSelect = () => wrapper.findComponent(GlFormSelect);
+ const findFormGroup = () => wrapper.findComponent(GlFormGroup);
const findDescription = () => wrapper.find('[data-testid="description"]');
const findOptions = () => wrapper.findAll('[data-testid="option"]');
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_input_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_input_spec.js
index 6b681924fcf..1cea0704154 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_input_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_input_spec.js
@@ -16,11 +16,11 @@ describe('ExpirationInput', () => {
const tagsRegexHelpPagePath = 'fooPath';
- const findInput = () => wrapper.find(GlFormInput);
- const findFormGroup = () => wrapper.find(GlFormGroup);
+ const findInput = () => wrapper.findComponent(GlFormInput);
+ const findFormGroup = () => wrapper.findComponent(GlFormGroup);
const findLabel = () => wrapper.find('[data-testid="label"]');
const findDescription = () => wrapper.find('[data-testid="description"]');
- const findDescriptionLink = () => wrapper.find(GlLink);
+ const findDescriptionLink = () => wrapper.findComponent(GlLink);
const mountComponent = (props) => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_run_text_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_run_text_spec.js
index 94f7783afe7..653f2a8b40e 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_run_text_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_run_text_spec.js
@@ -11,8 +11,8 @@ describe('ExpirationToggle', () => {
let wrapper;
const value = 'foo';
- const findInput = () => wrapper.find(GlFormInput);
- const findFormGroup = () => wrapper.find(GlFormGroup);
+ const findInput = () => wrapper.findComponent(GlFormInput);
+ const findFormGroup = () => wrapper.findComponent(GlFormGroup);
const mountComponent = (propsData) => {
wrapper = shallowMount(component, {
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_toggle_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_toggle_spec.js
index 45039614e49..55a66cebd83 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_toggle_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/expiration_toggle_spec.js
@@ -10,7 +10,7 @@ import {
describe('ExpirationToggle', () => {
let wrapper;
- const findToggle = () => wrapper.find(GlToggle);
+ const findToggle = () => wrapper.findComponent(GlToggle);
const findDescription = () => wrapper.find('[data-testid="description"]');
const mountComponent = (propsData) => {
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/packages_cleanup_policy_form_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/packages_cleanup_policy_form_spec.js
index 86f45d78bae..daf0ee85fdf 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/packages_cleanup_policy_form_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/packages_cleanup_policy_form_spec.js
@@ -39,7 +39,7 @@ describe('Packages Cleanup Policy Settings Form', () => {
label: 'packages_cleanup_policies',
};
- const findForm = () => wrapper.find({ ref: 'form-element' });
+ const findForm = () => wrapper.findComponent({ ref: 'form-element' });
const findSaveButton = () => wrapper.findByTestId('save-button');
const findKeepNDuplicatedPackageFilesDropdown = () =>
wrapper.findByTestId('keep-n-duplicated-package-files-dropdown');
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js
index f576bc79eae..07d13839c61 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/registry_settings_app_spec.js
@@ -1,41 +1,99 @@
+import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import waitForPromises from 'helpers/wait_for_promises';
+import setWindowLocation from 'helpers/set_window_location_helper';
+import * as commonUtils from '~/lib/utils/common_utils';
import component from '~/packages_and_registries/settings/project/components/registry_settings_app.vue';
import ContainerExpirationPolicy from '~/packages_and_registries/settings/project/components/container_expiration_policy.vue';
import PackagesCleanupPolicy from '~/packages_and_registries/settings/project/components/packages_cleanup_policy.vue';
+import {
+ SHOW_SETUP_SUCCESS_ALERT,
+ UPDATE_SETTINGS_SUCCESS_MESSAGE,
+} from '~/packages_and_registries/settings/project/constants';
+
+jest.mock('~/lib/utils/common_utils');
describe('Registry Settings app', () => {
let wrapper;
- const findContainerExpirationPolicy = () => wrapper.find(ContainerExpirationPolicy);
- const findPackagesCleanupPolicy = () => wrapper.find(PackagesCleanupPolicy);
+ const findContainerExpirationPolicy = () => wrapper.findComponent(ContainerExpirationPolicy);
+ const findPackagesCleanupPolicy = () => wrapper.findComponent(PackagesCleanupPolicy);
+ const findAlert = () => wrapper.findComponent(GlAlert);
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
- const mountComponent = (provide) => {
+ const defaultProvide = {
+ showContainerRegistrySettings: true,
+ showPackageRegistrySettings: true,
+ };
+
+ const mountComponent = (provide = defaultProvide) => {
wrapper = shallowMount(component, {
provide,
});
};
- it.each`
- showContainerRegistrySettings | showPackageRegistrySettings
- ${true} | ${false}
- ${true} | ${true}
- ${false} | ${true}
- ${false} | ${false}
- `(
- 'container expiration policy $showContainerRegistrySettings and package cleanup policy is $showPackageRegistrySettings',
- ({ showContainerRegistrySettings, showPackageRegistrySettings }) => {
- mountComponent({
- showContainerRegistrySettings,
- showPackageRegistrySettings,
+ describe('container policy success alert handling', () => {
+ const originalLocation = window.location.href;
+ const search = `?${SHOW_SETUP_SUCCESS_ALERT}=true`;
+
+ beforeEach(() => {
+ setWindowLocation(search);
+ });
+
+ afterEach(() => {
+ setWindowLocation(originalLocation);
+ });
+
+ it(`renders alert if the query string contains ${SHOW_SETUP_SUCCESS_ALERT}`, async () => {
+ mountComponent();
+
+ await waitForPromises();
+
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().props()).toMatchObject({
+ dismissible: true,
+ variant: 'success',
});
+ expect(findAlert().text()).toMatchInterpolatedText(UPDATE_SETTINGS_SUCCESS_MESSAGE);
+ });
+
+ it('calls historyReplaceState with a clean url', () => {
+ mountComponent();
+
+ expect(commonUtils.historyReplaceState).toHaveBeenCalledWith(originalLocation);
+ });
+
+ it(`does nothing if the query string does not contain ${SHOW_SETUP_SUCCESS_ALERT}`, () => {
+ setWindowLocation('?');
+ mountComponent();
- expect(findContainerExpirationPolicy().exists()).toBe(showContainerRegistrySettings);
- expect(findPackagesCleanupPolicy().exists()).toBe(showPackageRegistrySettings);
- },
- );
+ expect(findAlert().exists()).toBe(false);
+ expect(commonUtils.historyReplaceState).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('settings', () => {
+ it.each`
+ showContainerRegistrySettings | showPackageRegistrySettings
+ ${true} | ${false}
+ ${true} | ${true}
+ ${false} | ${true}
+ ${false} | ${false}
+ `(
+ 'container expiration policy $showContainerRegistrySettings and package cleanup policy is $showPackageRegistrySettings',
+ ({ showContainerRegistrySettings, showPackageRegistrySettings }) => {
+ mountComponent({
+ showContainerRegistrySettings,
+ showPackageRegistrySettings,
+ });
+
+ expect(findContainerExpirationPolicy().exists()).toBe(showContainerRegistrySettings);
+ expect(findPackagesCleanupPolicy().exists()).toBe(showPackageRegistrySettings);
+ },
+ );
+ });
});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cli_commands_spec.js b/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
index 7727bf167fe..18084766db9 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cli_commands_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
@@ -15,15 +15,15 @@ import {
import Tracking from '~/tracking';
import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue';
-import { dockerCommands } from '../../mock_data';
+import { dockerCommands } from 'jest/packages_and_registries/container_registry/explorer/mock_data';
Vue.use(Vuex);
describe('cli_commands', () => {
let wrapper;
- const findDropdownButton = () => wrapper.find(GlDropdown);
- const findCodeInstruction = () => wrapper.findAll(CodeInstruction);
+ const findDropdownButton = () => wrapper.findComponent(GlDropdown);
+ const findCodeInstruction = () => wrapper.findAllComponents(CodeInstruction);
const mountComponent = () => {
wrapper = mount(QuickstartDropdown, {
diff --git a/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js b/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js
index d6d1970cb12..a0ff6ca01b5 100644
--- a/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/package_icon_and_name_spec.js
@@ -5,7 +5,7 @@ import PackageIconAndName from '~/packages_and_registries/shared/components/pack
describe('PackageIconAndName', () => {
let wrapper;
- const findIcon = () => wrapper.find(GlIcon);
+ const findIcon = () => wrapper.findComponent(GlIcon);
const mountComponent = () => {
wrapper = shallowMount(PackageIconAndName, {