diff options
5 files changed, 64 insertions, 64 deletions
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js index b7090e09daf..59ead8a3dcf 100644 --- a/app/assets/javascripts/ide/stores/modules/file_templates/actions.js +++ b/app/assets/javascripts/ide/stores/modules/file_templates/actions.js @@ -23,22 +23,27 @@ export const receiveTemplateTypesError = ({ commit, dispatch }) => { export const receiveTemplateTypesSuccess = ({ commit }, templates) => commit(types.RECEIVE_TEMPLATE_TYPES_SUCCESS, templates); -export const fetchTemplateTypes = ({ dispatch, state, rootState }, page = 1) => { +export const fetchTemplateTypes = ({ dispatch, state, rootState }) => { if (!Object.keys(state.selectedTemplateType).length) return Promise.reject(); dispatch('requestTemplateTypes'); - return Api.projectTemplates(rootState.currentProjectId, state.selectedTemplateType.key, { page }) - .then(({ data, headers }) => { - const nextPage = parseInt(normalizeHeaders(headers)['X-NEXT-PAGE'], 10); + const fetchPages = (page = 1, prev = []) => + Api.projectTemplates(rootState.currentProjectId, state.selectedTemplateType.key, { + page, + per_page: 100, + }) + .then(({ data, headers }) => { + const nextPage = parseInt(normalizeHeaders(headers)['X-NEXT-PAGE'], 10); + const nextData = prev.concat(data); - dispatch('receiveTemplateTypesSuccess', data); + dispatch('receiveTemplateTypesSuccess', nextData); - if (nextPage) { - dispatch('fetchTemplateTypes', nextPage); - } - }) - .catch(() => dispatch('receiveTemplateTypesError')); + return nextPage ? fetchPages(nextPage, nextData) : nextData; + }) + .catch(() => dispatch('receiveTemplateTypesError')); + + return fetchPages(); }; export const setSelectedTemplateType = ({ commit, dispatch, rootGetters }, type) => { diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js b/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js index 25a65b047f1..7fc1c9134a7 100644 --- a/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js +++ b/app/assets/javascripts/ide/stores/modules/file_templates/mutations.js @@ -3,13 +3,14 @@ import * as types from './mutation_types'; export default { [types.REQUEST_TEMPLATE_TYPES](state) { state.isLoading = true; + state.templates = []; }, [types.RECEIVE_TEMPLATE_TYPES_ERROR](state) { state.isLoading = false; }, [types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, templates) { state.isLoading = false; - state.templates = state.templates.concat(templates); + state.templates = templates; }, [types.SET_SELECTED_TEMPLATE_TYPE](state, type) { state.selectedTemplateType = type; diff --git a/changelogs/unreleased/58252-web-ide-dropdown-duplicates.yml b/changelogs/unreleased/58252-web-ide-dropdown-duplicates.yml new file mode 100644 index 00000000000..48b03994586 --- /dev/null +++ b/changelogs/unreleased/58252-web-ide-dropdown-duplicates.yml @@ -0,0 +1,5 @@ +--- +title: Resolve Web IDE template dropdown showing duplicates +merge_request: 27237 +author: +type: fixed diff --git a/spec/frontend/ide/stores/modules/file_templates/mutations_spec.js b/spec/frontend/ide/stores/modules/file_templates/mutations_spec.js index 8e8b7f06ca2..6a1a826093c 100644 --- a/spec/frontend/ide/stores/modules/file_templates/mutations_spec.js +++ b/spec/frontend/ide/stores/modules/file_templates/mutations_spec.js @@ -2,6 +2,9 @@ import createState from '~/ide/stores/modules/file_templates/state'; import * as types from '~/ide/stores/modules/file_templates/mutation_types'; import mutations from '~/ide/stores/modules/file_templates/mutations'; +const mockFileTemplates = [['MIT'], ['CC']]; +const mockTemplateType = 'test'; + describe('IDE file templates mutations', () => { let state; @@ -10,11 +13,21 @@ describe('IDE file templates mutations', () => { }); describe(`${types.REQUEST_TEMPLATE_TYPES}`, () => { - it('sets isLoading', () => { + it('sets loading to true', () => { + state.isLoading = false; + mutations[types.REQUEST_TEMPLATE_TYPES](state); expect(state.isLoading).toBe(true); }); + + it('sets templates to an empty array', () => { + state.templates = mockFileTemplates; + + mutations[types.REQUEST_TEMPLATE_TYPES](state); + + expect(state.templates).toEqual([]); + }); }); describe(`${types.RECEIVE_TEMPLATE_TYPES_ERROR}`, () => { @@ -31,29 +44,33 @@ describe('IDE file templates mutations', () => { it('sets isLoading to false', () => { state.isLoading = true; - mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, []); + mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, mockFileTemplates); expect(state.isLoading).toBe(false); }); - it('sets templates', () => { - mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, ['test']); + it('sets templates to payload', () => { + state.templates = ['test']; + + mutations[types.RECEIVE_TEMPLATE_TYPES_SUCCESS](state, mockFileTemplates); - expect(state.templates).toEqual(['test']); + expect(state.templates).toEqual(mockFileTemplates); }); }); describe(`${types.SET_SELECTED_TEMPLATE_TYPE}`, () => { - it('sets selectedTemplateType', () => { - mutations[types.SET_SELECTED_TEMPLATE_TYPE](state, 'type'); + it('sets templates type to selected type', () => { + state.selectedTemplateType = ''; - expect(state.selectedTemplateType).toBe('type'); + mutations[types.SET_SELECTED_TEMPLATE_TYPE](state, mockTemplateType); + + expect(state.selectedTemplateType).toBe(mockTemplateType); }); - it('clears templates', () => { - state.templates = ['test']; + it('sets templates to empty array', () => { + state.templates = mockFileTemplates; - mutations[types.SET_SELECTED_TEMPLATE_TYPE](state, 'type'); + mutations[types.SET_SELECTED_TEMPLATE_TYPE](state, mockTemplateType); expect(state.templates).toEqual([]); }); @@ -61,6 +78,8 @@ describe('IDE file templates mutations', () => { describe(`${types.SET_UPDATE_SUCCESS}`, () => { it('sets updateSuccess', () => { + state.updateSuccess = false; + mutations[types.SET_UPDATE_SUCCESS](state, true); expect(state.updateSuccess).toBe(true); diff --git a/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js b/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js index 734233100ab..548962c7a92 100644 --- a/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js +++ b/spec/javascripts/ide/stores/modules/file_templates/actions_spec.js @@ -69,18 +69,16 @@ describe('IDE file templates actions', () => { describe('fetchTemplateTypes', () => { describe('success', () => { - let nextPage; + const pages = [[{ name: 'MIT' }], [{ name: 'Apache' }], [{ name: 'CC' }]]; beforeEach(() => { - mock.onGet(/api\/(.*)\/templates\/licenses/).replyOnce(() => [ - 200, - [ - { - name: 'MIT', - }, - ], - { 'X-NEXT-PAGE': nextPage }, - ]); + mock.onGet(/api\/(.*)\/templates\/licenses/).reply(({ params }) => { + const pageNum = params.page; + const page = pages[pageNum - 1]; + const hasNextPage = pageNum < pages.length; + + return [200, page, hasNextPage ? { 'X-NEXT-PAGE': pageNum + 1 } : {}]; + }); }); it('rejects if selectedTemplateType is empty', done => { @@ -112,43 +110,15 @@ describe('IDE file templates actions', () => { }, { type: 'receiveTemplateTypesSuccess', - payload: [ - { - name: 'MIT', - }, - ], - }, - ], - done, - ); - }); - - it('dispatches actions for next page', done => { - nextPage = '2'; - state.selectedTemplateType = { - key: 'licenses', - }; - - testAction( - actions.fetchTemplateTypes, - null, - state, - [], - [ - { - type: 'requestTemplateTypes', + payload: pages[0], }, { type: 'receiveTemplateTypesSuccess', - payload: [ - { - name: 'MIT', - }, - ], + payload: pages[0].concat(pages[1]), }, { - type: 'fetchTemplateTypes', - payload: 2, + type: 'receiveTemplateTypesSuccess', + payload: pages[0].concat(pages[1]).concat(pages[2]), }, ], done, |