Commit 7c65db20 authored by Mike Greiling's avatar Mike Greiling

Merge branch '33905-add-vuex-store' into 'master'

Add vuex store for package list app

See merge request gitlab-org/gitlab!19711
parents 0f264cd7 92bea793
import { __ } from '~/locale';
export const FETCH_PACKAGES_LIST_ERROR_MESSAGE = __(
'Something went wrong while fetching the packages list.',
);
export const FETCH_PACKAGE_ERROR_MESSAGE = __('Something went wrong while fetching the package.');
export const DELETE_PACKAGE_ERROR_MESSAGE = __('Something went wrong while deleting the package.');
import Api from '~/api';
import createFlash from '~/flash';
import * as types from './mutation_types';
import { FETCH_PACKAGES_LIST_ERROR_MESSAGE, DELETE_PACKAGE_ERROR_MESSAGE } from '../constants';
export const setProjectId = ({ commit }, data) => commit(types.SET_PROJECT_ID, data);
export const setUserCanDelete = ({ commit }, data) => commit(types.SET_USER_CAN_DELETE, data);
export const setLoading = ({ commit }, data) => commit(types.SET_MAIN_LOADING, data);
export const receivePackagesListSuccess = ({ commit }, data) =>
commit(types.SET_PACKAGE_LIST_SUCCESS, data);
export const requestPackagesList = ({ dispatch, state }) => {
dispatch('setLoading', true);
const { page, perPage } = state.pagination;
return Api.projectPackages(state.projectId, { params: { page, perPage } })
.then(({ data }) => {
dispatch('receivePackagesListSuccess', data);
})
.catch(() => {
createFlash(FETCH_PACKAGES_LIST_ERROR_MESSAGE);
})
.finally(() => {
dispatch('setLoading', false);
});
};
export const requestDeletePackage = ({ dispatch }, { projectId, packageId }) => {
dispatch('setLoading', true);
return Api.deleteProjectPackage(projectId, packageId)
.then(() => dispatch('fetchPackages'))
.catch(() => {
createFlash(DELETE_PACKAGE_ERROR_MESSAGE);
})
.finally(() => {
dispatch('setLoading', false);
});
};
export default () => {};
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
import mutations from './mutations';
import state from './state';
Vue.use(Vuex);
export const createStore = () =>
new Vuex.Store({
state,
actions,
mutations,
});
export default createStore();
export const SET_PROJECT_ID = 'SET_PROJECT_ID';
export const SET_USER_CAN_DELETE = 'SET_USER_CAN_DELETE';
export const SET_PACKAGE_LIST = 'SET_PACKAGE_LIST';
export const SET_PAGINATION = 'SET_PAGINATION';
export const SET_MAIN_LOADING = 'SET_MAIN_LOADING';
import * as types from './mutation_types';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
export default {
[types.SET_PROJECT_ID](state, projectId) {
state.projectId = projectId;
},
[types.SET_USER_CAN_DELETE](state, userCanDelete) {
state.userCanDelete = userCanDelete;
},
[types.SET_PACKAGE_LIST](state, packages) {
state.packages = packages;
},
[types.SET_MAIN_LOADING](state, isLoading) {
state.isLoading = isLoading;
},
[types.SET_PAGINATION](state, { headers }) {
const normalizedHeaders = normalizeHeaders(headers);
state.pagination = parseIntPagination(normalizedHeaders);
},
};
export default () => ({
isLoading: false,
/** project id used to fetch data */
projectId: null,
userCanDelete: false, // controls the delete buttons in the list
/**
* Each object in `packages` has the following structure:
* {
* id: String
* name: String,
* version: String,
* package_type: String // endpoint to request the list
* }
*/
packages: [],
pagination: {},
});
import * as actions from 'ee/packages/list/stores/actions';
import * as types from 'ee/packages/list/stores/mutation_types';
import testAction from 'helpers/vuex_action_helper';
import createFlash from '~/flash';
import Api from '~/api';
jest.mock('~/flash.js');
jest.mock('~/api.js');
describe('Actions Package list store', () => {
let state;
beforeEach(() => {
state = {
pagination: {
page: 1,
perPage: 10,
},
};
});
describe('requestPackagesList', () => {
beforeEach(() => {
Api.projectPackages = jest.fn().mockResolvedValue({ data: 'foo' });
});
it('should dispatch the correct actions', done => {
testAction(
actions.requestPackagesList,
null,
state,
[],
[
{ type: 'setLoading', payload: true },
{ type: 'receivePackagesListSuccess', payload: 'foo' },
{ type: 'setLoading', payload: false },
],
done,
);
});
it('should create flash on API error', done => {
Api.projectPackages = jest.fn().mockRejectedValue();
testAction(
actions.requestPackagesList,
null,
state,
[],
[{ type: 'setLoading', payload: true }, { type: 'setLoading', payload: false }],
() => {
expect(createFlash).toHaveBeenCalled();
done();
},
);
});
});
describe('receivePackagesListSuccess', () => {
it('should set received packages', done => {
testAction(
actions.receivePackagesListSuccess,
'foo',
state,
[{ type: types.SET_PACKAGE_LIST_SUCCESS, payload: 'foo' }],
[],
done,
);
});
});
describe('setProjectId', () => {
it('should commit setProjectId', done => {
testAction(
actions.setProjectId,
'1',
state,
[{ type: types.SET_PROJECT_ID, payload: '1' }],
[],
done,
);
});
});
describe('setUserCanDelete', () => {
it('should commit setUserCanDelete', done => {
testAction(
actions.setUserCanDelete,
true,
state,
[{ type: types.SET_USER_CAN_DELETE, payload: true }],
[],
done,
);
});
});
describe('setLoading', () => {
it('should commit set main loading', done => {
testAction(
actions.setLoading,
true,
state,
[{ type: types.SET_MAIN_LOADING, payload: true }],
[],
done,
);
});
});
describe('requestDeletePackage', () => {
it('should call deleteProjectPackage', done => {
Api.deleteProjectPackage = jest.fn().mockResolvedValue({ data: 'foo' });
Api.projectPackages = jest.fn().mockResolvedValue({ data: 'foo' });
testAction(
actions.requestDeletePackage,
{
projectId: 1,
packageId: 2,
},
null,
[],
[
{ type: 'setLoading', payload: true },
{ type: 'fetchPackages' },
{ type: 'setLoading', payload: false },
],
done,
);
});
it('should stop the loading and call create flash on api error', done => {
Api.deleteProjectPackage = jest.fn().mockRejectedValue();
testAction(
actions.requestDeletePackage,
{
projectId: 1,
packageId: 2,
},
null,
[],
[{ type: 'setLoading', payload: true }, { type: 'setLoading', payload: false }],
() => {
expect(createFlash).toHaveBeenCalled();
done();
},
);
});
});
});
import * as commonUtils from '~/lib/utils/common_utils';
import mutations from 'ee/packages/list/stores/mutations';
import * as types from 'ee/packages/list/stores/mutation_types';
import createState from 'ee/packages/list/stores/state';
import { npmPackage, mavenPackage } from '../../mock_data';
describe('Mutations Registry Store', () => {
let mockState;
beforeEach(() => {
mockState = createState();
});
describe('SET_PROJECT_ID', () => {
it('should set the project id', () => {
const expectedState = { ...mockState, projectId: 'foo' };
mutations[types.SET_PROJECT_ID](mockState, 'foo');
expect(mockState.projectId).toEqual(expectedState.projectId);
});
});
describe('SET_USER_CAN_DELETE', () => {
it('should set the userCanDelete', () => {
const expectedState = { ...mockState, userCanDelete: true };
mutations[types.SET_USER_CAN_DELETE](mockState, true);
expect(mockState.userCanDelete).toEqual(expectedState.userCanDelete);
});
});
describe('SET_PACKAGE_LIST', () => {
it('should set a packages list', () => {
const payload = [npmPackage, mavenPackage];
const expectedState = { ...mockState, packages: payload };
mutations[types.SET_PACKAGE_LIST](mockState, payload);
expect(mockState.packages).toEqual(expectedState.packages);
});
});
describe('SET_MAIN_LOADING', () => {
it('should set main loading', () => {
mutations[types.SET_MAIN_LOADING](mockState, true);
expect(mockState.isLoading).toEqual(true);
});
});
describe('SET_PAGINATION', () => {
const mockPagination = { perPage: 10, page: 1 };
beforeEach(() => {
commonUtils.normalizeHeaders = jest.fn().mockReturnValue('baz');
commonUtils.parseIntPagination = jest.fn().mockReturnValue(mockPagination);
});
it('should set a parsed pagination', () => {
mutations[types.SET_PAGINATION](mockState, { headers: 'foo' });
expect(commonUtils.normalizeHeaders).toHaveBeenCalledWith('foo');
expect(commonUtils.parseIntPagination).toHaveBeenCalledWith('baz');
expect(mockState.pagination).toEqual(mockPagination);
});
});
});
......@@ -15848,6 +15848,9 @@ msgstr ""
msgid "Something went wrong while closing the %{issuable}. Please try again later"
msgstr ""
msgid "Something went wrong while deleting the package."
msgstr ""
msgid "Something went wrong while deleting the source branch. Please try again."
msgstr ""
......@@ -15878,6 +15881,12 @@ msgstr ""
msgid "Something went wrong while fetching the environments for this merge request. Please try again."
msgstr ""
msgid "Something went wrong while fetching the package."
msgstr ""
msgid "Something went wrong while fetching the packages list."
msgstr ""
msgid "Something went wrong while fetching the projects."
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment