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>2020-03-25 15:08:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-25 15:08:19 +0300
commite6baeabaa9651d90b03bb64ffce75a2c3cb89aab (patch)
tree85f3cbd6e437b17be59505cf3ac4794c1838609e /spec/frontend/registry
parent5064bf8c5647d4c4430cbb4d097cf1592416de29 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/registry')
-rw-r--r--spec/frontend/registry/explorer/pages/details_spec.js63
-rw-r--r--spec/frontend/registry/explorer/pages/index_spec.js62
-rw-r--r--spec/frontend/registry/explorer/pages/list_spec.js41
-rw-r--r--spec/frontend/registry/explorer/stores/actions_spec.js67
-rw-r--r--spec/frontend/registry/explorer/stores/getters_spec.js18
-rw-r--r--spec/frontend/registry/explorer/stores/mutations_spec.js16
-rw-r--r--spec/frontend/registry/shared/mocks.js4
7 files changed, 222 insertions, 49 deletions
diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js
index 660004e5eea..60e509e4a88 100644
--- a/spec/frontend/registry/explorer/pages/details_spec.js
+++ b/spec/frontend/registry/explorer/pages/details_spec.js
@@ -5,8 +5,15 @@ import stubChildren from 'helpers/stub_children';
import component from '~/registry/explorer/pages/details.vue';
import store from '~/registry/explorer/stores/';
import { SET_MAIN_LOADING } from '~/registry/explorer/stores/mutation_types/';
+import {
+ DELETE_TAG_SUCCESS_MESSAGE,
+ DELETE_TAG_ERROR_MESSAGE,
+ DELETE_TAGS_SUCCESS_MESSAGE,
+ DELETE_TAGS_ERROR_MESSAGE,
+} from '~/registry/explorer/constants';
import { tagsListResponse } from '../mock_data';
import { GlModal } from '../stubs';
+import { $toast } from '../../shared/mocks';
describe('Details Page', () => {
let wrapper;
@@ -40,6 +47,7 @@ describe('Details Page', () => {
id: routeId,
},
},
+ $toast,
},
});
dispatchSpy = jest.spyOn(store, 'dispatch');
@@ -249,13 +257,11 @@ describe('Details Page', () => {
});
});
- it('when only one element is selected', () => {
- const deleteModal = findDeleteModal();
-
- wrapper.setData({ itemsToBeDeleted: [0] });
- deleteModal.vm.$emit('ok');
+ describe('when only one element is selected', () => {
+ it('execute the delete and remove selection', () => {
+ wrapper.setData({ itemsToBeDeleted: [0] });
+ findDeleteModal().vm.$emit('ok');
- return wrapper.vm.$nextTick().then(() => {
expect(store.dispatch).toHaveBeenCalledWith('requestDeleteTag', {
tag: store.state.tags[0],
params: wrapper.vm.$route.params.id,
@@ -264,15 +270,33 @@ describe('Details Page', () => {
expect(wrapper.vm.itemsToBeDeleted).toEqual([]);
expect(findCheckedCheckboxes()).toHaveLength(0);
});
+
+ it('show success toast on successful delete', () => {
+ return wrapper.vm.handleSingleDelete(0).then(() => {
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAG_SUCCESS_MESSAGE, {
+ type: 'success',
+ });
+ });
+ });
+
+ it('show error toast on erred delete', () => {
+ dispatchSpy.mockRejectedValue();
+ return wrapper.vm.handleSingleDelete(0).then(() => {
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAG_ERROR_MESSAGE, {
+ type: 'error',
+ });
+ });
+ });
});
- it('when multiple elements are selected', () => {
- const deleteModal = findDeleteModal();
+ describe('when multiple elements are selected', () => {
+ beforeEach(() => {
+ wrapper.setData({ itemsToBeDeleted: [0, 1] });
+ });
- wrapper.setData({ itemsToBeDeleted: [0, 1] });
- deleteModal.vm.$emit('ok');
+ it('execute the delete and remove selection', () => {
+ findDeleteModal().vm.$emit('ok');
- return wrapper.vm.$nextTick().then(() => {
expect(store.dispatch).toHaveBeenCalledWith('requestDeleteTags', {
ids: store.state.tags.map(t => t.name),
params: wrapper.vm.$route.params.id,
@@ -281,6 +305,23 @@ describe('Details Page', () => {
expect(wrapper.vm.itemsToBeDeleted).toEqual([]);
expect(findCheckedCheckboxes()).toHaveLength(0);
});
+
+ it('show success toast on successful delete', () => {
+ return wrapper.vm.handleMultipleDelete(0).then(() => {
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAGS_SUCCESS_MESSAGE, {
+ type: 'success',
+ });
+ });
+ });
+
+ it('show error toast on erred delete', () => {
+ dispatchSpy.mockRejectedValue();
+ return wrapper.vm.handleMultipleDelete(0).then(() => {
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_TAGS_ERROR_MESSAGE, {
+ type: 'error',
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/registry/explorer/pages/index_spec.js b/spec/frontend/registry/explorer/pages/index_spec.js
new file mode 100644
index 00000000000..f52e7d67866
--- /dev/null
+++ b/spec/frontend/registry/explorer/pages/index_spec.js
@@ -0,0 +1,62 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
+import component from '~/registry/explorer/pages/index.vue';
+import store from '~/registry/explorer/stores/';
+
+describe('List Page', () => {
+ let wrapper;
+ let dispatchSpy;
+
+ const findRouterView = () => wrapper.find({ ref: 'router-view' });
+ const findAlert = () => wrapper.find(GlAlert);
+ const findLink = () => wrapper.find(GlLink);
+
+ const mountComponent = () => {
+ wrapper = shallowMount(component, {
+ store,
+ stubs: {
+ RouterView: true,
+ GlSprintf,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ dispatchSpy = jest.spyOn(store, 'dispatch');
+ mountComponent();
+ });
+
+ it('has a router view', () => {
+ expect(findRouterView().exists()).toBe(true);
+ });
+
+ describe('garbageCollectionTip alert', () => {
+ beforeEach(() => {
+ store.dispatch('setInitialState', { isAdmin: true, garbageCollectionHelpPagePath: 'foo' });
+ store.dispatch('setShowGarbageCollectionTip', true);
+ });
+
+ afterEach(() => {
+ store.dispatch('setInitialState', {});
+ store.dispatch('setShowGarbageCollectionTip', false);
+ });
+
+ it('is visible when the user is an admin and the user performed a delete action', () => {
+ expect(findAlert().exists()).toBe(true);
+ });
+
+ it('on dismiss disappears ', () => {
+ findAlert().vm.$emit('dismiss');
+ expect(dispatchSpy).toHaveBeenCalledWith('setShowGarbageCollectionTip', false);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findAlert().exists()).toBe(false);
+ });
+ });
+
+ it('contains a link to the docs', () => {
+ const link = findLink();
+ expect(link.exists()).toBe(true);
+ expect(link.attributes('href')).toBe(store.state.config.garbageCollectionHelpPagePath);
+ });
+ });
+});
diff --git a/spec/frontend/registry/explorer/pages/list_spec.js b/spec/frontend/registry/explorer/pages/list_spec.js
index 5b713778495..3e46a29f776 100644
--- a/spec/frontend/registry/explorer/pages/list_spec.js
+++ b/spec/frontend/registry/explorer/pages/list_spec.js
@@ -8,8 +8,13 @@ import GroupEmptyState from '~/registry/explorer/components/group_empty_state.vu
import ProjectEmptyState from '~/registry/explorer/components/project_empty_state.vue';
import store from '~/registry/explorer/stores/';
import { SET_MAIN_LOADING } from '~/registry/explorer/stores/mutation_types/';
+import {
+ DELETE_IMAGE_SUCCESS_MESSAGE,
+ DELETE_IMAGE_ERROR_MESSAGE,
+} from '~/registry/explorer/constants';
import { imagesListResponse } from '../mock_data';
import { GlModal, GlEmptyState } from '../stubs';
+import { $toast } from '../../shared/mocks';
const localVue = createLocalVue();
localVue.use(VueRouter);
@@ -40,6 +45,9 @@ describe('List Page', () => {
GlEmptyState,
GlSprintf,
},
+ mocks: {
+ $toast,
+ },
});
dispatchSpy = jest.spyOn(store, 'dispatch');
store.dispatch('receiveImagesListSuccess', imagesListResponse);
@@ -174,11 +182,29 @@ describe('List Page', () => {
const itemToDelete = wrapper.vm.images[0];
wrapper.setData({ itemToDelete });
findDeleteModal().vm.$emit('ok');
- return wrapper.vm.$nextTick().then(() => {
- expect(store.dispatch).toHaveBeenCalledWith(
- 'requestDeleteImage',
- itemToDelete.destroy_path,
- );
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'requestDeleteImage',
+ itemToDelete.destroy_path,
+ );
+ });
+
+ it('should show a success toast when delete request is successful', () => {
+ dispatchSpy.mockResolvedValue();
+ return wrapper.vm.handleDeleteImage().then(() => {
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_IMAGE_SUCCESS_MESSAGE, {
+ type: 'success',
+ });
+ expect(wrapper.vm.itemToDelete).toEqual({});
+ });
+ });
+
+ it('should show a error toast when delete request fails', () => {
+ dispatchSpy.mockRejectedValue();
+ return wrapper.vm.handleDeleteImage().then(() => {
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(DELETE_IMAGE_ERROR_MESSAGE, {
+ type: 'error',
+ });
+ expect(wrapper.vm.itemToDelete).toEqual({});
});
});
});
@@ -227,7 +253,7 @@ describe('List Page', () => {
beforeEach(() => {
jest.spyOn(Tracking, 'event');
- dispatchSpy.mockReturnValue();
+ dispatchSpy.mockResolvedValue();
});
it('send an event when delete button is clicked', () => {
@@ -235,13 +261,14 @@ describe('List Page', () => {
deleteBtn.vm.$emit('click');
testTrackingCall('click_button');
});
+
it('send an event when cancel is pressed on modal', () => {
const deleteModal = findDeleteModal();
deleteModal.vm.$emit('cancel');
testTrackingCall('cancel_delete');
});
+
it('send an event when confirm is clicked on modal', () => {
- dispatchSpy.mockReturnValue();
const deleteModal = findDeleteModal();
deleteModal.vm.$emit('ok');
testTrackingCall('confirm_delete');
diff --git a/spec/frontend/registry/explorer/stores/actions_spec.js b/spec/frontend/registry/explorer/stores/actions_spec.js
index 3e22621058e..b39c79dd1ab 100644
--- a/spec/frontend/registry/explorer/stores/actions_spec.js
+++ b/spec/frontend/registry/explorer/stores/actions_spec.js
@@ -38,6 +38,17 @@ describe('Actions RegistryExplorer Store', () => {
);
});
+ it('setShowGarbageCollectionTip', done => {
+ testAction(
+ actions.setShowGarbageCollectionTip,
+ true,
+ null,
+ [{ type: types.SET_SHOW_GARBAGE_COLLECTION_TIP, payload: true }],
+ [],
+ done,
+ );
+ });
+
describe('receives api responses', () => {
const response = {
data: [1, 2, 3],
@@ -183,18 +194,19 @@ describe('Actions RegistryExplorer Store', () => {
[{ type: types.SET_MAIN_LOADING, payload: true }],
[
{
+ type: 'setShowGarbageCollectionTip',
+ payload: true,
+ },
+ {
type: 'requestTagsList',
payload: { pagination: {}, params },
},
],
- () => {
- expect(createFlash).toHaveBeenCalled();
- done();
- },
+ done,
);
});
- it('should show flash message on error', done => {
+ it('should turn off loading on error', done => {
testAction(
actions.requestDeleteTag,
{
@@ -208,10 +220,7 @@ describe('Actions RegistryExplorer Store', () => {
{ type: types.SET_MAIN_LOADING, payload: false },
],
[],
- () => {
- expect(createFlash).toHaveBeenCalled();
- done();
- },
+ done,
);
});
});
@@ -235,18 +244,19 @@ describe('Actions RegistryExplorer Store', () => {
[{ type: types.SET_MAIN_LOADING, payload: true }],
[
{
+ type: 'setShowGarbageCollectionTip',
+ payload: true,
+ },
+ {
type: 'requestTagsList',
payload: { pagination: {}, params },
},
],
- () => {
- expect(createFlash).toHaveBeenCalled();
- done();
- },
+ done,
);
});
- it('should show flash message on error', done => {
+ it('should turn off loading on error', done => {
mock.onDelete(url).replyOnce(500);
testAction(
@@ -263,17 +273,14 @@ describe('Actions RegistryExplorer Store', () => {
{ type: types.SET_MAIN_LOADING, payload: false },
],
[],
- () => {
- expect(createFlash).toHaveBeenCalled();
- done();
- },
+ done,
);
});
});
describe('request delete single image', () => {
+ const deletePath = 'delete/path';
it('successfully performs the delete request', done => {
- const deletePath = 'delete/path';
mock.onDelete(deletePath).replyOnce(200);
testAction(
@@ -288,32 +295,32 @@ describe('Actions RegistryExplorer Store', () => {
],
[
{
+ type: 'setShowGarbageCollectionTip',
+ payload: true,
+ },
+ {
type: 'requestImagesList',
payload: { pagination: {} },
},
],
- () => {
- expect(createFlash).toHaveBeenCalled();
- done();
- },
+ done,
);
});
- it('should show flash message on error', done => {
+ it('should turn off loading on error', done => {
+ mock.onDelete(deletePath).replyOnce(400);
testAction(
actions.requestDeleteImage,
- null,
+ deletePath,
{},
[
{ type: types.SET_MAIN_LOADING, payload: true },
{ type: types.SET_MAIN_LOADING, payload: false },
],
[],
- () => {
- expect(createFlash).toHaveBeenCalled();
- done();
- },
- );
+ ).catch(() => {
+ done();
+ });
});
});
});
diff --git a/spec/frontend/registry/explorer/stores/getters_spec.js b/spec/frontend/registry/explorer/stores/getters_spec.js
index 211b8169d82..cd053ea8edc 100644
--- a/spec/frontend/registry/explorer/stores/getters_spec.js
+++ b/spec/frontend/registry/explorer/stores/getters_spec.js
@@ -49,4 +49,22 @@ describe('Getters RegistryExplorer store', () => {
expect(getters[getter](state)).toBe(expectedPieces.join(' '));
});
});
+
+ describe('showGarbageCollection', () => {
+ it.each`
+ result | showGarbageCollectionTip | isAdmin
+ ${true} | ${true} | ${true}
+ ${false} | ${true} | ${false}
+ ${false} | ${false} | ${true}
+ `(
+ 'return $result when showGarbageCollectionTip $showGarbageCollectionTip and isAdmin is $isAdmin',
+ ({ result, showGarbageCollectionTip, isAdmin }) => {
+ state = {
+ config: { isAdmin },
+ showGarbageCollectionTip,
+ };
+ expect(getters.showGarbageCollection(state)).toBe(result);
+ },
+ );
+ });
});
diff --git a/spec/frontend/registry/explorer/stores/mutations_spec.js b/spec/frontend/registry/explorer/stores/mutations_spec.js
index 1d5055c02d2..029fd23f7ce 100644
--- a/spec/frontend/registry/explorer/stores/mutations_spec.js
+++ b/spec/frontend/registry/explorer/stores/mutations_spec.js
@@ -10,7 +10,12 @@ describe('Mutations Registry Explorer Store', () => {
describe('SET_INITIAL_STATE', () => {
it('should set the initial state', () => {
- const payload = { endpoint: 'foo', isGroupPage: true, expirationPolicy: { foo: 'bar' } };
+ const payload = {
+ endpoint: 'foo',
+ isGroupPage: true,
+ expirationPolicy: { foo: 'bar' },
+ isAdmin: true,
+ };
const expectedState = { ...mockState, config: payload };
mutations[types.SET_INITIAL_STATE](mockState, {
...payload,
@@ -50,6 +55,15 @@ describe('Mutations Registry Explorer Store', () => {
});
});
+ describe('SET_SHOW_GARBAGE_COLLECTION_TIP', () => {
+ it('should set the showGarbageCollectionTip', () => {
+ const expectedState = { ...mockState, showGarbageCollectionTip: true };
+ mutations[types.SET_SHOW_GARBAGE_COLLECTION_TIP](mockState, true);
+
+ expect(mockState).toEqual(expectedState);
+ });
+ });
+
describe('SET_PAGINATION', () => {
const generatePagination = () => [
{
diff --git a/spec/frontend/registry/shared/mocks.js b/spec/frontend/registry/shared/mocks.js
new file mode 100644
index 00000000000..e33d06e7499
--- /dev/null
+++ b/spec/frontend/registry/shared/mocks.js
@@ -0,0 +1,4 @@
+// eslint-disable-next-line import/prefer-default-export
+export const $toast = {
+ show: jest.fn(),
+};