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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 10:33:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-19 10:33:21 +0300
commit36a59d088eca61b834191dacea009677a96c052f (patch)
treee4f33972dab5d8ef79e3944a9f403035fceea43f /spec/frontend/packages_and_registries
parenta1761f15ec2cae7c7f7bbda39a75494add0dfd6f (diff)
Add latest changes from gitlab-org/gitlab@15-0-stable-eev15.0.0-rc42
Diffstat (limited to 'spec/frontend/packages_and_registries')
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js27
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/cleanup_status_spec.js38
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js5
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/utils_spec.js21
-rw-r--r--spec/frontend/packages_and_registries/dependency_proxy/app_spec.js83
-rw-r--r--spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js66
-rw-r--r--spec/frontend/packages_and_registries/dependency_proxy/mock_data.js14
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap12
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/__snapshots__/package_list_row_spec.js.snap39
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js29
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js41
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/packages_title_spec.js2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/components/list/tokens/package_type_token_spec.js5
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/dependency_proxy_settings_spec.js23
-rw-r--r--spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js12
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js19
17 files changed, 239 insertions, 206 deletions
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
index a8d0d15007c..ca666e38291 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
@@ -1,7 +1,7 @@
import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
-import { nextTick } from 'vue';
+import Vue, { nextTick } from 'vue';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -28,7 +28,6 @@ import { imageTagsCountMock } from '../../mock_data';
describe('Details Header', () => {
let wrapper;
let apolloProvider;
- let localVue;
const defaultImage = {
name: 'foo',
@@ -64,28 +63,18 @@ describe('Details Header', () => {
const mountComponent = ({
propsData = { image: defaultImage },
resolver = jest.fn().mockResolvedValue(imageTagsCountMock()),
- $apollo = undefined,
} = {}) => {
- const mocks = {};
+ Vue.use(VueApollo);
- if ($apollo) {
- mocks.$apollo = $apollo;
- } else {
- localVue = createLocalVue();
- localVue.use(VueApollo);
-
- const requestHandlers = [[getContainerRepositoryMetadata, resolver]];
- apolloProvider = createMockApollo(requestHandlers);
- }
+ const requestHandlers = [[getContainerRepositoryMetadata, resolver]];
+ apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMount(component, {
- localVue,
apolloProvider,
propsData,
directives: {
GlTooltip: createMockDirective(),
},
- mocks,
stubs: {
TitleArea,
GlDropdown,
@@ -98,7 +87,6 @@ describe('Details Header', () => {
// if we want to mix createMockApollo and manual mocks we need to reset everything
wrapper.destroy();
apolloProvider = undefined;
- localVue = undefined;
wrapper = null;
});
@@ -194,10 +182,7 @@ describe('Details Header', () => {
describe('metadata items', () => {
describe('tags count', () => {
it('displays "-- tags" while loading', async () => {
- // here we are forced to mock apollo because `waitForMetadataItems` waits
- // for two ticks, de facto allowing the promise to resolve, so there is
- // no way to catch the component as both rendered and in loading state
- mountComponent({ $apollo: { queries: { containerRepository: { loading: true } } } });
+ mountComponent();
await waitForMetadataItems();
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 e8ddad2d8ca..af5723267f4 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
@@ -1,8 +1,8 @@
-import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { GlLink, GlPopover, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { helpPagePath } from '~/helpers/help_page_helper';
import CleanupStatus from '~/packages_and_registries/container_registry/explorer/components/list_page/cleanup_status.vue';
import {
- CLEANUP_TIMED_OUT_ERROR_MESSAGE,
CLEANUP_STATUS_SCHEDULED,
CLEANUP_STATUS_ONGOING,
CLEANUP_STATUS_UNFINISHED,
@@ -17,12 +17,20 @@ describe('cleanup_status', () => {
const findMainIcon = () => wrapper.findByTestId('main-icon');
const findExtraInfoIcon = () => wrapper.findByTestId('extra-info');
+ const findPopover = () => wrapper.findComponent(GlPopover);
+
+ const cleanupPolicyHelpPage = helpPagePath(
+ 'user/packages/container_registry/reduce_container_registry_storage.html',
+ { anchor: 'how-the-cleanup-policy-works' },
+ );
const mountComponent = (propsData = { status: SCHEDULED_STATUS }) => {
wrapper = shallowMountExtended(CleanupStatus, {
propsData,
- directives: {
- GlTooltip: createMockDirective(),
+ stubs: {
+ GlLink,
+ GlPopover,
+ GlSprintf,
},
});
};
@@ -43,7 +51,7 @@ describe('cleanup_status', () => {
mountComponent({ status });
expect(findMainIcon().exists()).toBe(visible);
- expect(wrapper.text()).toBe(text);
+ expect(wrapper.text()).toContain(text);
},
);
@@ -53,12 +61,6 @@ describe('cleanup_status', () => {
expect(findMainIcon().exists()).toBe(true);
});
-
- it(`has the orange class when the status is ${UNFINISHED_STATUS}`, () => {
- mountComponent({ status: UNFINISHED_STATUS });
-
- expect(findMainIcon().classes('gl-text-orange-500')).toBe(true);
- });
});
describe('extra info icon', () => {
@@ -76,12 +78,18 @@ describe('cleanup_status', () => {
},
);
- it(`has a tooltip`, () => {
- mountComponent({ status: UNFINISHED_STATUS });
+ it(`has a popover with a learn more link and a time frame for the next run`, () => {
+ jest.spyOn(Date, 'now').mockImplementation(() => new Date('2063-04-04T00:42:00Z').getTime());
- const tooltip = getBinding(findExtraInfoIcon().element, 'gl-tooltip');
+ mountComponent({
+ status: UNFINISHED_STATUS,
+ expirationPolicy: { next_run: '2063-04-08T01:44:03Z' },
+ });
- expect(tooltip.value.title).toBe(CLEANUP_TIMED_OUT_ERROR_MESSAGE);
+ expect(findPopover().exists()).toBe(true);
+ expect(findPopover().text()).toContain('The cleanup will continue within 4 days. Learn more');
+ expect(findPopover().findComponent(GlLink).exists()).toBe(true);
+ expect(findPopover().findComponent(GlLink).attributes('href')).toBe(cleanupPolicyHelpPage);
});
});
});
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 7d09c09d03b..f811468550d 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
@@ -4,7 +4,6 @@ import { nextTick } from 'vue';
import Component from '~/packages_and_registries/container_registry/explorer/components/list_page/registry_header.vue';
import {
CONTAINER_REGISTRY_TITLE,
- LIST_INTRO_TEXT,
EXPIRATION_POLICY_DISABLED_TEXT,
SET_UP_CLEANUP,
} from '~/packages_and_registries/container_registry/explorer/constants';
@@ -135,9 +134,7 @@ describe('registry_header', () => {
it('is correctly bound to title_area props', () => {
mountComponent({ helpPagePath: 'foo' });
- expect(findTitleArea().props('infoMessages')).toEqual([
- { text: LIST_INTRO_TEXT, link: 'foo' },
- ]);
+ expect(findTitleArea().props('infoMessages')).toEqual([]);
});
});
});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/utils_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/utils_spec.js
new file mode 100644
index 00000000000..5063759a620
--- /dev/null
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/utils_spec.js
@@ -0,0 +1,21 @@
+import { timeTilRun } from '~/packages_and_registries/container_registry/explorer/utils';
+
+describe('Container registry utilities', () => {
+ describe('timeTilRun', () => {
+ beforeEach(() => {
+ jest.spyOn(Date, 'now').mockImplementation(() => new Date('2063-04-04T00:42:00Z').getTime());
+ });
+
+ it('should return a human readable time', () => {
+ const result = timeTilRun('2063-04-08T01:44:03Z');
+
+ expect(result).toBe('4 days');
+ });
+
+ it('should return an empty string with null times', () => {
+ const result = timeTilRun(null);
+
+ expect(result).toBe('');
+ });
+ });
+});
diff --git a/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js b/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
index dbe9793fb8c..fe4a2c06f1c 100644
--- a/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
+++ b/spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
@@ -9,7 +9,7 @@ import {
GlSprintf,
GlEmptyState,
} from '@gitlab/ui';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import MockAdapter from 'axios-mock-adapter';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -47,7 +47,6 @@ describe('DependencyProxyApp', () => {
const provideDefaults = {
groupPath: 'gitlab-org',
groupId: dummyGrouptId,
- dependencyProxyAvailable: true,
noManifestsIllustration: 'noManifestsIllustration',
};
@@ -74,7 +73,6 @@ describe('DependencyProxyApp', () => {
});
}
- const findProxyNotAvailableAlert = () => wrapper.findByTestId('proxy-not-available');
const findClipBoardButton = () => wrapper.findComponent(ClipboardButton);
const findFormGroup = () => wrapper.findComponent(GlFormGroup);
const findFormInputGroup = () => wrapper.findComponent(GlFormInputGroup);
@@ -103,59 +101,22 @@ describe('DependencyProxyApp', () => {
mock.restore();
});
- describe('when the dependency proxy is not available', () => {
- const createComponentArguments = {
- provide: { ...provideDefaults, dependencyProxyAvailable: false },
- };
-
- it('renders an info alert', () => {
- createComponent(createComponentArguments);
-
- expect(findProxyNotAvailableAlert().text()).toBe(
- DependencyProxyApp.i18n.proxyNotAvailableText,
- );
- });
-
- it('does not render the main area', () => {
- createComponent(createComponentArguments);
-
- expect(findMainArea().exists()).toBe(false);
- });
-
- it('does not call the graphql endpoint', async () => {
- resolver = jest.fn().mockResolvedValue(proxyDetailsQuery());
- createComponent({ ...createComponentArguments });
-
- await waitForPromises();
-
- expect(resolver).not.toHaveBeenCalled();
- });
-
- it('hides the clear cache dropdown list', () => {
- createComponent(createComponentArguments);
-
- expect(findClearCacheDropdownList().exists()).toBe(false);
- });
- });
-
describe('when the dependency proxy is available', () => {
describe('when is loading', () => {
- it('renders the skeleton loader', () => {
+ beforeEach(() => {
createComponent();
+ });
+ it('renders the skeleton loader', () => {
expect(findSkeletonLoader().exists()).toBe(true);
});
- it('does not show the main section', () => {
- createComponent();
-
- expect(findMainArea().exists()).toBe(false);
+ it('does not render a form group with label', () => {
+ expect(findFormGroup().exists()).toBe(false);
});
- it('does not render the info alert', () => {
- createComponent();
-
- expect(findProxyNotAvailableAlert().exists()).toBe(false);
+ it('does not show the main section', () => {
+ expect(findMainArea().exists()).toBe(false);
});
});
@@ -166,10 +127,6 @@ describe('DependencyProxyApp', () => {
return waitForPromises();
});
- it('does not render the info alert', () => {
- expect(findProxyNotAvailableAlert().exists()).toBe(false);
- });
-
it('renders the main area', () => {
expect(findMainArea().exists()).toBe(true);
});
@@ -193,7 +150,7 @@ describe('DependencyProxyApp', () => {
});
});
- it('from group has a description with proxy count', () => {
+ it('form group has a description with proxy count', () => {
expect(findProxyCountText().text()).toBe('Contains 2 blobs of images (1024 Bytes)');
});
@@ -257,6 +214,28 @@ describe('DependencyProxyApp', () => {
});
});
+ describe('triggering page event on list', () => {
+ beforeEach(async () => {
+ findManifestList().vm.$emit('next-page');
+
+ await nextTick();
+ });
+
+ it('re-renders the skeleton loader', () => {
+ expect(findSkeletonLoader().exists()).toBe(true);
+ });
+
+ it('renders form group with label', () => {
+ expect(findFormGroup().attributes('label')).toEqual(
+ expect.stringMatching(DependencyProxyApp.i18n.proxyImagePrefix),
+ );
+ });
+
+ it('does not show the main section', () => {
+ expect(findMainArea().exists()).toBe(false);
+ });
+ });
+
it('shows the clear cache dropdown list', () => {
expect(findClearCacheDropdownList().exists()).toBe(true);
diff --git a/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js b/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js
index b7cbd875497..be3236d1f9c 100644
--- a/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js
+++ b/spec/frontend/packages_and_registries/dependency_proxy/components/manifest_row_spec.js
@@ -3,6 +3,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ListItem from '~/vue_shared/components/registry/list_item.vue';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import Component from '~/packages_and_registries/dependency_proxy/components/manifest_row.vue';
+import { MANIFEST_PENDING_DESTRUCTION_STATUS } from '~/packages_and_registries/dependency_proxy/constants';
import { proxyManifests } from 'jest/packages_and_registries/dependency_proxy/mock_data';
describe('Manifest Row', () => {
@@ -26,34 +27,63 @@ describe('Manifest Row', () => {
const findListItem = () => wrapper.findComponent(ListItem);
const findCachedMessages = () => wrapper.findByTestId('cached-message');
const findTimeAgoTooltip = () => wrapper.findComponent(TimeagoTooltip);
-
- beforeEach(() => {
- createComponent();
- });
+ const findStatus = () => wrapper.findByTestId('status');
afterEach(() => {
wrapper.destroy();
});
- it('has a list item', () => {
- expect(findListItem().exists()).toBe(true);
- });
+ describe('With a manifest on the DEFAULT status', () => {
+ beforeEach(() => {
+ createComponent();
+ });
- it('displays the name', () => {
- expect(wrapper.text()).toContain('alpine');
- });
+ it('has a list item', () => {
+ expect(findListItem().exists()).toBe(true);
+ });
- it('displays the version', () => {
- expect(wrapper.text()).toContain('latest');
- });
+ it('displays the name', () => {
+ expect(wrapper.text()).toContain('alpine');
+ });
- it('displays the cached time', () => {
- expect(findCachedMessages().text()).toContain('Cached');
+ it('displays the version', () => {
+ expect(wrapper.text()).toContain('latest');
+ });
+
+ it('displays the cached time', () => {
+ expect(findCachedMessages().text()).toContain('Cached');
+ });
+
+ it('has a time ago tooltip component', () => {
+ expect(findTimeAgoTooltip().props()).toMatchObject({
+ time: defaultProps.manifest.createdAt,
+ });
+ });
+
+ it('does not have a status element displayed', () => {
+ expect(findStatus().exists()).toBe(false);
+ });
});
- it('has a time ago tooltip component', () => {
- expect(findTimeAgoTooltip().props()).toMatchObject({
- time: defaultProps.manifest.createdAt,
+ describe('With a manifest on the PENDING_DESTRUCTION_STATUS', () => {
+ const pendingDestructionManifest = {
+ manifest: {
+ ...defaultProps.manifest,
+ status: MANIFEST_PENDING_DESTRUCTION_STATUS,
+ },
+ };
+
+ beforeEach(() => {
+ createComponent(pendingDestructionManifest);
+ });
+
+ it('has a list item', () => {
+ expect(findListItem().exists()).toBe(true);
+ });
+
+ it('has a status element displayed', () => {
+ expect(findStatus().exists()).toBe(true);
+ expect(findStatus().text()).toBe('Scheduled for deletion');
});
});
});
diff --git a/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js b/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js
index 2aa427bc6af..37c8eb669ba 100644
--- a/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js
+++ b/spec/frontend/packages_and_registries/dependency_proxy/mock_data.js
@@ -8,8 +8,18 @@ export const proxyData = () => ({
export const proxySettings = (extend = {}) => ({ enabled: true, ...extend });
export const proxyManifests = () => [
- { id: 'proxy-1', createdAt: '2021-09-22T09:45:28Z', imageName: 'alpine:latest' },
- { id: 'proxy-2', createdAt: '2021-09-21T09:45:28Z', imageName: 'alpine:stable' },
+ {
+ id: 'proxy-1',
+ createdAt: '2021-09-22T09:45:28Z',
+ imageName: 'alpine:latest',
+ status: 'DEFAULT',
+ },
+ {
+ id: 'proxy-2',
+ createdAt: '2021-09-21T09:45:28Z',
+ imageName: 'alpine:stable',
+ status: 'DEFAULT',
+ },
];
export const pagination = (extend) => ({
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
index 519014bb9cf..fdddc131412 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap
@@ -29,12 +29,6 @@ exports[`PackageTitle renders with tags 1`] = `
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-3"
>
- <gl-icon-stub
- class="gl-mr-3"
- name="eye"
- size="16"
- />
-
<span
data-testid="sub-header"
>
@@ -127,12 +121,6 @@ exports[`PackageTitle renders without tags 1`] = `
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-3"
>
- <gl-icon-stub
- class="gl-mr-3"
- name="eye"
- size="16"
- />
-
<span
data-testid="sub-header"
>
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
index 5da9cfffaae..d306f7834f0 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
@@ -1,4 +1,4 @@
-import { GlIcon, GlSprintf } from '@gitlab/ui';
+import { GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import { nextTick } from 'vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -46,7 +46,6 @@ describe('PackageTitle', () => {
const findPackageRef = () => wrapper.findByTestId('package-ref');
const findPackageTags = () => wrapper.findComponent(PackageTags);
const findPackageBadges = () => wrapper.findAllByTestId('tag-badge');
- const findSubHeaderIcon = () => wrapper.findComponent(GlIcon);
const findSubHeaderText = () => wrapper.findByTestId('sub-header');
const findSubHeaderTimeAgo = () => wrapper.findComponent(TimeAgoTooltip);
@@ -120,12 +119,6 @@ describe('PackageTitle', () => {
});
describe('sub-header', () => {
- it('has the eye icon', async () => {
- await createComponent();
-
- expect(findSubHeaderIcon().props('name')).toBe('eye');
- });
-
it('has a text showing version', async () => {
await createComponent();
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 18a99f70756..031afa62890 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
@@ -38,8 +38,6 @@ exports[`packages_list_row renders 1`] = `
</router-link-stub>
<!---->
-
- <!---->
</div>
<!---->
@@ -98,16 +96,35 @@ exports[`packages_list_row renders 1`] = `
<div
class="gl-w-9 gl-display-flex gl-justify-content-end gl-pr-1"
>
- <gl-button-stub
- aria-label="Remove package"
- buttontextclasses=""
- category="secondary"
- data-testid="action-delete"
- icon="remove"
+ <gl-dropdown-stub
+ category="tertiary"
+ clearalltext="Clear all"
+ clearalltextclass="gl-px-5"
+ data-testid="delete-dropdown"
+ headertext=""
+ hideheaderborder="true"
+ highlighteditemstitle="Selected"
+ highlighteditemstitleclass="gl-px-5"
+ icon="ellipsis_v"
+ no-caret=""
size="medium"
- title="Remove package"
- variant="danger"
- />
+ text="More actions"
+ textsronly="true"
+ variant="default"
+ >
+ <gl-dropdown-item-stub
+ avatarurl=""
+ data-testid="action-delete"
+ iconcolor=""
+ iconname=""
+ iconrightarialabel=""
+ iconrightname=""
+ secondarytext=""
+ variant="danger"
+ >
+ Delete package
+ </gl-dropdown-item-stub>
+ </gl-dropdown-stub>
</div>
</div>
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 12a3eaa3873..c16c09b5326 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
@@ -28,12 +28,12 @@ describe('packages_list_row', () => {
const packageWithoutTags = { ...packageData(), project: packageProject() };
const packageWithTags = { ...packageWithoutTags, tags: { nodes: packageTags() } };
+ const packageCannotDestroy = { ...packageData(), canDestroy: false };
const findPackageTags = () => wrapper.find(PackageTags);
const findPackagePath = () => wrapper.find(PackagePath);
- const findDeleteButton = () => wrapper.findByTestId('action-delete');
+ const findDeleteDropdown = () => wrapper.findByTestId('action-delete');
const findPackageIconAndName = () => wrapper.find(PackageIconAndName);
- const findListItem = () => wrapper.findComponent(ListItem);
const findPackageLink = () => wrapper.findByTestId('details-link');
const findWarningIcon = () => wrapper.findByTestId('warning-icon');
const findLeftSecondaryInfos = () => wrapper.findByTestId('left-secondary-infos');
@@ -102,22 +102,25 @@ describe('packages_list_row', () => {
});
describe('delete button', () => {
+ it('does not exist when package cannot be destroyed', () => {
+ mountComponent({ packageEntity: packageCannotDestroy });
+
+ expect(findDeleteDropdown().exists()).toBe(false);
+ });
+
it('exists and has the correct props', () => {
mountComponent({ packageEntity: packageWithoutTags });
- expect(findDeleteButton().exists()).toBe(true);
- expect(findDeleteButton().attributes()).toMatchObject({
- icon: 'remove',
- category: 'secondary',
+ expect(findDeleteDropdown().exists()).toBe(true);
+ expect(findDeleteDropdown().attributes()).toMatchObject({
variant: 'danger',
- title: 'Remove package',
});
});
it('emits the packageToDelete event when the delete button is clicked', async () => {
mountComponent({ packageEntity: packageWithoutTags });
- findDeleteButton().vm.$emit('click');
+ findDeleteDropdown().vm.$emit('click');
await nextTick();
expect(wrapper.emitted('packageToDelete')).toBeTruthy();
@@ -130,10 +133,6 @@ describe('packages_list_row', () => {
mountComponent({ packageEntity: { ...packageWithoutTags, status: PACKAGE_ERROR_STATUS } });
});
- it('list item has a disabled prop', () => {
- expect(findListItem().props('disabled')).toBe(true);
- });
-
it('details link is disabled', () => {
expect(findPackageLink().props('event')).toBe('');
});
@@ -141,14 +140,14 @@ describe('packages_list_row', () => {
it('has a warning icon', () => {
const icon = findWarningIcon();
const tooltip = getBinding(icon.element, 'gl-tooltip');
- expect(icon.props('icon')).toBe('warning');
+ expect(icon.props('name')).toBe('warning');
expect(tooltip.value).toMatchObject({
title: 'Invalid Package: failed metadata extraction',
});
});
- it('delete button does not exist', () => {
- expect(findDeleteButton().exists()).toBe(false);
+ it('has a delete dropdown', () => {
+ expect(findDeleteDropdown().exists()).toBe(true);
});
});
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 97978dee909..660f00a2b31 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
@@ -1,4 +1,4 @@
-import { GlKeysetPagination, GlModal, GlSprintf } from '@gitlab/ui';
+import { GlAlert, GlKeysetPagination, GlModal, GlSprintf } from '@gitlab/ui';
import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PackagesListRow from '~/packages_and_registries/package_registry/components/list/package_list_row.vue';
@@ -21,6 +21,12 @@ describe('packages_list', () => {
id: 'gid://gitlab/Packages::Package/112',
name: 'second-package',
};
+ const errorPackage = {
+ ...packageData(),
+ id: 'gid://gitlab/Packages::Package/121',
+ status: 'ERROR',
+ name: 'error package',
+ };
const defaultProps = {
list: [firstPackage, secondPackage],
@@ -40,6 +46,7 @@ describe('packages_list', () => {
const findPackageListDeleteModal = () => wrapper.findComponent(GlModalStub);
const findEmptySlot = () => wrapper.findComponent(EmptySlotStub);
const findPackagesListRow = () => wrapper.findComponent(PackagesListRow);
+ const findErrorPackageAlert = () => wrapper.findComponent(GlAlert);
const mountComponent = (props) => {
wrapper = shallowMountExtended(PackagesList, {
@@ -109,6 +116,12 @@ describe('packages_list', () => {
expect(findPackageListDeleteModal().exists()).toBe(true);
});
+
+ it('does not have an error alert displayed', () => {
+ mountComponent();
+
+ expect(findErrorPackageAlert().exists()).toBe(false);
+ });
});
describe('when the user can destroy the package', () => {
@@ -140,6 +153,32 @@ describe('packages_list', () => {
});
});
+ describe('when an error package is present', () => {
+ beforeEach(() => {
+ mountComponent({ list: [firstPackage, errorPackage] });
+
+ return nextTick();
+ });
+
+ it('should display an alert message', () => {
+ expect(findErrorPackageAlert().exists()).toBe(true);
+ expect(findErrorPackageAlert().props('title')).toBe(
+ 'There was an error publishing a error package package',
+ );
+ expect(findErrorPackageAlert().text()).toBe(
+ 'There was a timeout and the package was not published. Delete this package and try again.',
+ );
+ });
+
+ it('should display the deletion modal when clicked on the confirm button', async () => {
+ findErrorPackageAlert().vm.$emit('primaryAction');
+
+ await nextTick();
+
+ expect(findPackageListDeleteModal().text()).toContain(errorPackage.name);
+ });
+ });
+
describe('when the list is empty', () => {
beforeEach(() => {
mountComponent({ list: [] });
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 e992ba12faa..23e5c7330d5 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
@@ -37,7 +37,7 @@ describe('PackageTitle', () => {
expect(findTitleArea().props()).toMatchObject({
title: PackageTitle.i18n.LIST_TITLE_TEXT,
- infoMessages: [{ text: PackageTitle.i18n.LIST_INTRO_TEXT, link: 'foo' }],
+ infoMessages: [],
});
});
});
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 26b2f3b359f..d0c111bae2d 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
@@ -11,7 +11,10 @@ describe('packages_filter', () => {
const mountComponent = ({ attrs, listeners } = {}) => {
wrapper = shallowMount(component, {
- attrs,
+ attrs: {
+ cursorPosition: 'start',
+ ...attrs,
+ },
listeners,
});
};
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 94f56e5c979..22754d31f93 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
@@ -6,11 +6,7 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import component from '~/packages_and_registries/settings/group/components/dependency_proxy_settings.vue';
-import {
- DEPENDENCY_PROXY_HEADER,
- DEPENDENCY_PROXY_SETTINGS_DESCRIPTION,
- DEPENDENCY_PROXY_DOCS_PATH,
-} from '~/packages_and_registries/settings/group/constants';
+import { DEPENDENCY_PROXY_HEADER } from '~/packages_and_registries/settings/group/constants';
import updateDependencyProxySettings from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_settings.mutation.graphql';
import updateDependencyProxyImageTtlGroupPolicy from '~/packages_and_registries/settings/group/graphql/mutations/update_dependency_proxy_image_ttl_group_policy.mutation.graphql';
@@ -91,8 +87,6 @@ describe('DependencyProxySettings', () => {
const findSettingsBlock = () => wrapper.findComponent(SettingsBlock);
const findSettingsTitles = () => wrapper.findComponent(SettingsTitles);
- const findDescription = () => wrapper.findByTestId('description');
- const findDescriptionLink = () => wrapper.findByTestId('description-link');
const findEnableProxyToggle = () => wrapper.findByTestId('dependency-proxy-setting-toggle');
const findEnableTtlPoliciesToggle = () =>
wrapper.findByTestId('dependency-proxy-ttl-policies-toggle');
@@ -126,21 +120,6 @@ describe('DependencyProxySettings', () => {
expect(wrapper.text()).toContain(DEPENDENCY_PROXY_HEADER);
});
- it('has the correct description text', () => {
- mountComponent();
-
- expect(findDescription().text()).toMatchInterpolatedText(DEPENDENCY_PROXY_SETTINGS_DESCRIPTION);
- });
-
- it('has the correct link', () => {
- mountComponent();
-
- expect(findDescriptionLink().attributes()).toMatchObject({
- href: DEPENDENCY_PROXY_DOCS_PATH,
- });
- expect(findDescriptionLink().text()).toBe('Learn more');
- });
-
describe('enable toggle', () => {
it('exists', () => {
mountComponent();
diff --git a/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js b/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js
index 5c30074a6af..635195ff0a4 100644
--- a/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js
+++ b/spec/frontend/packages_and_registries/settings/group/components/group_settings_app_spec.js
@@ -28,7 +28,6 @@ describe('Group Settings App', () => {
const defaultProvide = {
defaultExpanded: false,
groupPath: 'foo_group_path',
- dependencyProxyAvailable: true,
};
const mountComponent = ({
@@ -140,15 +139,4 @@ describe('Group Settings App', () => {
});
});
});
-
- describe('when the dependency proxy is not available', () => {
- beforeEach(() => {
- mountComponent({ provide: { ...defaultProvide, dependencyProxyAvailable: false } });
- return waitForApolloQueryAndRender();
- });
-
- it('the setting block is hidden', () => {
- expect(findDependencyProxySettings().exists()).toBe(false);
- });
- });
});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
index 266f953c3e0..465e6dc73e2 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
@@ -1,6 +1,6 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
-import { nextTick } from 'vue';
+import Vue, { nextTick } from 'vue';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { GlCard, GlLoadingIcon } from 'jest/packages_and_registries/shared/stubs';
@@ -14,8 +14,6 @@ import expirationPolicyQuery from '~/packages_and_registries/settings/project/gr
import Tracking from '~/tracking';
import { expirationPolicyPayload, expirationPolicyMutationPayload } from '../mock_data';
-const localVue = createLocalVue();
-
describe('Settings Form', () => {
let wrapper;
let fakeApollo;
@@ -59,7 +57,6 @@ describe('Settings Form', () => {
data,
config,
provide = defaultProvidedValues,
- mocks,
} = {}) => {
wrapper = shallowMount(component, {
stubs: {
@@ -77,7 +74,6 @@ describe('Settings Form', () => {
$toast: {
show: jest.fn(),
},
- ...mocks,
},
...config,
});
@@ -88,7 +84,7 @@ describe('Settings Form', () => {
mutationResolver,
queryPayload = expirationPolicyPayload(),
} = {}) => {
- localVue.use(VueApollo);
+ Vue.use(VueApollo);
const requestHandlers = [
[updateContainerExpirationPolicyMutation, mutationResolver],
@@ -120,7 +116,6 @@ describe('Settings Form', () => {
value,
},
config: {
- localVue,
apolloProvider: fakeApollo,
},
});
@@ -356,8 +351,8 @@ describe('Settings Form', () => {
});
it('parses the error messages', async () => {
- const mutate = jest.fn().mockRejectedValue({
- graphQLErrors: [
+ const mutate = jest.fn().mockResolvedValue({
+ errors: [
{
extensions: {
problems: [{ path: ['nameRegexKeep'], message: 'baz' }],
@@ -365,7 +360,9 @@ describe('Settings Form', () => {
},
],
});
- mountComponent({ mocks: { $apollo: { mutate } } });
+ mountComponentWithApollo({
+ mutationResolver: mutate,
+ });
await submitForm();