2022-01-05 15:13:51 +00:00
|
|
|
import { GlKeysetPagination, GlEmptyState } from '@gitlab/ui';
|
2022-01-25 12:14:14 +00:00
|
|
|
import { shallowMount } from '@vue/test-utils';
|
|
|
|
import Vue, { nextTick } from 'vue';
|
2020-12-10 15:10:12 +00:00
|
|
|
import VueApollo from 'vue-apollo';
|
2022-01-25 12:14:14 +00:00
|
|
|
|
2021-01-15 00:10:45 +00:00
|
|
|
import createMockApollo from 'helpers/mock_apollo_helper';
|
2020-12-10 15:10:12 +00:00
|
|
|
import waitForPromises from 'helpers/wait_for_promises';
|
2021-01-26 18:09:30 +00:00
|
|
|
import axios from '~/lib/utils/axios_utils';
|
2021-11-16 18:12:21 +00:00
|
|
|
import DeleteImage from '~/packages_and_registries/container_registry/explorer/components/delete_image.vue';
|
|
|
|
import DeleteAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue';
|
|
|
|
import DetailsHeader from '~/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue';
|
|
|
|
import PartialCleanupAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert.vue';
|
|
|
|
import StatusAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/status_alert.vue';
|
|
|
|
import TagsList from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue';
|
2022-01-20 15:11:58 +00:00
|
|
|
import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue';
|
2020-12-10 15:10:12 +00:00
|
|
|
|
2021-02-05 18:09:44 +00:00
|
|
|
import {
|
|
|
|
UNFINISHED_STATUS,
|
|
|
|
DELETE_SCHEDULED,
|
|
|
|
ALERT_DANGER_IMAGE,
|
2022-03-16 21:09:14 +00:00
|
|
|
ALERT_DANGER_IMPORTING,
|
2021-03-09 21:09:15 +00:00
|
|
|
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
|
2022-01-05 15:13:51 +00:00
|
|
|
MISSING_OR_DELETED_IMAGE_TITLE,
|
|
|
|
MISSING_OR_DELETED_IMAGE_MESSAGE,
|
2021-11-16 18:12:21 +00:00
|
|
|
} from '~/packages_and_registries/container_registry/explorer/constants';
|
|
|
|
import deleteContainerRepositoryTagsMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql';
|
|
|
|
import getContainerRepositoryDetailsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_details.query.graphql';
|
2021-11-24 21:12:47 +00:00
|
|
|
import getContainerRepositoryTagsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql';
|
2021-02-14 18:09:20 +00:00
|
|
|
|
2021-11-16 18:12:21 +00:00
|
|
|
import component from '~/packages_and_registries/container_registry/explorer/pages/details.vue';
|
2021-02-14 18:09:20 +00:00
|
|
|
import Tracking from '~/tracking';
|
2021-01-05 18:10:25 +00:00
|
|
|
|
2020-05-06 12:09:36 +00:00
|
|
|
import {
|
2020-12-10 15:10:12 +00:00
|
|
|
graphQLImageDetailsMock,
|
|
|
|
graphQLDeleteImageRepositoryTagsMock,
|
2022-03-16 21:09:14 +00:00
|
|
|
graphQLDeleteImageRepositoryTagImportingErrorMock,
|
2020-12-10 15:10:12 +00:00
|
|
|
containerRepositoryMock,
|
2021-02-01 15:08:56 +00:00
|
|
|
graphQLEmptyImageDetailsMock,
|
2020-12-10 15:10:12 +00:00
|
|
|
tagsMock,
|
2021-11-24 21:12:47 +00:00
|
|
|
imageTagsMock,
|
2020-12-10 15:10:12 +00:00
|
|
|
} from '../mock_data';
|
2020-06-26 09:08:59 +00:00
|
|
|
import { DeleteModal } from '../stubs';
|
2020-02-13 12:08:49 +00:00
|
|
|
|
|
|
|
describe('Details Page', () => {
|
|
|
|
let wrapper;
|
2020-12-10 15:10:12 +00:00
|
|
|
let apolloProvider;
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2022-09-12 21:10:38 +00:00
|
|
|
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);
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-11-10 12:08:57 +00:00
|
|
|
const routeId = 1;
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
const breadCrumbState = {
|
|
|
|
updateName: jest.fn(),
|
|
|
|
};
|
|
|
|
|
2022-01-05 15:13:51 +00:00
|
|
|
const defaultConfig = {
|
|
|
|
noContainersImage: 'noContainersImage',
|
|
|
|
};
|
|
|
|
|
2020-12-24 00:10:25 +00:00
|
|
|
const cleanTags = tagsMock.map((t) => {
|
2020-12-10 15:10:12 +00:00
|
|
|
const result = { ...t };
|
|
|
|
// eslint-disable-next-line no-underscore-dangle
|
|
|
|
delete result.__typename;
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
|
|
|
|
const waitForApolloRequestRender = async () => {
|
|
|
|
await waitForPromises();
|
2021-11-24 21:12:47 +00:00
|
|
|
await nextTick();
|
2020-12-10 15:10:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const mountComponent = ({
|
|
|
|
resolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock()),
|
|
|
|
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock),
|
2021-11-24 21:12:47 +00:00
|
|
|
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock)),
|
2020-12-10 15:10:12 +00:00
|
|
|
options,
|
2022-01-05 15:13:51 +00:00
|
|
|
config = defaultConfig,
|
2020-12-10 15:10:12 +00:00
|
|
|
} = {}) => {
|
2022-01-25 12:14:14 +00:00
|
|
|
Vue.use(VueApollo);
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
const requestHandlers = [
|
|
|
|
[getContainerRepositoryDetailsQuery, resolver],
|
|
|
|
[deleteContainerRepositoryTagsMutation, mutationResolver],
|
2021-11-24 21:12:47 +00:00
|
|
|
[getContainerRepositoryTagsQuery, tagsResolver],
|
2020-12-10 15:10:12 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
apolloProvider = createMockApollo(requestHandlers);
|
|
|
|
|
2020-06-10 12:08:58 +00:00
|
|
|
wrapper = shallowMount(component, {
|
2020-12-10 15:10:12 +00:00
|
|
|
apolloProvider,
|
2020-02-13 12:08:49 +00:00
|
|
|
stubs: {
|
2020-06-05 15:08:23 +00:00
|
|
|
DeleteModal,
|
2021-02-05 18:09:44 +00:00
|
|
|
DeleteImage,
|
2020-02-13 12:08:49 +00:00
|
|
|
},
|
|
|
|
mocks: {
|
|
|
|
$route: {
|
|
|
|
params: {
|
2020-11-10 12:08:57 +00:00
|
|
|
id: routeId,
|
2020-02-13 12:08:49 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-12-10 15:10:12 +00:00
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
breadCrumbState,
|
2020-12-11 12:09:43 +00:00
|
|
|
config,
|
2020-12-10 15:10:12 +00:00
|
|
|
};
|
|
|
|
},
|
2020-03-31 15:07:53 +00:00
|
|
|
...options,
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
2020-03-31 15:07:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2020-02-13 12:08:49 +00:00
|
|
|
jest.spyOn(Tracking, 'event');
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
wrapper.destroy();
|
2020-05-05 15:09:42 +00:00
|
|
|
wrapper = null;
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('when isLoading is true', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
it('shows the loader', () => {
|
2020-06-26 09:08:59 +00:00
|
|
|
mountComponent();
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-06-26 09:08:59 +00:00
|
|
|
expect(findTagsLoader().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not show the list', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
mountComponent();
|
|
|
|
|
2020-06-26 09:08:59 +00:00
|
|
|
expect(findTagsList().exists()).toBe(false);
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-02-01 15:08:56 +00:00
|
|
|
describe('when the image does not exist', () => {
|
|
|
|
it('does not show the default ui', async () => {
|
|
|
|
mountComponent({ resolver: jest.fn().mockResolvedValue(graphQLEmptyImageDetailsMock) });
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
|
|
|
expect(findTagsLoader().exists()).toBe(false);
|
|
|
|
expect(findDetailsHeader().exists()).toBe(false);
|
|
|
|
expect(findTagsList().exists()).toBe(false);
|
|
|
|
expect(findPagination().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows an empty state message', async () => {
|
|
|
|
mountComponent({ resolver: jest.fn().mockResolvedValue(graphQLEmptyImageDetailsMock) });
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2022-01-05 15:13:51 +00:00
|
|
|
expect(findEmptyState().props()).toMatchObject({
|
|
|
|
description: MISSING_OR_DELETED_IMAGE_MESSAGE,
|
|
|
|
svgPath: defaultConfig.noContainersImage,
|
|
|
|
title: MISSING_OR_DELETED_IMAGE_TITLE,
|
|
|
|
});
|
2021-02-01 15:08:56 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2020-06-26 09:08:59 +00:00
|
|
|
describe('list', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
it('exists', async () => {
|
2020-06-10 12:08:58 +00:00
|
|
|
mountComponent();
|
2020-03-31 15:07:53 +00:00
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2020-06-26 09:08:59 +00:00
|
|
|
expect(findTagsList().exists()).toBe(true);
|
2020-06-10 12:08:58 +00:00
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
it('has the correct props bound', async () => {
|
|
|
|
mountComponent();
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2020-06-26 09:08:59 +00:00
|
|
|
expect(findTagsList().props()).toMatchObject({
|
2020-11-06 18:09:07 +00:00
|
|
|
isMobile: false,
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
2020-06-10 12:08:58 +00:00
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-06-10 12:08:58 +00:00
|
|
|
describe('deleteEvent', () => {
|
|
|
|
describe('single item', () => {
|
2020-06-26 09:08:59 +00:00
|
|
|
let tagToBeDeleted;
|
2020-12-10 15:10:12 +00:00
|
|
|
beforeEach(async () => {
|
|
|
|
mountComponent();
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
|
|
|
[tagToBeDeleted] = cleanTags;
|
2021-04-28 18:10:12 +00:00
|
|
|
findTagsList().vm.$emit('delete', [tagToBeDeleted]);
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
it('open the modal', async () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
expect(DeleteModal.methods.show).toHaveBeenCalled();
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
|
2020-06-10 12:08:58 +00:00
|
|
|
it('tracks a single delete event', () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
|
2020-06-10 12:08:58 +00:00
|
|
|
label: 'registry_tag_delete',
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2020-03-31 15:07:53 +00:00
|
|
|
|
2020-06-10 12:08:58 +00:00
|
|
|
describe('multiple items', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
beforeEach(async () => {
|
|
|
|
mountComponent();
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2021-04-28 18:10:12 +00:00
|
|
|
findTagsList().vm.$emit('delete', cleanTags);
|
2020-03-31 15:07:53 +00:00
|
|
|
});
|
|
|
|
|
2020-06-10 12:08:58 +00:00
|
|
|
it('open the modal', () => {
|
|
|
|
expect(DeleteModal.methods.show).toHaveBeenCalled();
|
2020-03-31 15:07:53 +00:00
|
|
|
});
|
2020-05-11 21:09:40 +00:00
|
|
|
|
2020-06-10 12:08:58 +00:00
|
|
|
it('tracks a single delete event', () => {
|
|
|
|
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
|
|
|
|
label: 'bulk_registry_tag_delete',
|
2020-03-31 15:07:53 +00:00
|
|
|
});
|
|
|
|
});
|
2020-05-11 12:10:28 +00:00
|
|
|
});
|
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('modal', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
it('exists', async () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
mountComponent();
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2020-02-13 12:08:49 +00:00
|
|
|
expect(findDeleteModal().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
describe('cancel event', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
it('tracks cancel_delete', async () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
mountComponent();
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
findDeleteModal().vm.$emit('cancel');
|
2020-12-10 15:10:12 +00:00
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'cancel_delete', {
|
|
|
|
label: 'registry_tag_delete',
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
});
|
2020-06-05 15:08:23 +00:00
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
describe('confirmDelete event', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
let mutationResolver;
|
2021-11-24 21:12:47 +00:00
|
|
|
let tagsResolver;
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock);
|
2021-11-24 21:12:47 +00:00
|
|
|
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock));
|
|
|
|
mountComponent({ mutationResolver, tagsResolver });
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
return waitForApolloRequestRender();
|
|
|
|
});
|
2021-11-24 21:12:47 +00:00
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
describe('when one item is selected to be deleted', () => {
|
2021-11-24 21:12:47 +00:00
|
|
|
it('calls apollo mutation with the right parameters and refetches the tags list query', async () => {
|
2021-04-28 18:10:12 +00:00
|
|
|
findTagsList().vm.$emit('delete', [cleanTags[0]]);
|
2020-12-10 15:10:12 +00:00
|
|
|
|
2021-11-24 21:12:47 +00:00
|
|
|
await nextTick();
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
findDeleteModal().vm.$emit('confirmDelete');
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
expect(mutationResolver).toHaveBeenCalledWith(
|
|
|
|
expect.objectContaining({ tagNames: [cleanTags[0].name] }),
|
|
|
|
);
|
2021-11-24 21:12:47 +00:00
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
expect(tagsResolver).toHaveBeenCalled();
|
2020-06-05 15:08:23 +00:00
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
describe('when more than one item is selected to be deleted', () => {
|
2021-11-24 21:12:47 +00:00
|
|
|
it('calls apollo mutation with the right parameters and refetches the tags list query', async () => {
|
2021-04-28 18:10:12 +00:00
|
|
|
findTagsList().vm.$emit('delete', tagsMock);
|
2020-12-10 15:10:12 +00:00
|
|
|
|
2021-11-24 21:12:47 +00:00
|
|
|
await nextTick();
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
findDeleteModal().vm.$emit('confirmDelete');
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
expect(mutationResolver).toHaveBeenCalledWith(
|
2020-12-24 00:10:25 +00:00
|
|
|
expect.objectContaining({ tagNames: tagsMock.map((t) => t.name) }),
|
2020-12-10 15:10:12 +00:00
|
|
|
);
|
2021-11-24 21:12:47 +00:00
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
expect(tagsResolver).toHaveBeenCalled();
|
2020-06-05 15:08:23 +00:00
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
});
|
2020-06-05 15:08:23 +00:00
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
describe('Header', () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
it('exists', async () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
mountComponent();
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
2020-06-05 15:08:23 +00:00
|
|
|
expect(findDetailsHeader().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
it('has the correct props', async () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
mountComponent();
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
2021-01-05 18:10:25 +00:00
|
|
|
expect(findDetailsHeader().props()).toMatchObject({
|
|
|
|
image: {
|
|
|
|
name: containerRepositoryMock.name,
|
|
|
|
project: {
|
|
|
|
visibility: containerRepositoryMock.project.visibility,
|
|
|
|
},
|
2020-12-11 15:10:04 +00:00
|
|
|
},
|
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|
|
|
|
});
|
2020-05-05 15:09:42 +00:00
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
describe('Delete Alert', () => {
|
2020-05-05 15:09:42 +00:00
|
|
|
const config = {
|
2020-06-05 15:08:23 +00:00
|
|
|
isAdmin: true,
|
|
|
|
garbageCollectionHelpPagePath: 'baz',
|
2022-03-16 21:09:14 +00:00
|
|
|
containerRegistryImportingHelpPagePath: 'https://foobar',
|
2020-05-05 15:09:42 +00:00
|
|
|
};
|
2020-06-05 15:08:23 +00:00
|
|
|
const deleteAlertType = 'success_tag';
|
2020-05-05 15:09:42 +00:00
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
it('exists', async () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
mountComponent();
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
2020-06-05 15:08:23 +00:00
|
|
|
expect(findDeleteAlert().exists()).toBe(true);
|
|
|
|
});
|
2020-05-05 15:09:42 +00:00
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
it('has the correct props', async () => {
|
2020-06-05 15:08:23 +00:00
|
|
|
mountComponent({
|
2020-10-02 12:09:03 +00:00
|
|
|
options: {
|
|
|
|
data: () => ({
|
|
|
|
deleteAlertType,
|
|
|
|
}),
|
|
|
|
},
|
2020-12-11 12:09:43 +00:00
|
|
|
config,
|
2020-05-05 15:09:42 +00:00
|
|
|
});
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2020-06-05 15:08:23 +00:00
|
|
|
expect(findDeleteAlert().props()).toEqual({ ...config, deleteAlertType });
|
2020-05-05 15:09:42 +00:00
|
|
|
});
|
2022-03-16 21:09:14 +00:00
|
|
|
|
|
|
|
describe('importing repository error', () => {
|
|
|
|
let mutationResolver;
|
|
|
|
let tagsResolver;
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
mutationResolver = jest
|
|
|
|
.fn()
|
|
|
|
.mockResolvedValue(graphQLDeleteImageRepositoryTagImportingErrorMock);
|
|
|
|
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock));
|
|
|
|
|
|
|
|
mountComponent({ mutationResolver, tagsResolver });
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('displays the proper alert', async () => {
|
|
|
|
findTagsList().vm.$emit('delete', [cleanTags[0]]);
|
|
|
|
await nextTick();
|
|
|
|
|
|
|
|
findDeleteModal().vm.$emit('confirmDelete');
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
expect(tagsResolver).toHaveBeenCalled();
|
|
|
|
|
|
|
|
const deleteAlert = findDeleteAlert();
|
|
|
|
expect(deleteAlert.exists()).toBe(true);
|
|
|
|
expect(deleteAlert.props('deleteAlertType')).toBe(ALERT_DANGER_IMPORTING);
|
|
|
|
});
|
|
|
|
});
|
2020-05-05 15:09:42 +00:00
|
|
|
});
|
2020-10-02 12:09:03 +00:00
|
|
|
|
|
|
|
describe('Partial Cleanup Alert', () => {
|
|
|
|
const config = {
|
|
|
|
runCleanupPoliciesHelpPagePath: 'foo',
|
2021-07-28 21:08:53 +00:00
|
|
|
expirationPolicyHelpPagePath: 'bar',
|
2021-01-26 18:09:30 +00:00
|
|
|
userCalloutsPath: 'call_out_path',
|
|
|
|
userCalloutId: 'call_out_id',
|
|
|
|
showUnfinishedTagCleanupCallout: true,
|
2020-10-02 12:09:03 +00:00
|
|
|
};
|
|
|
|
|
2021-01-05 18:10:25 +00:00
|
|
|
describe(`when expirationPolicyCleanupStatus is ${UNFINISHED_STATUS}`, () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
let resolver;
|
|
|
|
|
2020-11-10 12:08:57 +00:00
|
|
|
beforeEach(() => {
|
2020-12-10 15:10:12 +00:00
|
|
|
resolver = jest.fn().mockResolvedValue(
|
|
|
|
graphQLImageDetailsMock({
|
2021-01-05 18:10:25 +00:00
|
|
|
expirationPolicyCleanupStatus: UNFINISHED_STATUS,
|
2020-12-10 15:10:12 +00:00
|
|
|
}),
|
|
|
|
);
|
2020-11-10 12:08:57 +00:00
|
|
|
});
|
2021-01-26 18:09:30 +00:00
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
it('exists', async () => {
|
2021-01-26 18:09:30 +00:00
|
|
|
mountComponent({ resolver, config });
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
2020-10-02 12:09:03 +00:00
|
|
|
|
|
|
|
expect(findPartialCleanupAlert().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
it('has the correct props', async () => {
|
2020-12-11 12:09:43 +00:00
|
|
|
mountComponent({ resolver, config });
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
2020-10-02 12:09:03 +00:00
|
|
|
|
2021-01-26 18:09:30 +00:00
|
|
|
expect(findPartialCleanupAlert().props()).toEqual({
|
|
|
|
runCleanupPoliciesHelpPagePath: config.runCleanupPoliciesHelpPagePath,
|
2021-07-28 21:08:53 +00:00
|
|
|
cleanupPoliciesHelpPagePath: config.expirationPolicyHelpPagePath,
|
2021-01-26 18:09:30 +00:00
|
|
|
});
|
2020-10-02 12:09:03 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('dismiss hides the component', async () => {
|
2021-01-26 18:09:30 +00:00
|
|
|
jest.spyOn(axios, 'post').mockReturnValue();
|
|
|
|
|
|
|
|
mountComponent({ resolver, config });
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
2020-10-02 12:09:03 +00:00
|
|
|
|
|
|
|
expect(findPartialCleanupAlert().exists()).toBe(true);
|
2020-12-10 15:10:12 +00:00
|
|
|
|
2020-10-02 12:09:03 +00:00
|
|
|
findPartialCleanupAlert().vm.$emit('dismiss');
|
|
|
|
|
2021-11-24 21:12:47 +00:00
|
|
|
await nextTick();
|
2020-10-02 12:09:03 +00:00
|
|
|
|
2021-01-26 18:09:30 +00:00
|
|
|
expect(axios.post).toHaveBeenCalledWith(config.userCalloutsPath, {
|
|
|
|
feature_name: config.userCalloutId,
|
|
|
|
});
|
|
|
|
expect(findPartialCleanupAlert().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('is hidden if the callout is dismissed', async () => {
|
|
|
|
mountComponent({ resolver });
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2020-10-02 12:09:03 +00:00
|
|
|
expect(findPartialCleanupAlert().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-01-05 18:10:25 +00:00
|
|
|
describe(`when expirationPolicyCleanupStatus is not ${UNFINISHED_STATUS}`, () => {
|
2020-12-10 15:10:12 +00:00
|
|
|
it('the component is hidden', async () => {
|
2021-01-26 18:09:30 +00:00
|
|
|
mountComponent({ config });
|
|
|
|
|
2020-12-10 15:10:12 +00:00
|
|
|
await waitForApolloRequestRender();
|
2020-10-02 12:09:03 +00:00
|
|
|
|
|
|
|
expect(findPartialCleanupAlert().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2020-12-10 15:10:12 +00:00
|
|
|
|
|
|
|
describe('Breadcrumb connection', () => {
|
|
|
|
it('when the details are fetched updates the name', async () => {
|
|
|
|
mountComponent();
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
|
|
|
expect(breadCrumbState.updateName).toHaveBeenCalledWith(containerRepositoryMock.name);
|
|
|
|
});
|
2021-03-09 21:09:15 +00:00
|
|
|
|
|
|
|
it(`when the image is missing set the breadcrumb to ${MISSING_OR_DELETED_IMAGE_BREADCRUMB}`, async () => {
|
|
|
|
mountComponent({ resolver: jest.fn().mockResolvedValue(graphQLEmptyImageDetailsMock) });
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
|
|
|
expect(breadCrumbState.updateName).toHaveBeenCalledWith(MISSING_OR_DELETED_IMAGE_BREADCRUMB);
|
|
|
|
});
|
|
|
|
|
2022-07-04 09:09:31 +00:00
|
|
|
it(`when the image has no name set the breadcrumb to project name`, async () => {
|
2021-03-09 21:09:15 +00:00
|
|
|
mountComponent({
|
|
|
|
resolver: jest
|
|
|
|
.fn()
|
|
|
|
.mockResolvedValue(graphQLImageDetailsMock({ ...containerRepositoryMock, name: null })),
|
|
|
|
});
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
2022-07-04 09:09:31 +00:00
|
|
|
expect(breadCrumbState.updateName).toHaveBeenCalledWith('gitlab-test');
|
2021-03-09 21:09:15 +00:00
|
|
|
});
|
2020-12-10 15:10:12 +00:00
|
|
|
});
|
2021-02-05 18:09:44 +00:00
|
|
|
|
|
|
|
describe('when the image has a status different from null', () => {
|
|
|
|
const resolver = jest
|
|
|
|
.fn()
|
|
|
|
.mockResolvedValue(graphQLImageDetailsMock({ status: DELETE_SCHEDULED }));
|
|
|
|
it('disables all the actions', async () => {
|
|
|
|
mountComponent({ resolver });
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
|
|
|
expect(findDetailsHeader().props('disabled')).toBe(true);
|
|
|
|
expect(findTagsList().props('disabled')).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('shows a status alert', async () => {
|
|
|
|
mountComponent({ resolver });
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
|
|
|
|
expect(findStatusAlert().exists()).toBe(true);
|
|
|
|
expect(findStatusAlert().props()).toMatchObject({
|
|
|
|
status: DELETE_SCHEDULED,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('delete the image', () => {
|
|
|
|
const mountComponentAndDeleteImage = async () => {
|
|
|
|
mountComponent();
|
|
|
|
|
|
|
|
await waitForApolloRequestRender();
|
|
|
|
findDetailsHeader().vm.$emit('delete');
|
|
|
|
|
2021-11-24 21:12:47 +00:00
|
|
|
await nextTick();
|
2021-02-05 18:09:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
it('on delete event it deletes the image', async () => {
|
|
|
|
await mountComponentAndDeleteImage();
|
|
|
|
|
|
|
|
findDeleteModal().vm.$emit('confirmDelete');
|
|
|
|
|
|
|
|
expect(findDeleteImage().emitted('start')).toEqual([[]]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('binds the correct props to the modal', async () => {
|
|
|
|
await mountComponentAndDeleteImage();
|
|
|
|
|
|
|
|
expect(findDeleteModal().props()).toMatchObject({
|
|
|
|
itemsToBeDeleted: [{ path: 'gitlab-org/gitlab-test/rails-12009' }],
|
|
|
|
deleteImage: true,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('binds correctly to delete-image start and end events', async () => {
|
|
|
|
mountComponent();
|
|
|
|
|
|
|
|
findDeleteImage().vm.$emit('start');
|
|
|
|
|
2022-01-24 21:14:06 +00:00
|
|
|
await waitForPromises();
|
2021-02-05 18:09:44 +00:00
|
|
|
|
|
|
|
expect(findTagsLoader().exists()).toBe(true);
|
|
|
|
|
|
|
|
findDeleteImage().vm.$emit('end');
|
|
|
|
|
2021-11-24 21:12:47 +00:00
|
|
|
await nextTick();
|
2021-02-05 18:09:44 +00:00
|
|
|
|
|
|
|
expect(findTagsLoader().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('binds correctly to delete-image error event', async () => {
|
|
|
|
mountComponent();
|
|
|
|
|
|
|
|
findDeleteImage().vm.$emit('error');
|
|
|
|
|
2021-11-24 21:12:47 +00:00
|
|
|
await nextTick();
|
2021-02-05 18:09:44 +00:00
|
|
|
|
|
|
|
expect(findDeleteAlert().props('deleteAlertType')).toBe(ALERT_DANGER_IMAGE);
|
|
|
|
});
|
|
|
|
});
|
2020-02-13 12:08:49 +00:00
|
|
|
});
|