diff options
author | Martin Wortschack <mwortschack@gitlab.com> | 2019-08-30 20:54:03 +0300 |
---|---|---|
committer | Martin Wortschack <mwortschack@gitlab.com> | 2019-08-30 22:22:17 +0300 |
commit | 85475de527deea2db0b92afdb31bac15732b7df4 (patch) | |
tree | 80baf072d9fcb6925d2f31b51a03c673255fe7a2 | |
parent | 5c933da3aa202b0777121b6cdcb0e9ebeb7eacfb (diff) |
Add specs for storetest-51123-2
- Add mock data
- Update error handling
- Update mock data
- Update getters
- Add specs for getters
9 files changed, 229 insertions, 30 deletions
diff --git a/app/assets/javascripts/admin/statistics_panel/components/app.vue b/app/assets/javascripts/admin/statistics_panel/components/app.vue index bc4d5e6e1ad..5ea8bc7c2ce 100644 --- a/app/assets/javascripts/admin/statistics_panel/components/app.vue +++ b/app/assets/javascripts/admin/statistics_panel/components/app.vue @@ -1,14 +1,20 @@ <script> import { mapState, mapGetters, mapActions } from 'vuex'; import { GlLoadingIcon } from '@gitlab/ui'; +import statisticsLabels from '../constants'; export default { components: { GlLoadingIcon, }, + data() { + return { + statisticsLabels, + }; + }, computed: { - ...mapState(['isLoading']), - ...mapGetters(['visibleStatistics']), + ...mapState(['isLoading', 'statistics']), + ...mapGetters(['getStatisticsData']), }, methods: { ...mapActions(['fetchStatistics']), @@ -25,7 +31,7 @@ export default { <h4>{{ __('Statistics') }}</h4> <gl-loading-icon v-if="isLoading" size="md" class="my-3" /> <template v-else> - <p v-for="statistic in visibleStatistics" :key="statistic.key"> + <p v-for="statistic in getStatisticsData(statisticsLabels)" :key="statistic.key"> {{ statistic.label }} <span class="light float-right">{{ statistic.value }}</span> </p> diff --git a/app/assets/javascripts/admin/statistics_panel/store/actions.js b/app/assets/javascripts/admin/statistics_panel/store/actions.js index 55eac687c2b..537025f524c 100644 --- a/app/assets/javascripts/admin/statistics_panel/store/actions.js +++ b/app/assets/javascripts/admin/statistics_panel/store/actions.js @@ -13,14 +13,14 @@ export const fetchStatistics = ({ dispatch }) => { .then(({ data }) => { dispatch('receiveStatisticsSuccess', convertObjectPropsToCamelCase(data, { deep: true })); }) - .catch(() => dispatch('receiveStatisticsError')); + .catch(error => dispatch('receiveStatisticsError', error)); }; export const receiveStatisticsSuccess = ({ commit }, statistics) => commit(types.RECEIVE_STATISTICS_SUCCESS, statistics); -export const receiveStatisticsError = ({ commit }) => { - commit(types.RECEIVE_STATISTICS_ERROR); +export const receiveStatisticsError = ({ commit }, error) => { + commit(types.RECEIVE_STATISTICS_ERROR, error); createFlash(s__('AdminDashboard|Error loading the statistics. Please try again')); }; diff --git a/app/assets/javascripts/admin/statistics_panel/store/getters.js b/app/assets/javascripts/admin/statistics_panel/store/getters.js index b666c9e7255..d8d06bc1d61 100644 --- a/app/assets/javascripts/admin/statistics_panel/store/getters.js +++ b/app/assets/javascripts/admin/statistics_panel/store/getters.js @@ -1,10 +1,19 @@ -import statisticsLabels from '../constants'; - -export const visibleStatistics = state => - Object.keys(statisticsLabels).map(key => { - const result = { key, label: statisticsLabels[key], value: state.statistics[key] }; - return result; - }); +/** + * Merges the statisticsLabels with the state's data + * and returns an array of the following form: + * [{ key: "forks", label: "Forks", value: 50 }] + */ +export const getStatisticsData = state => statisticsLabels => + state.statistics + ? Object.keys(statisticsLabels).map(key => { + const result = { + key, + label: statisticsLabels[key], + value: state.statistics[key] ? state.statistics[key] : null, + }; + return result; + }) + : null; // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/admin/statistics_panel/store/mutations.js b/app/assets/javascripts/admin/statistics_panel/store/mutations.js index bec83d5feda..ba691cf6948 100644 --- a/app/assets/javascripts/admin/statistics_panel/store/mutations.js +++ b/app/assets/javascripts/admin/statistics_panel/store/mutations.js @@ -7,12 +7,12 @@ export default { }, [types.RECEIVE_STATISTICS_SUCCESS](state, data) { state.isLoading = false; - state.hasError = false; + state.error = null; Vue.set(state, 'statistics', data); }, - [types.RECEIVE_STATISTICS_ERROR](state) { + [types.RECEIVE_STATISTICS_ERROR](state, error) { state.isLoading = false; - state.hasError = true; + state.error = error; }, }; diff --git a/app/assets/javascripts/admin/statistics_panel/store/state.js b/app/assets/javascripts/admin/statistics_panel/store/state.js index 274ccac8260..414248a25b3 100644 --- a/app/assets/javascripts/admin/statistics_panel/store/state.js +++ b/app/assets/javascripts/admin/statistics_panel/store/state.js @@ -1,18 +1,6 @@ export default () => ({ - hasError: false, + error: null, isLoading: false, - statistics: { - forks: null, - issues: null, - mergeRequests: null, - notes: null, - snippets: null, - sshKeys: null, - milestones: null, - users: null, - projects: null, - groups: null, - activeUsers: null, - }, + statistics: null, }); diff --git a/spec/frontend/admin/statistics_panel/mock_data.js b/spec/frontend/admin/statistics_panel/mock_data.js new file mode 100644 index 00000000000..5ff5d0ea8ae --- /dev/null +++ b/spec/frontend/admin/statistics_panel/mock_data.js @@ -0,0 +1,12 @@ +const mockStatistics = { + forks: 12, + issues: 180, + merge_requests: 31, + notes: 986, + snippets: 50, + ssh_keys: 10, + milestones: 40, + active_users: 50, +}; + +export default mockStatistics; diff --git a/spec/frontend/admin/statistics_panel/store/actions_spec.js b/spec/frontend/admin/statistics_panel/store/actions_spec.js new file mode 100644 index 00000000000..9b18b1aebda --- /dev/null +++ b/spec/frontend/admin/statistics_panel/store/actions_spec.js @@ -0,0 +1,115 @@ +import axios from 'axios'; +import MockAdapter from 'axios-mock-adapter'; +import testAction from 'helpers/vuex_action_helper'; +import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import * as actions from '~/admin/statistics_panel/store/actions'; +import * as types from '~/admin/statistics_panel/store/mutation_types'; +import getInitialState from '~/admin/statistics_panel/store/state'; +import mockStatistics from '../mock_data'; + +describe('Admin statistics panel actions', () => { + let mock; + let state; + + beforeEach(() => { + state = getInitialState(); + mock = new MockAdapter(axios); + }); + + describe('fetchStatistics', () => { + describe('success', () => { + beforeEach(() => { + mock.onGet(/api\/(.*)\/application\/statistics/).replyOnce(200, mockStatistics); + }); + + it('dispatches success with received data', done => + testAction( + actions.fetchStatistics, + null, + state, + [], + [ + { type: 'requestStatistics' }, + { + type: 'receiveStatisticsSuccess', + payload: expect.objectContaining( + convertObjectPropsToCamelCase(mockStatistics, { deep: true }), + ), + }, + ], + done, + )); + }); + + describe('error', () => { + beforeEach(() => { + mock.onGet(/api\/(.*)\/application\/statistics/).replyOnce(500); + }); + + it('dispatches error', done => + testAction( + actions.fetchStatistics, + null, + state, + [], + [ + { + type: 'requestStatistics', + }, + { + type: 'receiveStatisticsError', + payload: new Error('Request failed with status code 500'), + }, + ], + done, + )); + }); + }); + + describe('requestStatistic', () => { + it('should commit the request mutation', done => + testAction( + actions.requestStatistics, + null, + state, + [{ type: types.REQUEST_STATISTICS }], + [], + done, + )); + }); + + describe('receiveStatisticsSuccess', () => { + it('should commit received data', done => + testAction( + actions.receiveStatisticsSuccess, + mockStatistics, + state, + [ + { + type: types.RECEIVE_STATISTICS_SUCCESS, + payload: mockStatistics, + }, + ], + [], + done, + )); + }); + + describe('receiveStatisticsError', () => { + it('should commit error', done => { + testAction( + actions.receiveStatisticsError, + 500, + state, + [ + { + type: types.RECEIVE_STATISTICS_ERROR, + payload: 500, + }, + ], + [], + done, + ); + }); + }); +}); diff --git a/spec/frontend/admin/statistics_panel/store/getters_spec.js b/spec/frontend/admin/statistics_panel/store/getters_spec.js new file mode 100644 index 00000000000..bc60e633696 --- /dev/null +++ b/spec/frontend/admin/statistics_panel/store/getters_spec.js @@ -0,0 +1,28 @@ +import createState from '~/admin/statistics_panel/store/state'; +import * as getters from '~/admin/statistics_panel/store/getters'; + +describe('Admin statistics panel getters', () => { + let state; + + beforeEach(() => { + state = createState(); + }); + + describe('getStatisticsData', () => { + it('', () => { + state.statistics = { forks: 10, issues: 20 }; + + const statisticsLabels = { + forks: 'Forks', + issues: 'Issues', + }; + + const statisticsData = [ + { key: 'forks', label: 'Forks', value: 10 }, + { key: 'issues', label: 'Issues', value: 20 }, + ]; + + expect(getters.getStatisticsData(state)(statisticsLabels)).toEqual(statisticsData); + }); + }); +}); diff --git a/spec/frontend/admin/statistics_panel/store/mutations_spec.js b/spec/frontend/admin/statistics_panel/store/mutations_spec.js new file mode 100644 index 00000000000..23b78a1f3d9 --- /dev/null +++ b/spec/frontend/admin/statistics_panel/store/mutations_spec.js @@ -0,0 +1,41 @@ +import mutations from '~/admin/statistics_panel/store/mutations'; +import * as types from '~/admin/statistics_panel/store/mutation_types'; +import getInitialState from '~/admin/statistics_panel/store/state'; +import mockStatistics from '../mock_data'; + +describe('Admin statistics panel mutations', () => { + let state; + + beforeEach(() => { + state = getInitialState(); + }); + + describe(`${types.REQUEST_STATISTICS}`, () => { + it('sets isLoading to true', () => { + mutations[types.REQUEST_STATISTICS](state); + + expect(state.isLoading).toBe(true); + }); + }); + + describe(`${types.RECEIVE_STATISTICS_SUCCESS}`, () => { + it('updates the store with the with statistics', () => { + mutations[types.RECEIVE_STATISTICS_SUCCESS](state, mockStatistics); + + expect(state.isLoading).toBe(false); + expect(state.error).toBe(null); + expect(state.statistics).toEqual(mockStatistics); + }); + }); + + describe(`${types.RECEIVE_STATISTICS_ERROR}`, () => { + it('sets isError and clears data', () => { + const error = 500; + mutations[types.RECEIVE_STATISTICS_ERROR](state, error); + + expect(state.isLoading).toBe(false); + expect(state.error).toBe(error); + expect(state.statistics).toEqual(null); + }); + }); +}); |