diff options
Diffstat (limited to 'spec/frontend/boards/stores/actions_spec.js')
-rw-r--r-- | spec/frontend/boards/stores/actions_spec.js | 307 |
1 files changed, 261 insertions, 46 deletions
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index 0cae6456887..e4209cd5e55 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -9,19 +9,26 @@ import { mockMilestone, labels, mockActiveIssue, + mockGroupProjects, } from '../mock_data'; import actions, { gqlClient } from '~/boards/stores/actions'; import * as types from '~/boards/stores/mutation_types'; import { inactiveId } from '~/boards/constants'; import issueMoveListMutation from '~/boards/graphql/issue_move_list.mutation.graphql'; import destroyBoardListMutation from '~/boards/graphql/board_list_destroy.mutation.graphql'; +import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql'; import updateAssignees from '~/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql'; -import { fullBoardId, formatListIssues, formatBoardLists } from '~/boards/boards_util'; +import { + fullBoardId, + formatListIssues, + formatBoardLists, + formatIssueInput, +} from '~/boards/boards_util'; import createFlash from '~/flash'; jest.mock('~/flash'); -const expectNotImplemented = action => { +const expectNotImplemented = (action) => { it('is not implemented', () => { expect(action).toThrow(new Error('Not implemented!')); }); @@ -29,7 +36,7 @@ const expectNotImplemented = action => { // We need this helper to make sure projectPath is including // subgroups when the movIssue action is called. -const getProjectPath = path => path.split('#')[0]; +const getProjectPath = (path) => path.split('#')[0]; beforeEach(() => { window.gon = { features: {} }; @@ -53,7 +60,7 @@ describe('setInitialBoardData', () => { }); describe('setFilters', () => { - it('should commit mutation SET_FILTERS', done => { + it('should commit mutation SET_FILTERS', (done) => { const state = { filters: {}, }; @@ -72,11 +79,11 @@ describe('setFilters', () => { }); describe('performSearch', () => { - it('should dispatch setFilters action', done => { + it('should dispatch setFilters action', (done) => { testAction(actions.performSearch, {}, {}, [], [{ type: 'setFilters', payload: {} }], done); }); - it('should dispatch setFilters, fetchLists and resetIssues action when graphqlBoardLists FF is on', done => { + it('should dispatch setFilters, fetchLists and resetIssues action when graphqlBoardLists FF is on', (done) => { window.gon = { features: { graphqlBoardLists: true } }; testAction( actions.performSearch, @@ -90,7 +97,7 @@ describe('performSearch', () => { }); describe('setActiveId', () => { - it('should commit mutation SET_ACTIVE_ID', done => { + it('should commit mutation SET_ACTIVE_ID', (done) => { const state = { activeId: inactiveId, }; @@ -108,10 +115,8 @@ describe('setActiveId', () => { describe('fetchLists', () => { const state = { - endpoints: { - fullPath: 'gitlab-org', - boardId: 1, - }, + fullPath: 'gitlab-org', + boardId: '1', filterParams: {}, boardType: 'group', }; @@ -131,7 +136,7 @@ describe('fetchLists', () => { const formattedLists = formatBoardLists(queryResponse.data.group.board.lists); - it('should commit mutations RECEIVE_BOARD_LISTS_SUCCESS on success', done => { + it('should commit mutations RECEIVE_BOARD_LISTS_SUCCESS on success', (done) => { jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse); testAction( @@ -149,7 +154,7 @@ describe('fetchLists', () => { ); }); - it('dispatch createList action when backlog list does not exist and is not hidden', done => { + it('dispatch createList action when backlog list does not exist and is not hidden', (done) => { queryResponse = { data: { group: { @@ -181,7 +186,7 @@ describe('fetchLists', () => { }); describe('createList', () => { - it('should dispatch addList action when creating backlog list', done => { + it('should dispatch addList action when creating backlog list', (done) => { const backlogList = { id: 'gid://gitlab/List/1', listType: 'backlog', @@ -201,7 +206,8 @@ describe('createList', () => { ); const state = { - endpoints: { fullPath: 'gitlab-org', boardId: '1' }, + fullPath: 'gitlab-org', + boardId: '1', boardType: 'group', disabled: false, boardLists: [{ type: 'closed' }], @@ -217,7 +223,7 @@ describe('createList', () => { ); }); - it('should commit CREATE_LIST_FAILURE mutation when API returns an error', done => { + it('should commit CREATE_LIST_FAILURE mutation when API returns an error', (done) => { jest.spyOn(gqlClient, 'mutate').mockReturnValue( Promise.resolve({ data: { @@ -230,7 +236,8 @@ describe('createList', () => { ); const state = { - endpoints: { fullPath: 'gitlab-org', boardId: '1' }, + fullPath: 'gitlab-org', + boardId: '1', boardType: 'group', disabled: false, boardLists: [{ type: 'closed' }], @@ -248,14 +255,15 @@ describe('createList', () => { }); describe('moveList', () => { - it('should commit MOVE_LIST mutation and dispatch updateList action', done => { + it('should commit MOVE_LIST mutation and dispatch updateList action', (done) => { const initialBoardListsState = { 'gid://gitlab/List/1': mockLists[0], 'gid://gitlab/List/2': mockLists[1], }; const state = { - endpoints: { fullPath: 'gitlab-org', boardId: '1' }, + fullPath: 'gitlab-org', + boardId: '1', boardType: 'group', disabled: false, boardLists: initialBoardListsState, @@ -297,7 +305,8 @@ describe('moveList', () => { }; const state = { - endpoints: { fullPath: 'gitlab-org', boardId: '1' }, + fullPath: 'gitlab-org', + boardId: '1', boardType: 'group', disabled: false, boardLists: initialBoardListsState, @@ -319,7 +328,7 @@ describe('moveList', () => { }); describe('updateList', () => { - it('should commit UPDATE_LIST_FAILURE mutation when API returns an error', done => { + it('should commit UPDATE_LIST_FAILURE mutation when API returns an error', (done) => { jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ data: { updateBoardList: { @@ -330,7 +339,8 @@ describe('updateList', () => { }); const state = { - endpoints: { fullPath: 'gitlab-org', boardId: '1' }, + fullPath: 'gitlab-org', + boardId: '1', boardType: 'group', disabled: false, boardLists: [{ type: 'closed' }], @@ -429,15 +439,13 @@ describe('fetchIssuesForList', () => { const listId = mockLists[0].id; const state = { - endpoints: { - fullPath: 'gitlab-org', - boardId: 1, - }, + fullPath: 'gitlab-org', + boardId: '1', filterParams: {}, boardType: 'group', }; - const mockIssuesNodes = mockIssues.map(issue => ({ node: issue })); + const mockIssuesNodes = mockIssues.map((issue) => ({ node: issue })); const pageInfo = { endCursor: '', @@ -470,7 +478,7 @@ describe('fetchIssuesForList', () => { [listId]: pageInfo, }; - it('should commit mutations REQUEST_ISSUES_FOR_LIST and RECEIVE_ISSUES_FOR_LIST_SUCCESS on success', done => { + it('should commit mutations REQUEST_ISSUES_FOR_LIST and RECEIVE_ISSUES_FOR_LIST_SUCCESS on success', (done) => { jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse); testAction( @@ -492,7 +500,7 @@ describe('fetchIssuesForList', () => { ); }); - it('should commit mutations REQUEST_ISSUES_FOR_LIST and RECEIVE_ISSUES_FOR_LIST_FAILURE on failure', done => { + it('should commit mutations REQUEST_ISSUES_FOR_LIST and RECEIVE_ISSUES_FOR_LIST_FAILURE on failure', (done) => { jest.spyOn(gqlClient, 'query').mockResolvedValue(Promise.reject()); testAction( @@ -525,12 +533,13 @@ describe('moveIssue', () => { }; const issues = { - '436': mockIssue, - '437': mockIssue2, + 436: mockIssue, + 437: mockIssue2, }; const state = { - endpoints: { fullPath: 'gitlab-org', boardId: '1' }, + fullPath: 'gitlab-org', + boardId: '1', boardType: 'group', disabled: false, boardLists: mockLists, @@ -538,7 +547,7 @@ describe('moveIssue', () => { issues, }; - it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_SUCCESS mutation when successful', done => { + it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_SUCCESS mutation when successful', (done) => { jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ data: { issueMoveList: { @@ -582,7 +591,7 @@ describe('moveIssue', () => { mutation: issueMoveListMutation, variables: { projectPath: getProjectPath(mockIssue.referencePath), - boardId: fullBoardId(state.endpoints.boardId), + boardId: fullBoardId(state.boardId), iid: mockIssue.iid, fromListId: 1, toListId: 2, @@ -613,7 +622,7 @@ describe('moveIssue', () => { expect(gqlClient.mutate).toHaveBeenCalledWith(mutationVariables); }); - it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_FAILURE mutation when unsuccessful', done => { + it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_FAILURE mutation when unsuccessful', (done) => { jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ data: { issueMoveList: { @@ -684,7 +693,7 @@ describe('setAssignees', () => { }); }); - it('calls the correct mutation with the correct values', done => { + it('calls the correct mutation with the correct values', (done) => { testAction( actions.setAssignees, {}, @@ -724,8 +733,27 @@ describe('setAssignees', () => { describe('createNewIssue', () => { const state = { boardType: 'group', - endpoints: { - fullPath: 'gitlab-org/gitlab', + fullPath: 'gitlab-org/gitlab', + boardConfig: { + labelIds: [], + assigneeId: null, + milestoneId: -1, + }, + }; + + const stateWithBoardConfig = { + boardConfig: { + labels: [ + { + id: 5, + title: 'Test', + color: '#ff0000', + description: 'testing;', + textColor: 'white', + }, + ], + assigneeId: 2, + milestoneId: 3, }, }; @@ -743,11 +771,59 @@ describe('createNewIssue', () => { expect(result).toEqual(mockIssue); }); - it('should commit CREATE_ISSUE_FAILURE mutation when API returns an error', done => { + it('should add board scope to the issue being created', async () => { jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ data: { createIssue: { - issue: {}, + issue: mockIssue, + errors: [], + }, + }, + }); + + await actions.createNewIssue({ state: stateWithBoardConfig }, mockIssue); + expect(gqlClient.mutate).toHaveBeenCalledWith({ + mutation: issueCreateMutation, + variables: { + input: formatIssueInput(mockIssue, stateWithBoardConfig.boardConfig), + }, + }); + }); + + it('should add board scope by merging attributes to the issue being created', async () => { + const issue = { + ...mockIssue, + assigneeIds: ['gid://gitlab/User/1'], + labelIds: ['gid://gitlab/GroupLabel/4'], + }; + + jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ + data: { + createIssue: { + issue, + errors: [], + }, + }, + }); + + const payload = formatIssueInput(issue, stateWithBoardConfig.boardConfig); + + await actions.createNewIssue({ state: stateWithBoardConfig }, issue); + expect(gqlClient.mutate).toHaveBeenCalledWith({ + mutation: issueCreateMutation, + variables: { + input: formatIssueInput(issue, stateWithBoardConfig.boardConfig), + }, + }); + expect(payload.labelIds).toEqual(['gid://gitlab/GroupLabel/4', 'gid://gitlab/GroupLabel/5']); + expect(payload.assigneeIds).toEqual(['gid://gitlab/User/1', 'gid://gitlab/User/2']); + }); + + it('should commit CREATE_ISSUE_FAILURE mutation when API returns an error', (done) => { + jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ + data: { + createIssue: { + issue: mockIssue, errors: [{ foo: 'bar' }], }, }, @@ -767,7 +843,7 @@ describe('createNewIssue', () => { }); describe('addListIssue', () => { - it('should commit ADD_ISSUE_TO_LIST mutation', done => { + it('should commit ADD_ISSUE_TO_LIST mutation', (done) => { const payload = { list: mockLists[0], issue: mockIssue, @@ -788,14 +864,14 @@ describe('addListIssue', () => { describe('setActiveIssueLabels', () => { const state = { issues: { [mockIssue.id]: mockIssue } }; const getters = { activeIssue: mockIssue }; - const testLabelIds = labels.map(label => label.id); + const testLabelIds = labels.map((label) => label.id); const input = { addLabelIds: testLabelIds, removeLabelIds: [], projectPath: 'h/b', }; - it('should assign labels on success', done => { + it('should assign labels on success', (done) => { jest .spyOn(gqlClient, 'mutate') .mockResolvedValue({ data: { updateIssue: { issue: { labels: { nodes: labels } } } } }); @@ -839,7 +915,7 @@ describe('setActiveIssueDueDate', () => { projectPath: 'h/b', }; - it('should commit due date after setting the issue', done => { + it('should commit due date after setting the issue', (done) => { jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ data: { updateIssue: { @@ -890,7 +966,7 @@ describe('setActiveIssueSubscribed', () => { projectPath: 'gitlab-org/gitlab-test', }; - it('should commit subscribed status', done => { + it('should commit subscribed status', (done) => { jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ data: { issueSetSubscription: { @@ -944,7 +1020,7 @@ describe('setActiveIssueMilestone', () => { projectPath: 'h/b', }; - it('should commit milestone after setting the issue', done => { + it('should commit milestone after setting the issue', (done) => { jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ data: { updateIssue: { @@ -986,6 +1062,145 @@ describe('setActiveIssueMilestone', () => { }); }); +describe('setActiveIssueTitle', () => { + const state = { issues: { [mockIssue.id]: mockIssue } }; + const getters = { activeIssue: mockIssue }; + const testTitle = 'Test Title'; + const input = { + title: testTitle, + projectPath: 'h/b', + }; + + it('should commit title after setting the issue', (done) => { + jest.spyOn(gqlClient, 'mutate').mockResolvedValue({ + data: { + updateIssue: { + issue: { + title: testTitle, + }, + errors: [], + }, + }, + }); + + const payload = { + issueId: getters.activeIssue.id, + prop: 'title', + value: testTitle, + }; + + testAction( + actions.setActiveIssueTitle, + input, + { ...state, ...getters }, + [ + { + type: types.UPDATE_ISSUE_BY_ID, + payload, + }, + ], + [], + done, + ); + }); + + it('throws error if fails', async () => { + jest + .spyOn(gqlClient, 'mutate') + .mockResolvedValue({ data: { updateIssue: { errors: ['failed mutation'] } } }); + + await expect(actions.setActiveIssueTitle({ getters }, input)).rejects.toThrow(Error); + }); +}); + +describe('fetchGroupProjects', () => { + const state = { + fullPath: 'gitlab-org', + }; + + const pageInfo = { + endCursor: '', + hasNextPage: false, + }; + + const queryResponse = { + data: { + group: { + projects: { + nodes: mockGroupProjects, + pageInfo: { + endCursor: '', + hasNextPage: false, + }, + }, + }, + }, + }; + + it('should commit mutations REQUEST_GROUP_PROJECTS and RECEIVE_GROUP_PROJECTS_SUCCESS on success', (done) => { + jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse); + + testAction( + actions.fetchGroupProjects, + {}, + state, + [ + { + type: types.REQUEST_GROUP_PROJECTS, + payload: false, + }, + { + type: types.RECEIVE_GROUP_PROJECTS_SUCCESS, + payload: { projects: mockGroupProjects, pageInfo, fetchNext: false }, + }, + ], + [], + done, + ); + }); + + it('should commit mutations REQUEST_GROUP_PROJECTS and RECEIVE_GROUP_PROJECTS_FAILURE on failure', (done) => { + jest.spyOn(gqlClient, 'query').mockRejectedValue(); + + testAction( + actions.fetchGroupProjects, + {}, + state, + [ + { + type: types.REQUEST_GROUP_PROJECTS, + payload: false, + }, + { + type: types.RECEIVE_GROUP_PROJECTS_FAILURE, + }, + ], + [], + done, + ); + }); +}); + +describe('setSelectedProject', () => { + it('should commit mutation SET_SELECTED_PROJECT', (done) => { + const project = mockGroupProjects[0]; + + testAction( + actions.setSelectedProject, + project, + {}, + [ + { + type: types.SET_SELECTED_PROJECT, + payload: project, + }, + ], + [], + done, + ); + }); +}); + describe('fetchBacklog', () => { expectNotImplemented(actions.fetchBacklog); }); |