Commit 01c4d41b authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '208470_02-package-file-store' into 'master'

Geo Package Files - Fetch Data Correctly

See merge request gitlab-org/gitlab!33522
parents ba2bce61 163cb2b3
...@@ -24,9 +24,9 @@ export default { ...@@ -24,9 +24,9 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(['isLoading', 'totalReplicableItems']), ...mapState(['isLoading', 'paginationData']),
hasReplicableItems() { hasReplicableItems() {
return this.totalReplicableItems > 0; return this.paginationData.total > 0;
}, },
}, },
created() { created() {
......
...@@ -10,10 +10,10 @@ export default { ...@@ -10,10 +10,10 @@ export default {
GeoReplicableItem, GeoReplicableItem,
}, },
computed: { computed: {
...mapState(['replicableItems', 'currentPage', 'pageSize', 'totalReplicableItems']), ...mapState(['replicableItems', 'paginationData']),
page: { page: {
get() { get() {
return this.currentPage; return this.paginationData.page;
}, },
set(newVal) { set(newVal) {
this.setPage(newVal); this.setPage(newVal);
...@@ -21,7 +21,7 @@ export default { ...@@ -21,7 +21,7 @@ export default {
}, },
}, },
hasReplicableItems() { hasReplicableItems() {
return this.totalReplicableItems > 0; return this.paginationData.total > 0;
}, },
}, },
methods: { methods: {
...@@ -45,8 +45,8 @@ export default { ...@@ -45,8 +45,8 @@ export default {
<gl-pagination <gl-pagination
v-if="hasReplicableItems" v-if="hasReplicableItems"
v-model="page" v-model="page"
:per-page="pageSize" :per-page="paginationData.perPage"
:total-items="totalReplicableItems" :total-items="paginationData.total"
align="center" align="center"
/> />
</section> </section>
......
...@@ -3,7 +3,7 @@ import { mapActions, mapState, mapGetters } from 'vuex'; ...@@ -3,7 +3,7 @@ import { mapActions, mapState, mapGetters } from 'vuex';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { GlSearchBoxByType, GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui'; import { GlSearchBoxByType, GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
import { DEFAULT_SEARCH_DELAY, ACTION_TYPES, FILTER_STATES } from '../store/constants'; import { DEFAULT_SEARCH_DELAY, ACTION_TYPES, FILTER_STATES } from '../constants';
export default { export default {
name: 'GeoReplicableFilterBar', name: 'GeoReplicableFilterBar',
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { GlLink, GlButton } from '@gitlab/ui'; import { GlLink, GlButton } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { ACTION_TYPES } from '../store/constants'; import { ACTION_TYPES } from '../constants';
import GeoReplicableStatus from './geo_replicable_status.vue'; import GeoReplicableStatus from './geo_replicable_status.vue';
import GeoReplicableTimeAgo from './geo_replicable_time_ago.vue'; import GeoReplicableTimeAgo from './geo_replicable_time_ago.vue';
......
<script> <script>
import { STATUS_ICON_NAMES, STATUS_ICON_CLASS, DEFAULT_STATUS } from '../store/constants'; import { STATUS_ICON_NAMES, STATUS_ICON_CLASS, DEFAULT_STATUS } from '../constants';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
export default { export default {
......
...@@ -43,3 +43,7 @@ export const ACTION_TYPES = { ...@@ -43,3 +43,7 @@ export const ACTION_TYPES = {
REVERIFY: 'reverify', REVERIFY: 'reverify',
FORCE_REDOWNLOAD: 'force_redownload', FORCE_REDOWNLOAD: 'force_redownload',
}; };
export const PREV = 'prev';
export const NEXT = 'next';
import Vue from 'vue'; import Vue from 'vue';
import Translate from '~/vue_shared/translate'; import Translate from '~/vue_shared/translate';
import { parseBoolean } from '~/lib/utils/common_utils';
import createStore from './store'; import createStore from './store';
import GeoReplicableApp from './components/app.vue'; import GeoReplicableApp from './components/app.vue';
...@@ -7,30 +8,21 @@ Vue.use(Translate); ...@@ -7,30 +8,21 @@ Vue.use(Translate);
export default () => { export default () => {
const el = document.getElementById('js-geo-replicable'); const el = document.getElementById('js-geo-replicable');
const { replicableType } = el.dataset; const { replicableType, geoTroubleshootingLink, geoReplicableEmptySvgPath } = el.dataset;
const useGraphQl = parseBoolean(el.dataset.graphql);
return new Vue({ return new Vue({
el, el,
store: createStore(replicableType), store: createStore({ replicableType, useGraphQl }),
components: { components: {
GeoReplicableApp, GeoReplicableApp,
}, },
data() {
const {
dataset: { geoTroubleshootingLink, geoReplicableEmptySvgPath },
} = this.$options.el;
return {
geoTroubleshootingLink,
geoReplicableEmptySvgPath,
};
},
render(createElement) { render(createElement) {
return createElement('geo-replicable-app', { return createElement('geo-replicable-app', {
props: { props: {
geoTroubleshootingLink: this.geoTroubleshootingLink, geoTroubleshootingLink,
geoReplicableEmptySvgPath: this.geoReplicableEmptySvgPath, geoReplicableEmptySvgPath,
}, },
}); });
}, },
......
...@@ -10,7 +10,7 @@ import { ...@@ -10,7 +10,7 @@ import {
import packageFilesQuery from '../graphql/package_files.query.graphql'; import packageFilesQuery from '../graphql/package_files.query.graphql';
import { gqClient } from '../utils'; import { gqClient } from '../utils';
import * as types from './mutation_types'; import * as types from './mutation_types';
import { FILTER_STATES } from './constants'; import { FILTER_STATES, PREV, NEXT } from '../constants';
// Fetch Replicable Items // Fetch Replicable Items
export const requestReplicableItems = ({ commit }) => commit(types.REQUEST_REPLICABLE_ITEMS); export const requestReplicableItems = ({ commit }) => commit(types.REQUEST_REPLICABLE_ITEMS);
...@@ -25,24 +25,35 @@ export const receiveReplicableItemsError = ({ state, commit }) => { ...@@ -25,24 +25,35 @@ export const receiveReplicableItemsError = ({ state, commit }) => {
commit(types.RECEIVE_REPLICABLE_ITEMS_ERROR); commit(types.RECEIVE_REPLICABLE_ITEMS_ERROR);
}; };
export const fetchReplicableItems = ({ state, dispatch }) => { export const fetchReplicableItems = ({ state, dispatch }, direction) => {
dispatch('requestReplicableItems'); dispatch('requestReplicableItems');
return state.useGraphQl return state.useGraphQl
? dispatch('fetchReplicableItemsGraphQl') ? dispatch('fetchReplicableItemsGraphQl', direction)
: dispatch('fetchReplicableItemsRestful'); : dispatch('fetchReplicableItemsRestful');
}; };
export const fetchReplicableItemsGraphQl = ({ dispatch }) => { export const fetchReplicableItemsGraphQl = ({ state, dispatch }, direction) => {
let before = '';
let after = '';
if (direction === PREV) {
before = state.paginationData.startCursor;
} else if (direction === NEXT) {
after = state.paginationData.endCursor;
}
gqClient gqClient
.query({ .query({
query: packageFilesQuery, query: packageFilesQuery,
variables: { before, after },
}) })
.then(res => { .then(res => {
const registries = res.data.geoNode.packageFileRegistries; const registries = res.data.geoNode.packageFileRegistries;
const data = registries.edges.map(e => e.node); const data = registries.edges.map(e => e.node);
const pagination = registries.pageInfo;
dispatch('receiveReplicableItemsSuccess', { data }); dispatch('receiveReplicableItemsSuccess', { data, pagination });
}) })
.catch(() => { .catch(() => {
dispatch('receiveReplicableItemsError'); dispatch('receiveReplicableItemsError');
...@@ -50,12 +61,12 @@ export const fetchReplicableItemsGraphQl = ({ dispatch }) => { ...@@ -50,12 +61,12 @@ export const fetchReplicableItemsGraphQl = ({ dispatch }) => {
}; };
export const fetchReplicableItemsRestful = ({ state, dispatch }) => { export const fetchReplicableItemsRestful = ({ state, dispatch }) => {
const { filterOptions, currentFilterIndex, currentPage, searchFilter } = state; const { filterOptions, currentFilterIndex, searchFilter, paginationData } = state;
const statusFilter = currentFilterIndex ? filterOptions[currentFilterIndex] : filterOptions[0]; const statusFilter = currentFilterIndex ? filterOptions[currentFilterIndex] : filterOptions[0];
const query = { const query = {
page: currentPage, page: paginationData.page,
search: searchFilter || null, search: searchFilter || null,
sync_status: statusFilter.value === FILTER_STATES.ALL.value ? null : statusFilter.value, sync_status: statusFilter.value === FILTER_STATES.ALL.value ? null : statusFilter.value,
}; };
...@@ -63,14 +74,10 @@ export const fetchReplicableItemsRestful = ({ state, dispatch }) => { ...@@ -63,14 +74,10 @@ export const fetchReplicableItemsRestful = ({ state, dispatch }) => {
Api.getGeoReplicableItems(state.replicableType, query) Api.getGeoReplicableItems(state.replicableType, query)
.then(res => { .then(res => {
const normalizedHeaders = normalizeHeaders(res.headers); const normalizedHeaders = normalizeHeaders(res.headers);
const paginationInformation = parseIntPagination(normalizedHeaders); const pagination = parseIntPagination(normalizedHeaders);
const camelCaseData = convertObjectPropsToCamelCase(res.data, { deep: true }); const data = convertObjectPropsToCamelCase(res.data, { deep: true });
dispatch('receiveReplicableItemsSuccess', { dispatch('receiveReplicableItemsSuccess', { data, pagination });
data: camelCaseData,
perPage: paginationInformation.perPage,
total: paginationInformation.total,
});
}) })
.catch(() => { .catch(() => {
dispatch('receiveReplicableItemsError'); dispatch('receiveReplicableItemsError');
......
...@@ -7,11 +7,11 @@ import createState from './state'; ...@@ -7,11 +7,11 @@ import createState from './state';
Vue.use(Vuex); Vue.use(Vuex);
const createStore = replicableType => const createStore = ({ replicableType, useGraphQl }) =>
new Vuex.Store({ new Vuex.Store({
actions, actions,
getters, getters,
mutations, mutations,
state: createState(replicableType), state: createState({ replicableType, useGraphQl }),
}); });
export default createStore; export default createStore;
...@@ -2,30 +2,28 @@ import * as types from './mutation_types'; ...@@ -2,30 +2,28 @@ import * as types from './mutation_types';
export default { export default {
[types.SET_FILTER](state, filterIndex) { [types.SET_FILTER](state, filterIndex) {
state.currentPage = 1; state.paginationData.page = 1;
state.currentFilterIndex = filterIndex; state.currentFilterIndex = filterIndex;
}, },
[types.SET_SEARCH](state, search) { [types.SET_SEARCH](state, search) {
state.currentPage = 1; state.paginationData.page = 1;
state.searchFilter = search; state.searchFilter = search;
}, },
[types.SET_PAGE](state, page) { [types.SET_PAGE](state, page) {
state.currentPage = page; state.paginationData.page = page;
}, },
[types.REQUEST_REPLICABLE_ITEMS](state) { [types.REQUEST_REPLICABLE_ITEMS](state) {
state.isLoading = true; state.isLoading = true;
}, },
[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, { data, perPage, total }) { [types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, { data, pagination }) {
state.isLoading = false; state.isLoading = false;
state.replicableItems = data; state.replicableItems = data;
state.pageSize = perPage; state.paginationData = pagination;
state.totalReplicableItems = total;
}, },
[types.RECEIVE_REPLICABLE_ITEMS_ERROR](state) { [types.RECEIVE_REPLICABLE_ITEMS_ERROR](state) {
state.isLoading = false; state.isLoading = false;
state.replicableItems = []; state.replicableItems = [];
state.pageSize = 0; state.paginationData = {};
state.totalReplicableItems = 0;
}, },
[types.REQUEST_INITIATE_ALL_REPLICABLE_SYNCS](state) { [types.REQUEST_INITIATE_ALL_REPLICABLE_SYNCS](state) {
state.isLoading = true; state.isLoading = true;
......
import { FILTER_STATES } from './constants'; import { FILTER_STATES } from '../constants';
const createState = replicableType => ({ const createState = ({ replicableType, useGraphQl }) => ({
replicableType, replicableType,
useGraphQl: false, useGraphQl,
isLoading: false, isLoading: false,
replicableItems: [], replicableItems: [],
totalReplicableItems: 0, paginationData: {
pageSize: 0, // GraphQL
currentPage: 1, hasNextPage: false,
hasPreviousPage: false,
startCursor: '',
endCursor: '',
// RESTful
total: 0,
perPage: 0,
page: 1,
},
searchFilter: '', searchFilter: '',
currentFilterIndex: 0, currentFilterIndex: 0,
......
...@@ -2,7 +2,7 @@ import Vuex from 'vuex'; ...@@ -2,7 +2,7 @@ import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import GeoReplicableApp from 'ee/geo_replicable/components/app.vue'; import GeoReplicableApp from 'ee/geo_replicable/components/app.vue';
import store from 'ee/geo_replicable/store'; import createStore from 'ee/geo_replicable/store';
import GeoReplicable from 'ee/geo_replicable/components/geo_replicable.vue'; import GeoReplicable from 'ee/geo_replicable/components/geo_replicable.vue';
import GeoReplicableEmptyState from 'ee/geo_replicable/components/geo_replicable_empty_state.vue'; import GeoReplicableEmptyState from 'ee/geo_replicable/components/geo_replicable_empty_state.vue';
import GeoReplicableFilterBar from 'ee/geo_replicable/components/geo_replicable_filter_bar.vue'; import GeoReplicableFilterBar from 'ee/geo_replicable/components/geo_replicable_filter_bar.vue';
...@@ -10,6 +10,7 @@ import { ...@@ -10,6 +10,7 @@ import {
MOCK_GEO_REPLICATION_SVG_PATH, MOCK_GEO_REPLICATION_SVG_PATH,
MOCK_GEO_TROUBLESHOOTING_LINK, MOCK_GEO_TROUBLESHOOTING_LINK,
MOCK_BASIC_FETCH_DATA_MAP, MOCK_BASIC_FETCH_DATA_MAP,
MOCK_REPLICABLE_TYPE,
} from '../mock_data'; } from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -31,7 +32,7 @@ describe('GeoReplicableApp', () => { ...@@ -31,7 +32,7 @@ describe('GeoReplicableApp', () => {
const createComponent = () => { const createComponent = () => {
wrapper = shallowMount(GeoReplicableApp, { wrapper = shallowMount(GeoReplicableApp, {
localVue, localVue,
store, store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
propsData, propsData,
methods: { methods: {
...actionSpies, ...actionSpies,
...@@ -90,7 +91,7 @@ describe('GeoReplicableApp', () => { ...@@ -90,7 +91,7 @@ describe('GeoReplicableApp', () => {
describe('with replicableItems', () => { describe('with replicableItems', () => {
beforeEach(() => { beforeEach(() => {
wrapper.vm.$store.state.replicableItems = MOCK_BASIC_FETCH_DATA_MAP; wrapper.vm.$store.state.replicableItems = MOCK_BASIC_FETCH_DATA_MAP;
wrapper.vm.$store.state.totalReplicableItems = wrapper.vm.$store.state.paginationData.total =
wrapper.vm.$store.state.replicableItems.length; wrapper.vm.$store.state.replicableItems.length;
}); });
...@@ -110,7 +111,7 @@ describe('GeoReplicableApp', () => { ...@@ -110,7 +111,7 @@ describe('GeoReplicableApp', () => {
describe('with no replicableItems', () => { describe('with no replicableItems', () => {
beforeEach(() => { beforeEach(() => {
wrapper.vm.$store.state.replicableItems = []; wrapper.vm.$store.state.replicableItems = [];
wrapper.vm.$store.state.totalReplicableItems = 0; wrapper.vm.$store.state.paginationData.total = 0;
}); });
it('hides replicable items', () => { it('hides replicable items', () => {
......
...@@ -23,7 +23,7 @@ describe('GeoReplicableEmptyState', () => { ...@@ -23,7 +23,7 @@ describe('GeoReplicableEmptyState', () => {
const createComponent = () => { const createComponent = () => {
wrapper = shallowMount(GeoReplicableEmptyState, { wrapper = shallowMount(GeoReplicableEmptyState, {
localVue, localVue,
store: createStore(MOCK_REPLICABLE_TYPE), store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
propsData, propsData,
}); });
}; };
......
...@@ -3,7 +3,7 @@ import { createLocalVue, mount } from '@vue/test-utils'; ...@@ -3,7 +3,7 @@ import { createLocalVue, mount } from '@vue/test-utils';
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlButton } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlButton } from '@gitlab/ui';
import GeoReplicableFilterBar from 'ee/geo_replicable/components/geo_replicable_filter_bar.vue'; import GeoReplicableFilterBar from 'ee/geo_replicable/components/geo_replicable_filter_bar.vue';
import createStore from 'ee/geo_replicable/store'; import createStore from 'ee/geo_replicable/store';
import { DEFAULT_SEARCH_DELAY } from 'ee/geo_replicable/store/constants'; import { DEFAULT_SEARCH_DELAY } from 'ee/geo_replicable/constants';
import { MOCK_REPLICABLE_TYPE } from '../mock_data'; import { MOCK_REPLICABLE_TYPE } from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -22,7 +22,7 @@ describe('GeoReplicableFilterBar', () => { ...@@ -22,7 +22,7 @@ describe('GeoReplicableFilterBar', () => {
const createComponent = () => { const createComponent = () => {
wrapper = mount(GeoReplicableFilterBar, { wrapper = mount(GeoReplicableFilterBar, {
localVue, localVue,
store: createStore(MOCK_REPLICABLE_TYPE), store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
methods: { methods: {
...actionSpies, ...actionSpies,
}, },
......
...@@ -2,9 +2,9 @@ import Vuex from 'vuex'; ...@@ -2,9 +2,9 @@ import Vuex from 'vuex';
import { createLocalVue, mount } from '@vue/test-utils'; import { createLocalVue, mount } from '@vue/test-utils';
import { GlLink, GlButton } from '@gitlab/ui'; import { GlLink, GlButton } from '@gitlab/ui';
import GeoReplicableItem from 'ee/geo_replicable/components/geo_replicable_item.vue'; import GeoReplicableItem from 'ee/geo_replicable/components/geo_replicable_item.vue';
import store from 'ee/geo_replicable/store'; import createStore from 'ee/geo_replicable/store';
import { ACTION_TYPES } from 'ee/geo_replicable/store/constants'; import { ACTION_TYPES } from 'ee/geo_replicable/constants';
import { MOCK_BASIC_FETCH_DATA_MAP } from '../mock_data'; import { MOCK_BASIC_FETCH_DATA_MAP, MOCK_REPLICABLE_TYPE } from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -29,7 +29,7 @@ describe('GeoReplicableItem', () => { ...@@ -29,7 +29,7 @@ describe('GeoReplicableItem', () => {
const createComponent = () => { const createComponent = () => {
wrapper = mount(GeoReplicableItem, { wrapper = mount(GeoReplicableItem, {
localVue, localVue,
store, store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
propsData, propsData,
methods: { methods: {
...actionSpies, ...actionSpies,
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { createLocalVue, mount } from '@vue/test-utils'; import { createLocalVue, mount } from '@vue/test-utils';
import { GlPagination } from '@gitlab/ui'; import { GlPagination } from '@gitlab/ui';
import store from 'ee/geo_replicable/store'; import createStore from 'ee/geo_replicable/store';
import GeoReplicable from 'ee/geo_replicable/components/geo_replicable.vue'; import GeoReplicable from 'ee/geo_replicable/components/geo_replicable.vue';
import GeoReplicableItem from 'ee/geo_replicable/components/geo_replicable_item.vue'; import GeoReplicableItem from 'ee/geo_replicable/components/geo_replicable_item.vue';
import { MOCK_BASIC_FETCH_DATA_MAP } from '../mock_data'; import { MOCK_BASIC_FETCH_DATA_MAP, MOCK_REPLICABLE_TYPE } from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -20,7 +20,7 @@ describe('GeoReplicable', () => { ...@@ -20,7 +20,7 @@ describe('GeoReplicable', () => {
const createComponent = () => { const createComponent = () => {
wrapper = mount(GeoReplicable, { wrapper = mount(GeoReplicable, {
localVue, localVue,
store, store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
methods: { methods: {
...actionSpies, ...actionSpies,
}, },
...@@ -45,10 +45,10 @@ describe('GeoReplicable', () => { ...@@ -45,10 +45,10 @@ describe('GeoReplicable', () => {
}); });
describe('GlPagination', () => { describe('GlPagination', () => {
describe('when pageSize >= totalReplicableItems', () => { describe('when perPage >= total', () => {
beforeEach(() => { beforeEach(() => {
wrapper.vm.$store.state.pageSize = 2; wrapper.vm.$store.state.paginationData.perPage = 2;
wrapper.vm.$store.state.totalReplicableItems = 1; wrapper.vm.$store.state.paginationData.total = 1;
}); });
it('is hidden', () => { it('is hidden', () => {
...@@ -56,10 +56,10 @@ describe('GeoReplicable', () => { ...@@ -56,10 +56,10 @@ describe('GeoReplicable', () => {
}); });
}); });
describe('when pageSize < totalReplicableItems', () => { describe('when perPage < total', () => {
beforeEach(() => { beforeEach(() => {
wrapper.vm.$store.state.pageSize = 1; wrapper.vm.$store.state.paginationData.perPage = 1;
wrapper.vm.$store.state.totalReplicableItems = 2; wrapper.vm.$store.state.paginationData.total = 2;
}); });
it('renders', () => { it('renders', () => {
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { createLocalVue, mount } from '@vue/test-utils'; import { createLocalVue, mount } from '@vue/test-utils';
import store from 'ee/geo_replicable/store'; import createStore from 'ee/geo_replicable/store';
import GeoReplicableStatus from 'ee/geo_replicable/components/geo_replicable_status.vue'; import GeoReplicableStatus from 'ee/geo_replicable/components/geo_replicable_status.vue';
import { import {
FILTER_STATES, FILTER_STATES,
STATUS_ICON_NAMES, STATUS_ICON_NAMES,
STATUS_ICON_CLASS, STATUS_ICON_CLASS,
DEFAULT_STATUS, DEFAULT_STATUS,
} from 'ee/geo_replicable/store/constants'; } from 'ee/geo_replicable/constants';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { MOCK_REPLICABLE_TYPE } from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -23,7 +24,7 @@ describe('GeoReplicableStatus', () => { ...@@ -23,7 +24,7 @@ describe('GeoReplicableStatus', () => {
const createComponent = () => { const createComponent = () => {
wrapper = mount(GeoReplicableStatus, { wrapper = mount(GeoReplicableStatus, {
localVue, localVue,
store, store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
propsData, propsData,
}); });
}; };
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { createLocalVue, mount } from '@vue/test-utils'; import { createLocalVue, mount } from '@vue/test-utils';
import store from 'ee/geo_replicable/store'; import createStore from 'ee/geo_replicable/store';
import GeoReplicableTimeAgo from 'ee/geo_replicable/components/geo_replicable_time_ago.vue'; import GeoReplicableTimeAgo from 'ee/geo_replicable/components/geo_replicable_time_ago.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { MOCK_REPLICABLE_TYPE } from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -19,7 +20,7 @@ describe('GeoReplicableTimeAgo', () => { ...@@ -19,7 +20,7 @@ describe('GeoReplicableTimeAgo', () => {
const createComponent = () => { const createComponent = () => {
wrapper = mount(GeoReplicableTimeAgo, { wrapper = mount(GeoReplicableTimeAgo, {
localVue, localVue,
store, store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
propsData, propsData,
}); });
}; };
......
...@@ -6,7 +6,7 @@ import Api from 'ee/api'; ...@@ -6,7 +6,7 @@ import Api from 'ee/api';
import * as actions from 'ee/geo_replicable/store/actions'; import * as actions from 'ee/geo_replicable/store/actions';
import * as types from 'ee/geo_replicable/store/mutation_types'; import * as types from 'ee/geo_replicable/store/mutation_types';
import createState from 'ee/geo_replicable/store/state'; import createState from 'ee/geo_replicable/store/state';
import { ACTION_TYPES } from 'ee/geo_replicable/store/constants'; import { ACTION_TYPES, PREV, NEXT } from 'ee/geo_replicable/constants';
import { gqClient } from 'ee/geo_replicable/utils'; import { gqClient } from 'ee/geo_replicable/utils';
import packageFilesQuery from 'ee/geo_replicable/graphql/package_files.query.graphql'; import packageFilesQuery from 'ee/geo_replicable/graphql/package_files.query.graphql';
import { import {
...@@ -16,6 +16,7 @@ import { ...@@ -16,6 +16,7 @@ import {
MOCK_REPLICABLE_TYPE, MOCK_REPLICABLE_TYPE,
MOCK_RESTFUL_PAGINATION_DATA, MOCK_RESTFUL_PAGINATION_DATA,
MOCK_BASIC_GRAPHQL_QUERY_RESPONSE, MOCK_BASIC_GRAPHQL_QUERY_RESPONSE,
MOCK_GRAPHQL_PAGINATION_DATA,
} from '../mock_data'; } from '../mock_data';
jest.mock('~/flash'); jest.mock('~/flash');
...@@ -25,7 +26,7 @@ describe('GeoReplicable Store Actions', () => { ...@@ -25,7 +26,7 @@ describe('GeoReplicable Store Actions', () => {
let state; let state;
beforeEach(() => { beforeEach(() => {
state = createState(MOCK_REPLICABLE_TYPE); state = createState({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false });
}); });
describe('requestReplicableItems', () => { describe('requestReplicableItems', () => {
...@@ -86,7 +87,10 @@ describe('GeoReplicable Store Actions', () => { ...@@ -86,7 +87,10 @@ describe('GeoReplicable Store Actions', () => {
null, null,
state, state,
[], [],
[{ type: 'requestReplicableItems' }, { type: 'fetchReplicableItemsGraphQl' }], [
{ type: 'requestReplicableItems' },
{ type: 'fetchReplicableItemsGraphQl', payload: null },
],
done, done,
); );
}); });
...@@ -112,36 +116,95 @@ describe('GeoReplicable Store Actions', () => { ...@@ -112,36 +116,95 @@ describe('GeoReplicable Store Actions', () => {
describe('fetchReplicableItemsGraphQl', () => { describe('fetchReplicableItemsGraphQl', () => {
describe('on success', () => { describe('on success', () => {
const registries = MOCK_BASIC_GRAPHQL_QUERY_RESPONSE.geoNode?.packageFileRegistries;
const data = registries.edges.map(e => e.node);
beforeEach(() => { beforeEach(() => {
jest.spyOn(gqClient, 'query').mockResolvedValue({ jest.spyOn(gqClient, 'query').mockResolvedValue({
data: MOCK_BASIC_GRAPHQL_QUERY_RESPONSE, data: MOCK_BASIC_GRAPHQL_QUERY_RESPONSE,
}); });
state.paginationData = MOCK_GRAPHQL_PAGINATION_DATA;
}); });
describe('with no direction set', () => {
const direction = null;
const registries = MOCK_BASIC_GRAPHQL_QUERY_RESPONSE.geoNode?.packageFileRegistries;
const data = registries.edges.map(e => e.node);
it('should call gqClient with no before/after variables', () => { it('should call gqClient with no before/after variables', () => {
testAction( testAction(
actions.fetchReplicableItemsGraphQl, actions.fetchReplicableItemsGraphQl,
null, direction,
state,
[],
[
{
type: 'receiveReplicableItemsSuccess',
payload: { data, pagination: registries.pageInfo },
},
],
() => {
expect(gqClient.query).toHaveBeenCalledWith({
query: packageFilesQuery,
variables: { before: '', after: '' },
});
},
);
});
});
describe('with direction set to "next"', () => {
const direction = NEXT;
const registries = MOCK_BASIC_GRAPHQL_QUERY_RESPONSE.geoNode?.packageFileRegistries;
const data = registries.edges.map(e => e.node);
it('should call gqClient with after variable but no before variable', () => {
testAction(
actions.fetchReplicableItemsGraphQl,
direction,
state, state,
[], [],
[ [
{ {
type: 'receiveReplicableItemsSuccess', type: 'receiveReplicableItemsSuccess',
payload: { data }, payload: { data, pagination: registries.pageInfo },
}, },
], ],
() => { () => {
expect(gqClient.query).toHaveBeenCalledWith({ expect(gqClient.query).toHaveBeenCalledWith({
query: packageFilesQuery, query: packageFilesQuery,
variables: { before: '', after: MOCK_GRAPHQL_PAGINATION_DATA.endCursor },
}); });
}, },
); );
}); });
}); });
describe('with direction set to "prev"', () => {
const direction = PREV;
const registries = MOCK_BASIC_GRAPHQL_QUERY_RESPONSE.geoNode?.packageFileRegistries;
const data = registries.edges.map(e => e.node);
it('should call gqClient with before variable but no after variable', () => {
testAction(
actions.fetchReplicableItemsGraphQl,
direction,
state,
[],
[
{
type: 'receiveReplicableItemsSuccess',
payload: { data, pagination: registries.pageInfo },
},
],
() => {
expect(gqClient.query).toHaveBeenCalledWith({
query: packageFilesQuery,
variables: { before: MOCK_GRAPHQL_PAGINATION_DATA.startCursor, after: '' },
});
},
);
});
});
});
describe('on error', () => { describe('on error', () => {
beforeEach(() => { beforeEach(() => {
jest.spyOn(gqClient, 'query').mockRejectedValue(); jest.spyOn(gqClient, 'query').mockRejectedValue();
...@@ -185,11 +248,7 @@ describe('GeoReplicable Store Actions', () => { ...@@ -185,11 +248,7 @@ describe('GeoReplicable Store Actions', () => {
[ [
{ {
type: 'receiveReplicableItemsSuccess', type: 'receiveReplicableItemsSuccess',
payload: { payload: { data: MOCK_BASIC_FETCH_DATA_MAP, pagination },
data: MOCK_BASIC_FETCH_DATA_MAP,
perPage: pagination.perPage,
total: pagination.total,
},
}, },
], ],
() => { () => {
...@@ -204,7 +263,7 @@ describe('GeoReplicable Store Actions', () => { ...@@ -204,7 +263,7 @@ describe('GeoReplicable Store Actions', () => {
describe('with params set', () => { describe('with params set', () => {
beforeEach(() => { beforeEach(() => {
state.currentPage = 3; state.paginationData.page = 3;
state.searchFilter = 'test search'; state.searchFilter = 'test search';
state.currentFilterIndex = 2; state.currentFilterIndex = 2;
}); });
...@@ -218,11 +277,7 @@ describe('GeoReplicable Store Actions', () => { ...@@ -218,11 +277,7 @@ describe('GeoReplicable Store Actions', () => {
[ [
{ {
type: 'receiveReplicableItemsSuccess', type: 'receiveReplicableItemsSuccess',
payload: { payload: { data: MOCK_BASIC_FETCH_DATA_MAP, pagination },
data: MOCK_BASIC_FETCH_DATA_MAP,
perPage: pagination.perPage,
total: pagination.total,
},
}, },
], ],
() => { () => {
...@@ -488,7 +543,7 @@ describe('GeoReplicable Store Actions', () => { ...@@ -488,7 +543,7 @@ describe('GeoReplicable Store Actions', () => {
describe('setPage', () => { describe('setPage', () => {
it('should commit mutation SET_PAGE', done => { it('should commit mutation SET_PAGE', done => {
state.currentPage = 1; state.paginationData.page = 1;
const testValue = 2; const testValue = 2;
......
import * as getters from 'ee/geo_replicable/store/getters'; import * as getters from 'ee/geo_replicable/store/getters';
import createState from 'ee/geo_replicable/store/state'; import createState from 'ee/geo_replicable/store/state';
import { MOCK_REPLICABLE_TYPE } from '../mock_data';
describe('GeoReplicable Store Getters', () => { describe('GeoReplicable Store Getters', () => {
let state; let state;
beforeEach(() => { beforeEach(() => {
state = createState(); state = createState({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false });
}); });
describe('replicableTypeName', () => { describe('replicableTypeName', () => {
......
import mutations from 'ee/geo_replicable/store/mutations'; import mutations from 'ee/geo_replicable/store/mutations';
import createState from 'ee/geo_replicable/store/state'; import createState from 'ee/geo_replicable/store/state';
import * as types from 'ee/geo_replicable/store/mutation_types'; import * as types from 'ee/geo_replicable/store/mutation_types';
import { MOCK_BASIC_FETCH_DATA_MAP } from '../mock_data'; import {
MOCK_BASIC_FETCH_DATA_MAP,
MOCK_REPLICABLE_TYPE,
MOCK_RESTFUL_PAGINATION_DATA,
MOCK_GRAPHQL_PAGINATION_DATA,
} from '../mock_data';
describe('GeoReplicable Store Mutations', () => { describe('GeoReplicable Store Mutations', () => {
let state; let state;
beforeEach(() => { beforeEach(() => {
state = createState(); state = createState({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false });
}); });
describe('SET_FILTER', () => { describe('SET_FILTER', () => {
...@@ -14,7 +19,7 @@ describe('GeoReplicable Store Mutations', () => { ...@@ -14,7 +19,7 @@ describe('GeoReplicable Store Mutations', () => {
beforeEach(() => { beforeEach(() => {
state.currentFilterIndex = 1; state.currentFilterIndex = 1;
state.currentPage = 2; state.paginationData.page = 2;
mutations[types.SET_FILTER](state, testValue); mutations[types.SET_FILTER](state, testValue);
}); });
...@@ -24,7 +29,7 @@ describe('GeoReplicable Store Mutations', () => { ...@@ -24,7 +29,7 @@ describe('GeoReplicable Store Mutations', () => {
}); });
it('resets the page to 1', () => { it('resets the page to 1', () => {
expect(state.currentPage).toEqual(1); expect(state.paginationData.page).toEqual(1);
}); });
}); });
...@@ -32,7 +37,7 @@ describe('GeoReplicable Store Mutations', () => { ...@@ -32,7 +37,7 @@ describe('GeoReplicable Store Mutations', () => {
const testValue = 'test search'; const testValue = 'test search';
beforeEach(() => { beforeEach(() => {
state.currentPage = 2; state.paginationData.page = 2;
mutations[types.SET_SEARCH](state, testValue); mutations[types.SET_SEARCH](state, testValue);
}); });
...@@ -42,16 +47,16 @@ describe('GeoReplicable Store Mutations', () => { ...@@ -42,16 +47,16 @@ describe('GeoReplicable Store Mutations', () => {
}); });
it('resets the page to 1', () => { it('resets the page to 1', () => {
expect(state.currentPage).toEqual(1); expect(state.paginationData.page).toEqual(1);
}); });
}); });
describe('SET_PAGE', () => { describe('SET_PAGE', () => {
it('sets the currentPage state key', () => { it('sets the page state key', () => {
const testValue = 2; const testValue = 2;
mutations[types.SET_PAGE](state, testValue); mutations[types.SET_PAGE](state, testValue);
expect(state.currentPage).toEqual(testValue); expect(state.paginationData.page).toEqual(testValue);
}); });
}); });
...@@ -64,27 +69,76 @@ describe('GeoReplicable Store Mutations', () => { ...@@ -64,27 +69,76 @@ describe('GeoReplicable Store Mutations', () => {
describe('RECEIVE_REPLICABLE_ITEMS_SUCCESS', () => { describe('RECEIVE_REPLICABLE_ITEMS_SUCCESS', () => {
let mockData = {}; let mockData = {};
let mockPaginationData = {};
describe('with RESTful pagination', () => {
beforeEach(() => { beforeEach(() => {
mockData = MOCK_BASIC_FETCH_DATA_MAP; mockData = MOCK_BASIC_FETCH_DATA_MAP;
mockPaginationData = MOCK_RESTFUL_PAGINATION_DATA;
}); });
it('sets isLoading to false', () => { it('sets isLoading to false', () => {
state.isLoading = true; state.isLoading = true;
mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, mockData); mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, {
data: mockData,
pagination: mockPaginationData,
});
expect(state.isLoading).toEqual(false);
});
it('sets replicableItems array with data', () => {
mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, {
data: mockData,
pagination: mockPaginationData,
});
expect(state.replicableItems).toBe(mockData);
});
it('sets perPage and total', () => {
mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, {
data: mockData,
pagination: mockPaginationData,
});
expect(state.paginationData.perPage).toEqual(mockPaginationData.perPage);
expect(state.paginationData.total).toEqual(mockPaginationData.total);
});
});
describe('with GraphQL pagination', () => {
beforeEach(() => {
mockData = MOCK_BASIC_FETCH_DATA_MAP;
mockPaginationData = MOCK_GRAPHQL_PAGINATION_DATA;
});
it('sets isLoading to false', () => {
state.isLoading = true;
mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, {
data: mockData,
pagination: mockPaginationData,
});
expect(state.isLoading).toEqual(false); expect(state.isLoading).toEqual(false);
}); });
it('sets replicableItems array with data', () => { it('sets replicableItems array with data', () => {
mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, mockData); mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, {
expect(state.replicableItems).toBe(mockData.data); data: mockData,
pagination: mockPaginationData,
});
expect(state.replicableItems).toBe(mockData);
}); });
it('sets pageSize and totalReplicableItems', () => { it('sets hasNextPage, hasPreviousPage, startCursor, and endCursor', () => {
mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, mockData); mutations[types.RECEIVE_REPLICABLE_ITEMS_SUCCESS](state, {
expect(state.pageSize).toEqual(mockData.perPage); data: mockData,
expect(state.totalReplicableItems).toEqual(mockData.total); pagination: mockPaginationData,
});
expect(state.paginationData.hasNextPage).toEqual(mockPaginationData.hasNextPage);
expect(state.paginationData.hasPreviousPage).toEqual(mockPaginationData.hasPreviousPage);
expect(state.paginationData.startCursor).toEqual(mockPaginationData.startCursor);
expect(state.paginationData.endCursor).toEqual(mockPaginationData.endCursor);
});
}); });
}); });
...@@ -110,12 +164,8 @@ describe('GeoReplicable Store Mutations', () => { ...@@ -110,12 +164,8 @@ describe('GeoReplicable Store Mutations', () => {
}); });
it('resets pagination data', () => { it('resets pagination data', () => {
state.pageSize = mockData.perPage;
state.totalReplicableItems = mockData.total;
mutations[types.RECEIVE_REPLICABLE_ITEMS_ERROR](state); mutations[types.RECEIVE_REPLICABLE_ITEMS_ERROR](state);
expect(state.pageSize).toEqual(0); expect(state.paginationData).toEqual({});
expect(state.totalReplicableItems).toEqual(0);
}); });
}); });
......
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