2020-06-23 00:09:42 +05:30
|
|
|
import { shallowMount } from '@vue/test-utils';
|
|
|
|
import { GlPagination } from '@gitlab/ui';
|
2020-03-13 15:44:24 +05:30
|
|
|
import Tracking from '~/tracking';
|
|
|
|
import component from '~/registry/explorer/pages/details.vue';
|
2020-06-23 00:09:42 +05:30
|
|
|
import DeleteAlert from '~/registry/explorer/components/details_page/delete_alert.vue';
|
|
|
|
import DetailsHeader from '~/registry/explorer/components/details_page/details_header.vue';
|
|
|
|
import TagsLoader from '~/registry/explorer/components/details_page/tags_loader.vue';
|
2020-07-28 23:09:34 +05:30
|
|
|
import TagsList from '~/registry/explorer/components/details_page/tags_list.vue';
|
2020-06-23 00:09:42 +05:30
|
|
|
import EmptyTagsState from '~/registry/explorer/components/details_page/empty_tags_state.vue';
|
2020-05-24 23:13:21 +05:30
|
|
|
import { createStore } from '~/registry/explorer/stores/';
|
|
|
|
import {
|
|
|
|
SET_MAIN_LOADING,
|
|
|
|
SET_TAGS_LIST_SUCCESS,
|
|
|
|
SET_TAGS_PAGINATION,
|
2020-06-23 00:09:42 +05:30
|
|
|
SET_INITIAL_STATE,
|
2020-10-24 23:57:45 +05:30
|
|
|
} from '~/registry/explorer/stores/mutation_types';
|
2020-06-23 00:09:42 +05:30
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
import { tagsListResponse } from '../mock_data';
|
2020-07-28 23:09:34 +05:30
|
|
|
import { DeleteModal } from '../stubs';
|
2020-03-13 15:44:24 +05:30
|
|
|
|
|
|
|
describe('Details Page', () => {
|
|
|
|
let wrapper;
|
|
|
|
let dispatchSpy;
|
2020-05-24 23:13:21 +05:30
|
|
|
let store;
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
const findDeleteModal = () => wrapper.find(DeleteModal);
|
2020-03-13 15:44:24 +05:30
|
|
|
const findPagination = () => wrapper.find(GlPagination);
|
2020-06-23 00:09:42 +05:30
|
|
|
const findTagsLoader = () => wrapper.find(TagsLoader);
|
2020-07-28 23:09:34 +05:30
|
|
|
const findTagsList = () => wrapper.find(TagsList);
|
2020-06-23 00:09:42 +05:30
|
|
|
const findDeleteAlert = () => wrapper.find(DeleteAlert);
|
|
|
|
const findDetailsHeader = () => wrapper.find(DetailsHeader);
|
|
|
|
const findEmptyTagsState = () => wrapper.find(EmptyTagsState);
|
2020-03-13 15:44:24 +05:30
|
|
|
|
|
|
|
const routeId = window.btoa(JSON.stringify({ name: 'foo', tags_path: 'bar' }));
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
const tagsArrayToSelectedTags = tags =>
|
|
|
|
tags.reduce((acc, c) => {
|
|
|
|
acc[c.name] = true;
|
|
|
|
return acc;
|
|
|
|
}, {});
|
|
|
|
|
2020-04-22 19:07:51 +05:30
|
|
|
const mountComponent = options => {
|
2020-06-23 00:09:42 +05:30
|
|
|
wrapper = shallowMount(component, {
|
2020-03-13 15:44:24 +05:30
|
|
|
store,
|
|
|
|
stubs: {
|
2020-06-23 00:09:42 +05:30
|
|
|
DeleteModal,
|
2020-03-13 15:44:24 +05:30
|
|
|
},
|
|
|
|
mocks: {
|
|
|
|
$route: {
|
|
|
|
params: {
|
|
|
|
id: routeId,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-04-22 19:07:51 +05:30
|
|
|
...options,
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
2020-04-22 19:07:51 +05:30
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2020-05-24 23:13:21 +05:30
|
|
|
store = createStore();
|
2020-03-13 15:44:24 +05:30
|
|
|
dispatchSpy = jest.spyOn(store, 'dispatch');
|
2020-05-24 23:13:21 +05:30
|
|
|
dispatchSpy.mockResolvedValue();
|
|
|
|
store.commit(SET_TAGS_LIST_SUCCESS, tagsListResponse.data);
|
|
|
|
store.commit(SET_TAGS_PAGINATION, tagsListResponse.headers);
|
2020-03-13 15:44:24 +05:30
|
|
|
jest.spyOn(Tracking, 'event');
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
wrapper.destroy();
|
2020-05-24 23:13:21 +05:30
|
|
|
wrapper = null;
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('when isLoading is true', () => {
|
2020-04-08 14:13:33 +05:30
|
|
|
beforeEach(() => {
|
|
|
|
store.commit(SET_MAIN_LOADING, true);
|
2020-07-28 23:09:34 +05:30
|
|
|
mountComponent();
|
2020-04-08 14:13:33 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
afterEach(() => store.commit(SET_MAIN_LOADING, false));
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it('shows the loader', () => {
|
|
|
|
expect(findTagsLoader().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not show the list', () => {
|
|
|
|
expect(findTagsList().exists()).toBe(false);
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
2020-04-22 19:07:51 +05:30
|
|
|
|
|
|
|
it('does not show pagination', () => {
|
|
|
|
expect(findPagination().exists()).toBe(false);
|
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
describe('when the list of tags is empty', () => {
|
2020-04-22 19:07:51 +05:30
|
|
|
beforeEach(() => {
|
2020-07-28 23:09:34 +05:30
|
|
|
store.commit(SET_TAGS_LIST_SUCCESS, []);
|
2020-04-22 19:07:51 +05:30
|
|
|
mountComponent();
|
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('has the empty state', () => {
|
|
|
|
expect(findEmptyTagsState().exists()).toBe(true);
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
it('does not show the loader', () => {
|
|
|
|
expect(findTagsLoader().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not show the list', () => {
|
|
|
|
expect(findTagsList().exists()).toBe(false);
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
describe('list', () => {
|
2020-06-23 00:09:42 +05:30
|
|
|
beforeEach(() => {
|
|
|
|
mountComponent();
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('exists', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
expect(findTagsList().exists()).toBe(true);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('has the correct props bound', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
expect(findTagsList().props()).toMatchObject({
|
2020-06-23 00:09:42 +05:30
|
|
|
isDesktop: true,
|
|
|
|
tags: store.state.tags,
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe('deleteEvent', () => {
|
|
|
|
describe('single item', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
let tagToBeDeleted;
|
2020-06-23 00:09:42 +05:30
|
|
|
beforeEach(() => {
|
2020-07-28 23:09:34 +05:30
|
|
|
[tagToBeDeleted] = store.state.tags;
|
|
|
|
findTagsList().vm.$emit('delete', { [tagToBeDeleted.name]: true });
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('open the modal', () => {
|
|
|
|
expect(DeleteModal.methods.show).toHaveBeenCalled();
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('maps the selection to itemToBeDeleted', () => {
|
2020-07-28 23:09:34 +05:30
|
|
|
expect(wrapper.vm.itemsToBeDeleted).toEqual([tagToBeDeleted]);
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('tracks a single delete event', () => {
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
|
|
|
|
label: 'registry_tag_delete',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe('multiple items', () => {
|
2020-04-22 19:07:51 +05:30
|
|
|
beforeEach(() => {
|
2020-07-28 23:09:34 +05:30
|
|
|
findTagsList().vm.$emit('delete', tagsArrayToSelectedTags(store.state.tags));
|
2020-04-22 19:07:51 +05:30
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('open the modal', () => {
|
|
|
|
expect(DeleteModal.methods.show).toHaveBeenCalled();
|
2020-04-22 19:07:51 +05:30
|
|
|
});
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('maps the selection to itemToBeDeleted', () => {
|
|
|
|
expect(wrapper.vm.itemsToBeDeleted).toEqual(store.state.tags);
|
2020-05-24 23:13:21 +05:30
|
|
|
});
|
2020-04-22 19:07:51 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('tracks a single delete event', () => {
|
|
|
|
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'click_button', {
|
|
|
|
label: 'bulk_registry_tag_delete',
|
2020-04-22 19:07:51 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('pagination', () => {
|
2020-04-22 19:07:51 +05:30
|
|
|
beforeEach(() => {
|
|
|
|
mountComponent();
|
|
|
|
});
|
|
|
|
|
2020-03-13 15:44:24 +05:30
|
|
|
it('exists', () => {
|
|
|
|
expect(findPagination().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('is wired to the correct pagination props', () => {
|
|
|
|
const pagination = findPagination();
|
|
|
|
expect(pagination.props('perPage')).toBe(store.state.tagsPagination.perPage);
|
|
|
|
expect(pagination.props('totalItems')).toBe(store.state.tagsPagination.total);
|
|
|
|
expect(pagination.props('value')).toBe(store.state.tagsPagination.page);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('fetch the data from the API when the v-model changes', () => {
|
|
|
|
dispatchSpy.mockResolvedValue();
|
2020-06-23 00:09:42 +05:30
|
|
|
findPagination().vm.$emit(GlPagination.model.event, 2);
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(store.dispatch).toHaveBeenCalledWith('requestTagsList', {
|
2020-04-08 14:13:33 +05:30
|
|
|
params: wrapper.vm.$route.params.id,
|
2020-03-13 15:44:24 +05:30
|
|
|
pagination: { page: 2 },
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('modal', () => {
|
|
|
|
it('exists', () => {
|
2020-06-23 00:09:42 +05:30
|
|
|
mountComponent();
|
2020-03-13 15:44:24 +05:30
|
|
|
expect(findDeleteModal().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe('cancel event', () => {
|
|
|
|
it('tracks cancel_delete', () => {
|
|
|
|
mountComponent();
|
|
|
|
findDeleteModal().vm.$emit('cancel');
|
|
|
|
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'cancel_delete', {
|
|
|
|
label: 'registry_tag_delete',
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
});
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe('confirmDelete event', () => {
|
|
|
|
describe('when one item is selected to be deleted', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
mountComponent();
|
2020-07-28 23:09:34 +05:30
|
|
|
findTagsList().vm.$emit('delete', { [store.state.tags[0].name]: true });
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('dispatch requestDeleteTag with the right parameters', () => {
|
|
|
|
findDeleteModal().vm.$emit('confirmDelete');
|
|
|
|
expect(dispatchSpy).toHaveBeenCalledWith('requestDeleteTag', {
|
2020-03-13 15:44:24 +05:30
|
|
|
tag: store.state.tags[0],
|
2020-06-23 00:09:42 +05:30
|
|
|
params: routeId,
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe('when more than one item is selected to be deleted', () => {
|
2020-04-22 19:07:51 +05:30
|
|
|
beforeEach(() => {
|
2020-06-23 00:09:42 +05:30
|
|
|
mountComponent();
|
2020-07-28 23:09:34 +05:30
|
|
|
findTagsList().vm.$emit('delete', tagsArrayToSelectedTags(store.state.tags));
|
2020-04-22 19:07:51 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('dispatch requestDeleteTags with the right parameters', () => {
|
|
|
|
findDeleteModal().vm.$emit('confirmDelete');
|
|
|
|
expect(dispatchSpy).toHaveBeenCalledWith('requestDeleteTags', {
|
2020-03-13 15:44:24 +05:30
|
|
|
ids: store.state.tags.map(t => t.name),
|
2020-06-23 00:09:42 +05:30
|
|
|
params: routeId,
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe('Header', () => {
|
|
|
|
it('exists', () => {
|
|
|
|
mountComponent();
|
|
|
|
expect(findDetailsHeader().exists()).toBe(true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('has the correct props', () => {
|
|
|
|
mountComponent();
|
|
|
|
expect(findDetailsHeader().props()).toEqual({ imageName: 'foo' });
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|
|
|
|
});
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
describe('Delete Alert', () => {
|
2020-05-24 23:13:21 +05:30
|
|
|
const config = {
|
2020-06-23 00:09:42 +05:30
|
|
|
isAdmin: true,
|
|
|
|
garbageCollectionHelpPagePath: 'baz',
|
2020-05-24 23:13:21 +05:30
|
|
|
};
|
2020-06-23 00:09:42 +05:30
|
|
|
const deleteAlertType = 'success_tag';
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('exists', () => {
|
|
|
|
mountComponent();
|
|
|
|
expect(findDeleteAlert().exists()).toBe(true);
|
|
|
|
});
|
2020-05-24 23:13:21 +05:30
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
it('has the correct props', () => {
|
|
|
|
store.commit(SET_INITIAL_STATE, { ...config });
|
|
|
|
mountComponent({
|
|
|
|
data: () => ({
|
|
|
|
deleteAlertType,
|
|
|
|
}),
|
2020-05-24 23:13:21 +05:30
|
|
|
});
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(findDeleteAlert().props()).toEqual({ ...config, deleteAlertType });
|
2020-05-24 23:13:21 +05:30
|
|
|
});
|
|
|
|
});
|
2020-03-13 15:44:24 +05:30
|
|
|
});
|