summaryrefslogtreecommitdiff
path: root/spec/frontend/registry/explorer/pages/details_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/registry/explorer/pages/details_spec.js')
-rw-r--r--spec/frontend/registry/explorer/pages/details_spec.js521
1 files changed, 0 insertions, 521 deletions
diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js
deleted file mode 100644
index 21af9dcc60f..00000000000
--- a/spec/frontend/registry/explorer/pages/details_spec.js
+++ /dev/null
@@ -1,521 +0,0 @@
-import { GlKeysetPagination } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import axios from '~/lib/utils/axios_utils';
-import DeleteImage from '~/registry/explorer/components/delete_image.vue';
-import DeleteAlert from '~/registry/explorer/components/details_page/delete_alert.vue';
-import DetailsHeader from '~/registry/explorer/components/details_page/details_header.vue';
-import EmptyTagsState from '~/registry/explorer/components/details_page/empty_state.vue';
-import PartialCleanupAlert from '~/registry/explorer/components/details_page/partial_cleanup_alert.vue';
-import StatusAlert from '~/registry/explorer/components/details_page/status_alert.vue';
-import TagsList from '~/registry/explorer/components/details_page/tags_list.vue';
-import TagsLoader from '~/registry/explorer/components/details_page/tags_loader.vue';
-
-import {
- UNFINISHED_STATUS,
- DELETE_SCHEDULED,
- ALERT_DANGER_IMAGE,
- MISSING_OR_DELETED_IMAGE_BREADCRUMB,
- ROOT_IMAGE_TEXT,
-} from '~/registry/explorer/constants';
-import deleteContainerRepositoryTagsMutation from '~/registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql';
-import getContainerRepositoryDetailsQuery from '~/registry/explorer/graphql/queries/get_container_repository_details.query.graphql';
-
-import component from '~/registry/explorer/pages/details.vue';
-import Tracking from '~/tracking';
-
-import {
- graphQLImageDetailsMock,
- graphQLDeleteImageRepositoryTagsMock,
- containerRepositoryMock,
- graphQLEmptyImageDetailsMock,
- tagsMock,
-} from '../mock_data';
-import { DeleteModal } from '../stubs';
-
-const localVue = createLocalVue();
-
-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(EmptyTagsState);
- const findPartialCleanupAlert = () => wrapper.find(PartialCleanupAlert);
- const findStatusAlert = () => wrapper.find(StatusAlert);
- const findDeleteImage = () => wrapper.find(DeleteImage);
-
- const routeId = 1;
-
- const breadCrumbState = {
- updateName: jest.fn(),
- };
-
- const cleanTags = tagsMock.map((t) => {
- const result = { ...t };
- // eslint-disable-next-line no-underscore-dangle
- delete result.__typename;
- return result;
- });
-
- const waitForApolloRequestRender = async () => {
- await waitForPromises();
- await wrapper.vm.$nextTick();
- };
-
- const mountComponent = ({
- resolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock()),
- mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock),
- options,
- config = {},
- } = {}) => {
- localVue.use(VueApollo);
-
- const requestHandlers = [
- [getContainerRepositoryDetailsQuery, resolver],
- [deleteContainerRepositoryTagsMutation, mutationResolver],
- ];
-
- apolloProvider = createMockApollo(requestHandlers);
-
- wrapper = shallowMount(component, {
- localVue,
- apolloProvider,
- stubs: {
- DeleteModal,
- DeleteImage,
- },
- mocks: {
- $route: {
- params: {
- id: routeId,
- },
- },
- },
- provide() {
- return {
- breadCrumbState,
- config,
- };
- },
- ...options,
- });
- };
-
- beforeEach(() => {
- jest.spyOn(Tracking, 'event');
- });
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('when isLoading is true', () => {
- it('shows the loader', () => {
- mountComponent();
-
- expect(findTagsLoader().exists()).toBe(true);
- });
-
- it('does not show the list', () => {
- mountComponent();
-
- expect(findTagsList().exists()).toBe(false);
- });
- });
-
- 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();
-
- expect(findEmptyState().exists()).toBe(true);
- });
- });
-
- describe('list', () => {
- it('exists', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findTagsList().exists()).toBe(true);
- });
-
- it('has the correct props bound', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findTagsList().props()).toMatchObject({
- isMobile: false,
- });
- });
-
- describe('deleteEvent', () => {
- describe('single item', () => {
- let tagToBeDeleted;
- beforeEach(async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- [tagToBeDeleted] = cleanTags;
- findTagsList().vm.$emit('delete', [tagToBeDeleted]);
- });
-
- it('open the modal', async () => {
- expect(DeleteModal.methods.show).toHaveBeenCalled();
- });
-
- it('tracks a single delete event', () => {
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
- label: 'registry_tag_delete',
- });
- });
- });
-
- describe('multiple items', () => {
- beforeEach(async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- findTagsList().vm.$emit('delete', cleanTags);
- });
-
- it('open the modal', () => {
- expect(DeleteModal.methods.show).toHaveBeenCalled();
- });
-
- it('tracks a single delete event', () => {
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
- label: 'bulk_registry_tag_delete',
- });
- });
- });
- });
- });
-
- describe('modal', () => {
- it('exists', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findDeleteModal().exists()).toBe(true);
- });
-
- describe('cancel event', () => {
- it('tracks cancel_delete', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- findDeleteModal().vm.$emit('cancel');
-
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'cancel_delete', {
- label: 'registry_tag_delete',
- });
- });
- });
-
- describe('confirmDelete event', () => {
- let mutationResolver;
-
- beforeEach(() => {
- mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock);
- mountComponent({ mutationResolver });
-
- return waitForApolloRequestRender();
- });
- describe('when one item is selected to be deleted', () => {
- it('calls apollo mutation with the right parameters', async () => {
- findTagsList().vm.$emit('delete', [cleanTags[0]]);
-
- await wrapper.vm.$nextTick();
-
- findDeleteModal().vm.$emit('confirmDelete');
-
- expect(mutationResolver).toHaveBeenCalledWith(
- expect.objectContaining({ tagNames: [cleanTags[0].name] }),
- );
- });
- });
-
- describe('when more than one item is selected to be deleted', () => {
- it('calls apollo mutation with the right parameters', async () => {
- findTagsList().vm.$emit('delete', tagsMock);
-
- await wrapper.vm.$nextTick();
-
- findDeleteModal().vm.$emit('confirmDelete');
-
- expect(mutationResolver).toHaveBeenCalledWith(
- expect.objectContaining({ tagNames: tagsMock.map((t) => t.name) }),
- );
- });
- });
- });
- });
-
- describe('Header', () => {
- it('exists', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
- expect(findDetailsHeader().exists()).toBe(true);
- });
-
- it('has the correct props', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
- expect(findDetailsHeader().props()).toMatchObject({
- image: {
- name: containerRepositoryMock.name,
- project: {
- visibility: containerRepositoryMock.project.visibility,
- },
- },
- });
- });
- });
-
- describe('Delete Alert', () => {
- const config = {
- isAdmin: true,
- garbageCollectionHelpPagePath: 'baz',
- };
- const deleteAlertType = 'success_tag';
-
- it('exists', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
- expect(findDeleteAlert().exists()).toBe(true);
- });
-
- it('has the correct props', async () => {
- mountComponent({
- options: {
- data: () => ({
- deleteAlertType,
- }),
- },
- config,
- });
-
- await waitForApolloRequestRender();
-
- expect(findDeleteAlert().props()).toEqual({ ...config, deleteAlertType });
- });
- });
-
- describe('Partial Cleanup Alert', () => {
- const config = {
- runCleanupPoliciesHelpPagePath: 'foo',
- expirationPolicyHelpPagePath: 'bar',
- userCalloutsPath: 'call_out_path',
- userCalloutId: 'call_out_id',
- showUnfinishedTagCleanupCallout: true,
- };
-
- describe(`when expirationPolicyCleanupStatus is ${UNFINISHED_STATUS}`, () => {
- let resolver;
-
- beforeEach(() => {
- resolver = jest.fn().mockResolvedValue(
- graphQLImageDetailsMock({
- expirationPolicyCleanupStatus: UNFINISHED_STATUS,
- }),
- );
- });
-
- it('exists', async () => {
- mountComponent({ resolver, config });
-
- await waitForApolloRequestRender();
-
- expect(findPartialCleanupAlert().exists()).toBe(true);
- });
-
- it('has the correct props', async () => {
- mountComponent({ resolver, config });
-
- await waitForApolloRequestRender();
-
- expect(findPartialCleanupAlert().props()).toEqual({
- runCleanupPoliciesHelpPagePath: config.runCleanupPoliciesHelpPagePath,
- cleanupPoliciesHelpPagePath: config.expirationPolicyHelpPagePath,
- });
- });
-
- it('dismiss hides the component', async () => {
- jest.spyOn(axios, 'post').mockReturnValue();
-
- mountComponent({ resolver, config });
-
- await waitForApolloRequestRender();
-
- expect(findPartialCleanupAlert().exists()).toBe(true);
-
- findPartialCleanupAlert().vm.$emit('dismiss');
-
- await wrapper.vm.$nextTick();
-
- 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();
-
- expect(findPartialCleanupAlert().exists()).toBe(false);
- });
- });
-
- describe(`when expirationPolicyCleanupStatus is not ${UNFINISHED_STATUS}`, () => {
- it('the component is hidden', async () => {
- mountComponent({ config });
-
- await waitForApolloRequestRender();
-
- expect(findPartialCleanupAlert().exists()).toBe(false);
- });
- });
- });
-
- describe('Breadcrumb connection', () => {
- it('when the details are fetched updates the name', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(breadCrumbState.updateName).toHaveBeenCalledWith(containerRepositoryMock.name);
- });
-
- 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);
- });
-
- it(`when the image has no name set the breadcrumb to ${ROOT_IMAGE_TEXT}`, async () => {
- mountComponent({
- resolver: jest
- .fn()
- .mockResolvedValue(graphQLImageDetailsMock({ ...containerRepositoryMock, name: null })),
- });
-
- await waitForApolloRequestRender();
-
- expect(breadCrumbState.updateName).toHaveBeenCalledWith(ROOT_IMAGE_TEXT);
- });
- });
-
- 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');
-
- await wrapper.vm.$nextTick();
- };
-
- 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');
-
- await wrapper.vm.$nextTick();
-
- expect(findTagsLoader().exists()).toBe(true);
-
- findDeleteImage().vm.$emit('end');
-
- await wrapper.vm.$nextTick();
-
- expect(findTagsLoader().exists()).toBe(false);
- });
-
- it('binds correctly to delete-image error event', async () => {
- mountComponent();
-
- findDeleteImage().vm.$emit('error');
-
- await wrapper.vm.$nextTick();
-
- expect(findDeleteAlert().props('deleteAlertType')).toBe(ALERT_DANGER_IMAGE);
- });
- });
-});