Commit d15cc293 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch...

Merge branch '325778-moving-issue-to-board-list-of-different-type-should-not-remove-it-from-previous-list' into 'master'

Clone issue card on move when necessary [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!58644
parents 1d76f120 96b703f5
import { sortBy } from 'lodash';
import { sortBy, cloneDeep } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { ListType, NOT_FILTER } from './constants';
......@@ -113,6 +113,37 @@ export function formatIssueInput(issueInput, boardConfig) {
};
}
export function shouldCloneCard(fromListType, toListType) {
const involvesClosed = fromListType === ListType.closed || toListType === ListType.closed;
const involvesBacklog = fromListType === ListType.backlog || toListType === ListType.backlog;
if (involvesClosed || involvesBacklog) {
return false;
}
if (fromListType !== toListType) {
return true;
}
return false;
}
export function getMoveData(state, params) {
const { boardItems, boardItemsByListId, boardLists } = state;
const { itemId, fromListId, toListId } = params;
const fromListType = boardLists[fromListId].listType;
const toListType = boardLists[toListId].listType;
return {
reordering: fromListId === toListId,
shouldClone: shouldCloneCard(fromListType, toListType),
itemNotInToList: !boardItemsByListId[toListId].includes(itemId),
originalIssue: cloneDeep(boardItems[itemId]),
originalIndex: boardItemsByListId[fromListId].indexOf(itemId),
...params,
};
}
export function moveItemListHelper(item, fromList, toList) {
const updatedItem = item;
if (
......
......@@ -190,7 +190,7 @@ export default {
}
this.moveItem({
itemId,
itemId: Number(itemId),
itemIid,
itemPath,
fromListId: from.dataset.listId,
......
......@@ -2,6 +2,7 @@ import * as Sentry from '@sentry/browser';
import { pick } from 'lodash';
import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql';
import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
import {
BoardType,
ListType,
......@@ -23,13 +24,14 @@ import {
formatIssueInput,
updateListPosition,
transformNotFilters,
moveItemListHelper,
getMoveData,
} from '../boards_util';
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql';
import updateBoardListMutation from '../graphql/board_list_update.mutation.graphql';
import groupProjectsQuery from '../graphql/group_projects.query.graphql';
import issueCreateMutation from '../graphql/issue_create.mutation.graphql';
import issueMoveListMutation from '../graphql/issue_move_list.mutation.graphql';
import issueSetDueDateMutation from '../graphql/issue_set_due_date.mutation.graphql';
import issueSetLabelsMutation from '../graphql/issue_set_labels.mutation.graphql';
import issueSetMilestoneMutation from '../graphql/issue_set_milestone.mutation.graphql';
......@@ -333,42 +335,134 @@ export default {
dispatch('moveIssue', payload);
},
moveIssue: (
{ state, commit },
{ itemId, itemIid, itemPath, fromListId, toListId, moveBeforeId, moveAfterId },
moveIssue: ({ dispatch, state }, params) => {
const moveData = getMoveData(state, params);
dispatch('moveIssueCard', moveData);
dispatch('updateMovedIssue', moveData);
dispatch('updateIssueOrder', { moveData });
},
moveIssueCard: ({ commit }, moveData) => {
const {
reordering,
shouldClone,
itemNotInToList,
originalIndex,
itemId,
fromListId,
toListId,
moveBeforeId,
moveAfterId,
} = moveData;
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
if (reordering) {
commit(types.ADD_BOARD_ITEM_TO_LIST, {
itemId,
listId: toListId,
moveBeforeId,
moveAfterId,
});
return;
}
if (itemNotInToList) {
commit(types.ADD_BOARD_ITEM_TO_LIST, {
itemId,
listId: toListId,
moveBeforeId,
moveAfterId,
});
}
if (shouldClone) {
commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
}
},
updateMovedIssue: (
{ commit, state: { boardItems, boardLists } },
{ itemId, fromListId, toListId },
) => {
const originalIssue = state.boardItems[itemId];
const fromList = state.boardItemsByListId[fromListId];
const originalIndex = fromList.indexOf(Number(itemId));
commit(types.MOVE_ISSUE, { originalIssue, fromListId, toListId, moveBeforeId, moveAfterId });
const updatedIssue = moveItemListHelper(
boardItems[itemId],
boardLists[fromListId],
boardLists[toListId],
);
const { boardId } = state;
const [fullProjectPath] = itemPath.split(/[#]/);
commit(types.UPDATE_BOARD_ITEM, updatedIssue);
},
gqlClient
.mutate({
undoMoveIssueCard: ({ commit }, moveData) => {
const {
reordering,
shouldClone,
itemNotInToList,
itemId,
fromListId,
toListId,
originalIssue,
originalIndex,
} = moveData;
commit(types.UPDATE_BOARD_ITEM, originalIssue);
if (reordering) {
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
return;
}
if (shouldClone) {
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
}
if (itemNotInToList) {
commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: toListId });
}
commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
},
updateIssueOrder: async ({ commit, dispatch, state }, { moveData, mutationVariables = {} }) => {
try {
const { itemId, fromListId, toListId, moveBeforeId, moveAfterId } = moveData;
const {
boardId,
boardItems: {
[itemId]: { iid, referencePath },
},
} = state;
const { data } = await gqlClient.mutate({
mutation: issueMoveListMutation,
variables: {
projectPath: fullProjectPath,
iid,
projectPath: referencePath.split(/[#]/)[0],
boardId: fullBoardId(boardId),
iid: itemIid,
fromListId: getIdFromGraphQLId(fromListId),
toListId: getIdFromGraphQLId(toListId),
moveBeforeId,
moveAfterId,
// 'mutationVariables' allows EE code to pass in extra parameters.
...mutationVariables,
},
})
.then(({ data }) => {
if (data?.issueMoveList?.errors.length) {
throw new Error();
} else {
const issue = data.issueMoveList?.issue;
commit(types.MOVE_ISSUE_SUCCESS, { issue });
}
})
.catch(() =>
commit(types.MOVE_ISSUE_FAILURE, { originalIssue, fromListId, toListId, originalIndex }),
});
if (data?.issueMoveList?.errors.length || !data.issueMoveList) {
throw new Error('issueMoveList empty');
}
commit(types.MUTATE_ISSUE_SUCCESS, { issue: data.issueMoveList.issue });
} catch {
commit(
types.SET_ERROR,
s__('Boards|An error occurred while moving the issue. Please try again.'),
);
dispatch('undoMoveIssueCard', moveData);
}
},
setAssignees: ({ commit, getters }, assigneeUsernames) => {
......
......@@ -23,12 +23,10 @@ export const RECEIVE_ITEMS_FOR_LIST_SUCCESS = 'RECEIVE_ITEMS_FOR_LIST_SUCCESS';
export const REQUEST_ADD_ISSUE = 'REQUEST_ADD_ISSUE';
export const RECEIVE_ADD_ISSUE_SUCCESS = 'RECEIVE_ADD_ISSUE_SUCCESS';
export const RECEIVE_ADD_ISSUE_ERROR = 'RECEIVE_ADD_ISSUE_ERROR';
export const MOVE_ISSUE = 'MOVE_ISSUE';
export const MOVE_ISSUE_SUCCESS = 'MOVE_ISSUE_SUCCESS';
export const MOVE_ISSUE_FAILURE = 'MOVE_ISSUE_FAILURE';
export const UPDATE_BOARD_ITEM = 'UPDATE_BOARD_ITEM';
export const REMOVE_BOARD_ITEM = 'REMOVE_BOARD_ITEM';
export const REQUEST_UPDATE_ISSUE = 'REQUEST_UPDATE_ISSUE';
export const MUTATE_ISSUE_SUCCESS = 'MUTATE_ISSUE_SUCCESS';
export const RECEIVE_UPDATE_ISSUE_SUCCESS = 'RECEIVE_UPDATE_ISSUE_SUCCESS';
export const RECEIVE_UPDATE_ISSUE_ERROR = 'RECEIVE_UPDATE_ISSUE_ERROR';
export const ADD_BOARD_ITEM_TO_LIST = 'ADD_BOARD_ITEM_TO_LIST';
......
......@@ -2,7 +2,7 @@ import { pull, union } from 'lodash';
import Vue from 'vue';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { s__ } from '~/locale';
import { formatIssue, moveItemListHelper } from '../boards_util';
import { formatIssue } from '../boards_util';
import { issuableTypes } from '../constants';
import * as mutationTypes from './mutation_types';
......@@ -183,40 +183,11 @@ export default {
notImplemented();
},
[mutationTypes.MOVE_ISSUE]: (
state,
{ originalIssue, fromListId, toListId, moveBeforeId, moveAfterId },
) => {
const fromList = state.boardLists[fromListId];
const toList = state.boardLists[toListId];
const issue = moveItemListHelper(originalIssue, fromList, toList);
Vue.set(state.boardItems, issue.id, issue);
removeItemFromList({ state, listId: fromListId, itemId: issue.id });
addItemToList({ state, listId: toListId, itemId: issue.id, moveBeforeId, moveAfterId });
},
[mutationTypes.MOVE_ISSUE_SUCCESS]: (state, { issue }) => {
[mutationTypes.MUTATE_ISSUE_SUCCESS]: (state, { issue }) => {
const issueId = getIdFromGraphQLId(issue.id);
Vue.set(state.boardItems, issueId, formatIssue({ ...issue, id: issueId }));
},
[mutationTypes.MOVE_ISSUE_FAILURE]: (
state,
{ originalIssue, fromListId, toListId, originalIndex },
) => {
state.error = s__('Boards|An error occurred while moving the issue. Please try again.');
Vue.set(state.boardItems, originalIssue.id, originalIssue);
removeItemFromList({ state, listId: toListId, itemId: originalIssue.id });
addItemToList({
state,
listId: fromListId,
itemId: originalIssue.id,
atIndex: originalIndex,
});
},
[mutationTypes.REQUEST_UPDATE_ISSUE]: () => {
notImplemented();
},
......
......@@ -147,7 +147,7 @@ export default {
}
this.moveIssue({
itemId,
itemId: Number(itemId),
itemIid,
itemPath,
fromListId: from.dataset.listId,
......
......@@ -5,6 +5,7 @@ import {
formatListsPageInfo,
fullBoardId,
transformNotFilters,
getMoveData,
} from '~/boards/boards_util';
import { BoardType } from '~/boards/constants';
import eventHub from '~/boards/eventhub';
......@@ -12,7 +13,6 @@ import listsIssuesQuery from '~/boards/graphql/lists_issues.query.graphql';
import actionsCE from '~/boards/stores/actions';
import boardsStore from '~/boards/stores/boards_store';
import * as typesCE from '~/boards/stores/mutation_types';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import createGqClient, { fetchPolicies } from '~/lib/graphql';
import axios from '~/lib/utils/axios_utils';
import {
......@@ -37,7 +37,6 @@ import epicsSwimlanesQuery from '../graphql/epics_swimlanes.query.graphql';
import groupBoardAssigneesQuery from '../graphql/group_board_assignees.query.graphql';
import groupBoardIterationsQuery from '../graphql/group_board_iterations.query.graphql';
import groupBoardMilestonesQuery from '../graphql/group_board_milestones.query.graphql';
import issueMoveListMutation from '../graphql/issue_move_list.mutation.graphql';
import issueSetEpicMutation from '../graphql/issue_set_epic.mutation.graphql';
import issueSetWeightMutation from '../graphql/issue_set_weight.mutation.graphql';
import listUpdateLimitMetricsMutation from '../graphql/list_update_limit_metrics.mutation.graphql';
......@@ -482,50 +481,35 @@ export default {
}
},
moveIssue: (
{ state, commit },
{ itemId, itemIid, itemPath, fromListId, toListId, moveBeforeId, moveAfterId, epicId },
) => {
const originalIssue = state.boardItems[itemId];
const fromList = state.boardItemsByListId[fromListId];
const originalIndex = fromList.indexOf(Number(itemId));
commit(types.MOVE_ISSUE, {
originalIssue,
fromListId,
toListId,
moveBeforeId,
moveAfterId,
epicId,
moveIssue: ({ dispatch, state }, params) => {
const { itemId, epicId } = params;
const moveData = getMoveData(state, params);
dispatch('moveIssueCard', moveData);
dispatch('updateMovedIssue', moveData);
dispatch('updateEpicForIssue', { itemId, epicId });
dispatch('updateIssueOrder', {
moveData,
mutationVariables: { epicId },
});
},
const { boardId } = state;
const [fullProjectPath] = itemPath.split(/[#]/);
updateEpicForIssue: ({ commit, state: { boardItems } }, { itemId, epicId }) => {
const issue = boardItems[itemId];
gqlClient
.mutate({
mutation: issueMoveListMutation,
variables: {
projectPath: fullProjectPath,
boardId: fullBoardId(boardId),
iid: itemIid,
fromListId: getIdFromGraphQLId(fromListId),
toListId: getIdFromGraphQLId(toListId),
moveBeforeId,
moveAfterId,
epicId,
},
})
.then(({ data }) => {
if (data?.issueMoveList?.errors.length) {
throw new Error();
} else {
const issue = data.issueMoveList?.issue;
commit(types.MOVE_ISSUE_SUCCESS, { issue });
}
})
.catch(() =>
commit(types.MOVE_ISSUE_FAILURE, { originalIssue, fromListId, toListId, originalIndex }),
);
if (epicId === null) {
commit(types.UPDATE_BOARD_ITEM_BY_ID, {
itemId: issue.id,
prop: 'epic',
value: null,
});
} else if (epicId !== undefined) {
commit(types.UPDATE_BOARD_ITEM_BY_ID, {
itemId: issue.id,
prop: 'epic',
value: { id: epicId },
});
}
},
moveEpic: ({ state, commit }, { itemId, fromListId, toListId, moveBeforeId, moveAfterId }) => {
......
......@@ -150,25 +150,6 @@ export default {
Vue.set(state, 'epics', []);
},
[mutationTypes.MOVE_ISSUE]: (
state,
{ originalIssue, fromListId, toListId, moveBeforeId, moveAfterId, epicId },
) => {
const fromList = state.boardLists[fromListId];
const toList = state.boardLists[toListId];
const issue = moveItemListHelper(originalIssue, fromList, toList);
if (epicId === null) {
Vue.set(state.boardItems, issue.id, { ...issue, epic: null });
} else if (epicId !== undefined) {
Vue.set(state.boardItems, issue.id, { ...issue, epic: { id: epicId } });
}
removeItemFromList({ state, listId: fromListId, itemId: issue.id });
addItemToList({ state, listId: toListId, itemId: issue.id, moveBeforeId, moveAfterId });
},
[mutationTypes.MOVE_EPIC]: (
state,
{ originalEpic, fromListId, toListId, moveBeforeId, moveAfterId },
......
---
title: Clone issue card on move when necessary in epic swimlanes
merge_request: 58644
author:
type: fixed
......@@ -9,6 +9,7 @@ import * as types from 'ee/boards/stores/mutation_types';
import mutations from 'ee/boards/stores/mutations';
import { TEST_HOST } from 'helpers/test_constants';
import testAction from 'helpers/vuex_action_helper';
import { mockMoveIssueParams, mockMoveData, mockMoveState } from 'jest/boards/mock_data';
import { formatBoardLists, formatListIssues } from '~/boards/boards_util';
import { issuableTypes } from '~/boards/constants';
import listsIssuesQuery from '~/boards/graphql/lists_issues.query.graphql';
......@@ -19,13 +20,10 @@ import {
labels,
mockLists,
mockIssue,
mockIssue2,
mockIssues,
mockEpic,
rawIssue,
mockMilestones,
mockAssignees,
mockEpics,
} from '../mock_data';
Vue.use(Vuex);
......@@ -903,204 +901,89 @@ describe.each`
});
describe('moveIssue', () => {
const epicId = 'gid://gitlab/Epic/1';
it('should dispatch a correct set of actions with epic id', () => {
const params = mockMoveIssueParams;
const listIssues = {
'gid://gitlab/List/1': [436, 437],
'gid://gitlab/List/2': [],
};
const issues = {
436: mockIssue,
437: mockIssue2,
};
const state = {
fullPath: 'gitlab-org',
boardId: 1,
boardType: 'group',
disabled: false,
boardLists: mockLists,
boardItemsByListId: listIssues,
boardItems: issues,
};
it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_SUCCESS mutation when successful', (done) => {
jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
data: {
issueMoveList: {
issue: rawIssue,
errors: [],
},
},
});
const moveData = {
...mockMoveData,
epicId: 'some-epic-id',
};
testAction(
actions.moveIssue,
{
itemId: '436',
itemIid: mockIssue.iid,
itemPath: mockIssue.referencePath,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
epicId,
testAction({
action: actions.moveIssue,
payload: {
...params,
epicId: 'some-epic-id',
},
state,
[
state: mockMoveState,
expectedActions: [
{ type: 'moveIssueCard', payload: moveData },
{ type: 'updateMovedIssue', payload: moveData },
{ type: 'updateEpicForIssue', payload: { itemId: params.itemId, epicId: 'some-epic-id' } },
{
type: types.MOVE_ISSUE,
type: 'updateIssueOrder',
payload: {
originalIssue: mockIssue,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
epicId,
moveData,
mutationVariables: {
epicId: 'some-epic-id',
},
},
},
{
type: types.MOVE_ISSUE_SUCCESS,
payload: { issue: rawIssue },
},
],
[],
done,
);
});
it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_FAILURE mutation when unsuccessful', (done) => {
jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
data: {
issueMoveList: {
issue: {},
errors: [{ foo: 'bar' }],
},
},
});
testAction(
actions.moveIssue,
{
itemId: '436',
itemIid: mockIssue.iid,
itemPath: mockIssue.referencePath,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
epicId,
},
state,
[
{
type: types.MOVE_ISSUE,
payload: {
originalIssue: mockIssue,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
epicId,
},
},
{
type: types.MOVE_ISSUE_FAILURE,
payload: {
originalIssue: mockIssue,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
originalIndex: 0,
},
},
],
[],
done,
);
});
});
describe('moveEpic', () => {
const listEpics = {
'gid://gitlab/List/1': [41, 40],
'gid://gitlab/List/2': [],
};
const epics = {
41: mockEpic,
40: mockEpics[1],
};
const state = {
fullPath: 'gitlab-org',
boardId: 1,
boardType: 'group',
disabled: false,
boardLists: mockLists,
boardItemsByListId: listEpics,
boardItems: epics,
issuableType: 'epic',
};
describe('updateEpicForIssue', () => {
let commonState;
it('should commit MOVE_EPIC mutation mutation when successful', async () => {
jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
data: {
epicMoveList: {
errors: [],
beforeEach(() => {
commonState = {
boardItems: {
itemId: {
id: 'issueId',
},
},
});
await testAction({
action: actions.moveEpic,
payload: {
itemId: '41',
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
},
state,
expectedMutations: [
{
type: types.MOVE_EPIC,
payload: {
originalEpic: mockEpic,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
},
},
],
});
};
});
it('should commit MOVE_EPIC mutation and MOVE_EPIC_FAILURE mutation when unsuccessful', async () => {
jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
data: {
epicMoveList: {
errors: [{ foo: 'bar' }],
it.each([
[
'with epic id',
{
payload: {
itemId: 'itemId',
epicId: 'epicId',
},
},
});
await testAction({
action: actions.moveEpic,
payload: {
itemId: '41',
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
},
state,
expectedMutations: [
{
type: types.MOVE_EPIC,
payload: {
originalEpic: mockEpic,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
expectedMutations: [
{
type: types.UPDATE_BOARD_ITEM_BY_ID,
payload: { itemId: 'issueId', prop: 'epic', value: { id: 'epicId' } },
},
],
},
],
[
'with null as epic id',
{
payload: {
itemId: 'itemId',
epicId: null,
},
{
type: types.MOVE_EPIC_FAILURE,
payload: {
originalEpic: mockEpic,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
originalIndex: 0,
expectedMutations: [
{
type: types.UPDATE_BOARD_ITEM_BY_ID,
payload: { itemId: 'issueId', prop: 'epic', value: null },
},
},
],
],
},
],
])(`commits UPDATE_BOARD_ITEM_BY_ID mutation %s`, (_, { payload, expectedMutations }) => {
testAction({
action: actions.updateEpicForIssue,
payload,
state: commonState,
expectedMutations,
});
});
});
......
import mutations from 'ee/boards/stores/mutations';
import { mockIssue, mockIssue2, mockEpics, mockEpic, mockLists } from '../mock_data';
import { mockEpics, mockEpic, mockLists } from '../mock_data';
const expectNotImplemented = (action) => {
it('is not implemented', () => {
......@@ -7,8 +7,6 @@ const expectNotImplemented = (action) => {
});
};
const epicId = mockEpic.id;
const initialBoardListsState = {
'gid://gitlab/List/1': mockLists[0],
'gid://gitlab/List/2': mockLists[1],
......@@ -222,64 +220,6 @@ describe('RESET_EPICS', () => {
});
});
describe('MOVE_ISSUE', () => {
beforeEach(() => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
'gid://gitlab/List/2': [],
};
const issues = {
436: mockIssue,
437: mockIssue2,
};
state = {
...state,
boardItemsByListId: listIssues,
boardItems: issues,
};
});
it('updates boardItemsByListId, moving issue between lists and updating epic id on issue', () => {
expect(state.boardItems['437'].epic.id).toEqual('gid://gitlab/Epic/40');
mutations.MOVE_ISSUE(state, {
originalIssue: mockIssue2,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
epicId,
});
const updatedListIssues = {
'gid://gitlab/List/1': [mockIssue.id],
'gid://gitlab/List/2': [mockIssue2.id],
};
expect(state.boardItemsByListId).toEqual(updatedListIssues);
expect(state.boardItems['437'].epic.id).toEqual(epicId);
});
it('removes epic id from issue when epicId is null', () => {
expect(state.boardItems['437'].epic.id).toEqual('gid://gitlab/Epic/40');
mutations.MOVE_ISSUE(state, {
originalIssue: mockIssue2,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
epicId: null,
});
const updatedListIssues = {
'gid://gitlab/List/1': [mockIssue.id],
'gid://gitlab/List/2': [mockIssue2.id],
};
expect(state.boardItemsByListId).toEqual(updatedListIssues);
expect(state.boardItems['437'].epic).toEqual(null);
});
});
describe('MOVE_EPIC', () => {
it('updates boardItemsByListId, moving epic between lists', () => {
const listIssues = {
......
......@@ -3,6 +3,7 @@
import { keyBy } from 'lodash';
import Vue from 'vue';
import '~/boards/models/list';
import { ListType } from '~/boards/constants';
import boardsStore from '~/boards/stores/boards_store';
export const boardObj = {
......@@ -488,3 +489,38 @@ export const mockBlockedIssue2 = {
blockedByCount: 4,
webUrl: 'http://gdk.test:3000/gitlab-org/my-project-1/-/issues/0',
};
export const mockMoveIssueParams = {
itemId: 1,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
moveBeforeId: undefined,
moveAfterId: undefined,
};
export const mockMoveState = {
boardLists: {
'gid://gitlab/List/1': {
listType: ListType.backlog,
},
'gid://gitlab/List/2': {
listType: ListType.closed,
},
},
boardItems: {
[mockMoveIssueParams.itemId]: { foo: 'bar' },
},
boardItemsByListId: {
[mockMoveIssueParams.fromListId]: [mockMoveIssueParams.itemId],
[mockMoveIssueParams.toListId]: [],
},
};
export const mockMoveData = {
reordering: false,
shouldClone: false,
itemNotInToList: true,
originalIndex: 0,
originalIssue: { foo: 'bar' },
...mockMoveIssueParams,
};
This diff is collapsed.
......@@ -394,41 +394,7 @@ describe('Board Store Mutations', () => {
expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_ERROR);
});
describe('MOVE_ISSUE', () => {
it('updates boardItemsByListId, moving issue between lists', () => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
'gid://gitlab/List/2': [],
};
const issues = {
1: mockIssue,
2: mockIssue2,
};
state = {
...state,
boardItemsByListId: listIssues,
boardLists: initialBoardListsState,
boardItems: issues,
};
mutations.MOVE_ISSUE(state, {
originalIssue: mockIssue2,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
});
const updatedListIssues = {
'gid://gitlab/List/1': [mockIssue.id],
'gid://gitlab/List/2': [mockIssue2.id],
};
expect(state.boardItemsByListId).toEqual(updatedListIssues);
});
});
describe('MOVE_ISSUE_SUCCESS', () => {
describe('MUTATE_ISSUE_SUCCESS', () => {
it('updates issue in issues state', () => {
const issues = {
436: { id: rawIssue.id },
......@@ -439,7 +405,7 @@ describe('Board Store Mutations', () => {
boardItems: issues,
};
mutations.MOVE_ISSUE_SUCCESS(state, {
mutations.MUTATE_ISSUE_SUCCESS(state, {
issue: rawIssue,
});
......@@ -447,36 +413,6 @@ describe('Board Store Mutations', () => {
});
});
describe('MOVE_ISSUE_FAILURE', () => {
it('updates boardItemsByListId, reverting moving issue between lists, and sets error message', () => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id],
'gid://gitlab/List/2': [mockIssue2.id],
};
state = {
...state,
boardItemsByListId: listIssues,
boardLists: initialBoardListsState,
};
mutations.MOVE_ISSUE_FAILURE(state, {
originalIssue: mockIssue2,
fromListId: 'gid://gitlab/List/1',
toListId: 'gid://gitlab/List/2',
originalIndex: 1,
});
const updatedListIssues = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
'gid://gitlab/List/2': [],
};
expect(state.boardItemsByListId).toEqual(updatedListIssues);
expect(state.error).toEqual('An error occurred while moving the issue. Please try again.');
});
});
describe('UPDATE_BOARD_ITEM', () => {
it('updates the given issue in state.boardItems', () => {
const updatedIssue = { id: 'some_gid', foo: 'bar' };
......
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