import AxiosMockAdapter from 'axios-mock-adapter'; import { TEST_HOST } from 'helpers/test_constants'; import axios from '~/lib/utils/axios_utils'; import boardsStore from '~/boards/stores/boards_store'; import eventHub from '~/boards/eventhub'; import { listObj, listObjDuplicate } from './mock_data'; import ListIssue from '~/boards/models/issue'; import List from '~/boards/models/list'; jest.mock('js-cookie'); const createTestIssue = () => ({ title: 'Testing', id: 1, iid: 1, confidential: false, labels: [], assignees: [], }); describe('boardsStore', () => { const dummyResponse = "without type checking this doesn't matter"; const boardId = 'dummy-board-id'; const endpoints = { boardsEndpoint: `${TEST_HOST}/boards`, listsEndpoint: `${TEST_HOST}/lists`, bulkUpdatePath: `${TEST_HOST}/bulk/update`, recentBoardsEndpoint: `${TEST_HOST}/recent/boards`, }; let axiosMock; beforeEach(() => { axiosMock = new AxiosMockAdapter(axios); boardsStore.setEndpoints({ ...endpoints, boardId, }); }); afterEach(() => { axiosMock.restore(); }); const setupDefaultResponses = () => { axiosMock .onGet(`${endpoints.listsEndpoint}/${listObj.id}/issues?id=${listObj.id}&page=1`) .reply(200, { issues: [createTestIssue()] }); axiosMock.onPost(endpoints.listsEndpoint).reply(200, listObj); axiosMock.onPut(); }; describe('all', () => { it('makes a request to fetch lists', () => { axiosMock.onGet(endpoints.listsEndpoint).replyOnce(200, dummyResponse); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.all()).resolves.toEqual(expectedResponse); }); it('fails for error response', () => { axiosMock.onGet(endpoints.listsEndpoint).replyOnce(500); return expect(boardsStore.all()).rejects.toThrow(); }); }); describe('createList', () => { const entityType = 'moorhen'; const entityId = 'quack'; const expectedRequest = expect.objectContaining({ data: JSON.stringify({ list: { [entityType]: entityId } }), }); let requestSpy; beforeEach(() => { requestSpy = jest.fn(); axiosMock.onPost(endpoints.listsEndpoint).replyOnce((config) => requestSpy(config)); }); it('makes a request to create a list', () => { requestSpy.mockReturnValue([200, dummyResponse]); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.createList(entityId, entityType)) .resolves.toEqual(expectedResponse) .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); it('fails for error response', () => { requestSpy.mockReturnValue([500]); return expect(boardsStore.createList(entityId, entityType)) .rejects.toThrow() .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); }); describe('updateList', () => { const id = 'David Webb'; const position = 'unknown'; const collapsed = false; const expectedRequest = expect.objectContaining({ data: JSON.stringify({ list: { position, collapsed } }), }); let requestSpy; beforeEach(() => { requestSpy = jest.fn(); axiosMock.onPut(`${endpoints.listsEndpoint}/${id}`).replyOnce((config) => requestSpy(config)); }); it('makes a request to update a list position', () => { requestSpy.mockReturnValue([200, dummyResponse]); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.updateList(id, position, collapsed)) .resolves.toEqual(expectedResponse) .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); it('fails for error response', () => { requestSpy.mockReturnValue([500]); return expect(boardsStore.updateList(id, position, collapsed)) .rejects.toThrow() .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); }); describe('destroyList', () => { const id = '-42'; let requestSpy; beforeEach(() => { requestSpy = jest.fn(); axiosMock .onDelete(`${endpoints.listsEndpoint}/${id}`) .replyOnce((config) => requestSpy(config)); }); it('makes a request to delete a list', () => { requestSpy.mockReturnValue([200, dummyResponse]); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.destroyList(id)) .resolves.toEqual(expectedResponse) .then(() => { expect(requestSpy).toHaveBeenCalled(); }); }); it('fails for error response', () => { requestSpy.mockReturnValue([500]); return expect(boardsStore.destroyList(id)) .rejects.toThrow() .then(() => { expect(requestSpy).toHaveBeenCalled(); }); }); }); describe('saveList', () => { let list; beforeEach(() => { list = new List(listObj); setupDefaultResponses(); }); it('makes a request to save a list', () => { const expectedResponse = expect.objectContaining({ issues: [createTestIssue()] }); const expectedListValue = { id: listObj.id, position: listObj.position, type: listObj.list_type, label: listObj.label, }; expect(list.id).toBe(listObj.id); expect(list.position).toBe(listObj.position); expect(list).toMatchObject(expectedListValue); return expect(boardsStore.saveList(list)).resolves.toEqual(expectedResponse); }); }); describe('getListIssues', () => { let list; beforeEach(() => { list = new List(listObj); setupDefaultResponses(); }); it('makes a request to get issues', () => { const expectedResponse = expect.objectContaining({ issues: [createTestIssue()] }); expect(list.issues).toEqual([]); return expect(boardsStore.getListIssues(list, true)).resolves.toEqual(expectedResponse); }); }); describe('getIssuesForList', () => { const id = 'TOO-MUCH'; const url = `${endpoints.listsEndpoint}/${id}/issues?id=${id}`; it('makes a request to fetch list issues', () => { axiosMock.onGet(url).replyOnce(200, dummyResponse); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.getIssuesForList(id)).resolves.toEqual(expectedResponse); }); it('makes a request to fetch list issues with filter', () => { const filter = { algal: 'scrubber' }; axiosMock.onGet(`${url}&algal=scrubber`).replyOnce(200, dummyResponse); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.getIssuesForList(id, filter)).resolves.toEqual(expectedResponse); }); it('fails for error response', () => { axiosMock.onGet(url).replyOnce(500); return expect(boardsStore.getIssuesForList(id)).rejects.toThrow(); }); }); describe('moveIssue', () => { const urlRoot = 'potato'; const id = 'over 9000'; const fromListId = 'left'; const toListId = 'right'; const moveBeforeId = 'up'; const moveAfterId = 'down'; const expectedRequest = expect.objectContaining({ data: JSON.stringify({ from_list_id: fromListId, to_list_id: toListId, move_before_id: moveBeforeId, move_after_id: moveAfterId, }), }); let requestSpy; beforeAll(() => { global.gon.relative_url_root = urlRoot; }); afterAll(() => { delete global.gon.relative_url_root; }); beforeEach(() => { requestSpy = jest.fn(); axiosMock .onPut(`${urlRoot}/-/boards/${boardId}/issues/${id}`) .replyOnce((config) => requestSpy(config)); }); it('makes a request to move an issue between lists', () => { requestSpy.mockReturnValue([200, dummyResponse]); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId)) .resolves.toEqual(expectedResponse) .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); it('fails for error response', () => { requestSpy.mockReturnValue([500]); return expect(boardsStore.moveIssue(id, fromListId, toListId, moveBeforeId, moveAfterId)) .rejects.toThrow() .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); }); describe('newIssue', () => { const id = 1; const issue = { some: 'issue data' }; const url = `${endpoints.listsEndpoint}/${id}/issues`; const expectedRequest = expect.objectContaining({ data: JSON.stringify({ issue, }), }); let requestSpy; beforeEach(() => { requestSpy = jest.fn(); axiosMock.onPost(url).replyOnce((config) => requestSpy(config)); }); it('makes a request to create a new issue', () => { requestSpy.mockReturnValue([200, dummyResponse]); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.newIssue(id, issue)) .resolves.toEqual(expectedResponse) .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); it('fails for error response', () => { requestSpy.mockReturnValue([500]); return expect(boardsStore.newIssue(id, issue)) .rejects.toThrow() .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); }); describe('getBacklog', () => { const urlRoot = 'deep'; const url = `${urlRoot}/-/boards/${boardId}/issues.json?not=relevant`; const requestParams = { not: 'relevant', }; beforeAll(() => { global.gon.relative_url_root = urlRoot; }); afterAll(() => { delete global.gon.relative_url_root; }); it('makes a request to fetch backlog', () => { axiosMock.onGet(url).replyOnce(200, dummyResponse); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.getBacklog(requestParams)).resolves.toEqual(expectedResponse); }); it('fails for error response', () => { axiosMock.onGet(url).replyOnce(500); return expect(boardsStore.getBacklog(requestParams)).rejects.toThrow(); }); }); describe('bulkUpdate', () => { const issueIds = [1, 2, 3]; const extraData = { moar: 'data' }; const expectedRequest = expect.objectContaining({ data: JSON.stringify({ update: { ...extraData, issuable_ids: '1,2,3', }, }), }); let requestSpy; beforeEach(() => { requestSpy = jest.fn(); axiosMock.onPost(endpoints.bulkUpdatePath).replyOnce((config) => requestSpy(config)); }); it('makes a request to create a list', () => { requestSpy.mockReturnValue([200, dummyResponse]); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.bulkUpdate(issueIds, extraData)) .resolves.toEqual(expectedResponse) .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); it('fails for error response', () => { requestSpy.mockReturnValue([500]); return expect(boardsStore.bulkUpdate(issueIds, extraData)) .rejects.toThrow() .then(() => { expect(requestSpy).toHaveBeenCalledWith(expectedRequest); }); }); }); describe('getIssueInfo', () => { const dummyEndpoint = `${TEST_HOST}/some/where`; it('makes a request to the given endpoint', () => { axiosMock.onGet(dummyEndpoint).replyOnce(200, dummyResponse); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.getIssueInfo(dummyEndpoint)).resolves.toEqual(expectedResponse); }); it('fails for error response', () => { axiosMock.onGet(dummyEndpoint).replyOnce(500); return expect(boardsStore.getIssueInfo(dummyEndpoint)).rejects.toThrow(); }); }); describe('toggleIssueSubscription', () => { const dummyEndpoint = `${TEST_HOST}/some/where`; it('makes a request to the given endpoint', () => { axiosMock.onPost(dummyEndpoint).replyOnce(200, dummyResponse); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).resolves.toEqual( expectedResponse, ); }); it('fails for error response', () => { axiosMock.onPost(dummyEndpoint).replyOnce(500); return expect(boardsStore.toggleIssueSubscription(dummyEndpoint)).rejects.toThrow(); }); }); describe('recentBoards', () => { const url = `${endpoints.recentBoardsEndpoint}.json`; it('makes a request to fetch all boards', () => { axiosMock.onGet(url).replyOnce(200, dummyResponse); const expectedResponse = expect.objectContaining({ data: dummyResponse }); return expect(boardsStore.recentBoards()).resolves.toEqual(expectedResponse); }); it('fails for error response', () => { axiosMock.onGet(url).replyOnce(500); return expect(boardsStore.recentBoards()).rejects.toThrow(); }); }); describe('when created', () => { beforeEach(() => { setupDefaultResponses(); jest.spyOn(boardsStore, 'moveIssue').mockReturnValue(Promise.resolve()); jest.spyOn(boardsStore, 'moveMultipleIssues').mockReturnValue(Promise.resolve()); boardsStore.create(); }); it('starts with a blank state', () => { expect(boardsStore.state.lists.length).toBe(0); }); describe('addList', () => { it('sorts by position', () => { boardsStore.addList({ position: 2 }); boardsStore.addList({ position: 1 }); expect(boardsStore.state.lists.map(({ position }) => position)).toEqual([1, 2]); }); }); describe('toggleFilter', () => { const dummyFilter = 'x=42'; let updateTokensSpy; beforeEach(() => { updateTokensSpy = jest.fn(); eventHub.$once('updateTokens', updateTokensSpy); // prevent using window.history jest.spyOn(boardsStore, 'updateFiltersUrl').mockReturnValue(); }); it('adds the filter if it is not present', () => { boardsStore.filter.path = 'something'; boardsStore.toggleFilter(dummyFilter); expect(boardsStore.filter.path).toEqual(`something&${dummyFilter}`); expect(updateTokensSpy).toHaveBeenCalled(); expect(boardsStore.updateFiltersUrl).toHaveBeenCalled(); }); it('removes the filter if it is present', () => { boardsStore.filter.path = `something&${dummyFilter}`; boardsStore.toggleFilter(dummyFilter); expect(boardsStore.filter.path).toEqual('something'); expect(updateTokensSpy).toHaveBeenCalled(); expect(boardsStore.updateFiltersUrl).toHaveBeenCalled(); }); }); describe('lists', () => { it('creates new list without persisting to DB', () => { expect(boardsStore.state.lists.length).toBe(0); boardsStore.addList(listObj); expect(boardsStore.state.lists.length).toBe(1); }); it('finds list by ID', () => { boardsStore.addList(listObj); const list = boardsStore.findList('id', listObj.id); expect(list.id).toBe(listObj.id); }); it('finds list by type', () => { boardsStore.addList(listObj); const list = boardsStore.findList('type', 'label'); expect(list).toBeDefined(); }); it('finds list by label ID', () => { boardsStore.addList(listObj); const list = boardsStore.findListByLabelId(listObj.label.id); expect(list.id).toBe(listObj.id); }); it('gets issue when new list added', () => { boardsStore.addList(listObj); const list = boardsStore.findList('id', listObj.id); expect(boardsStore.state.lists.length).toBe(1); return axios.waitForAll().then(() => { expect(list.issues.length).toBe(1); expect(list.issues[0].id).toBe(1); }); }); it('persists new list', () => { boardsStore.new({ title: 'Test', list_type: 'label', label: { id: 1, title: 'Testing', color: 'red', description: 'testing;', }, }); expect(boardsStore.state.lists.length).toBe(1); return axios.waitForAll().then(() => { const list = boardsStore.findList('id', listObj.id); expect(list).toEqual( expect.objectContaining({ id: listObj.id, position: 0, }), ); }); }); it('removes list from state', () => { boardsStore.addList(listObj); expect(boardsStore.state.lists.length).toBe(1); boardsStore.removeList(listObj.id); expect(boardsStore.state.lists.length).toBe(0); }); it('moves the position of lists', () => { const listOne = boardsStore.addList(listObj); boardsStore.addList(listObjDuplicate); expect(boardsStore.state.lists.length).toBe(2); boardsStore.moveList(listOne, [listObjDuplicate.id, listObj.id]); expect(listOne.position).toBe(1); }); it('moves an issue from one list to another', () => { const listOne = boardsStore.addList(listObj); const listTwo = boardsStore.addList(listObjDuplicate); expect(boardsStore.state.lists.length).toBe(2); return axios.waitForAll().then(() => { expect(listOne.issues.length).toBe(1); expect(listTwo.issues.length).toBe(1); boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(1)); expect(listOne.issues.length).toBe(0); expect(listTwo.issues.length).toBe(1); }); }); it('moves an issue from backlog to a list', () => { const backlog = boardsStore.addList({ ...listObj, list_type: 'backlog', }); const listTwo = boardsStore.addList(listObjDuplicate); expect(boardsStore.state.lists.length).toBe(2); return axios.waitForAll().then(() => { expect(backlog.issues.length).toBe(1); expect(listTwo.issues.length).toBe(1); boardsStore.moveIssueToList(backlog, listTwo, backlog.findIssue(1)); expect(backlog.issues.length).toBe(0); expect(listTwo.issues.length).toBe(1); }); }); it('moves issue to top of another list', () => { const listOne = boardsStore.addList(listObj); const listTwo = boardsStore.addList(listObjDuplicate); expect(boardsStore.state.lists.length).toBe(2); return axios.waitForAll().then(() => { listOne.issues[0].id = 2; expect(listOne.issues.length).toBe(1); expect(listTwo.issues.length).toBe(1); boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(2), 0); expect(listOne.issues.length).toBe(0); expect(listTwo.issues.length).toBe(2); expect(listTwo.issues[0].id).toBe(2); expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, listOne.id, listTwo.id, null, 1); }); }); it('moves issue to bottom of another list', () => { const listOne = boardsStore.addList(listObj); const listTwo = boardsStore.addList(listObjDuplicate); expect(boardsStore.state.lists.length).toBe(2); return axios.waitForAll().then(() => { listOne.issues[0].id = 2; expect(listOne.issues.length).toBe(1); expect(listTwo.issues.length).toBe(1); boardsStore.moveIssueToList(listOne, listTwo, listOne.findIssue(2), 1); expect(listOne.issues.length).toBe(0); expect(listTwo.issues.length).toBe(2); expect(listTwo.issues[1].id).toBe(2); expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, listOne.id, listTwo.id, 1, null); }); }); it('moves issue in list', () => { const issue = new ListIssue({ title: 'Testing', id: 2, iid: 2, confidential: false, labels: [], assignees: [], }); const list = boardsStore.addList(listObj); return axios.waitForAll().then(() => { list.addIssue(issue); expect(list.issues.length).toBe(2); boardsStore.moveIssueInList(list, issue, 0, 1, [1, 2]); expect(list.issues[0].id).toBe(2); expect(boardsStore.moveIssue).toHaveBeenCalledWith(2, null, null, 1, null); }); }); }); describe('setListDetail', () => { it('sets the list detail', () => { boardsStore.detail.list = 'not a list'; const dummyValue = 'new list'; boardsStore.setListDetail(dummyValue); expect(boardsStore.detail.list).toEqual(dummyValue); }); }); describe('clearDetailIssue', () => { it('resets issue details', () => { boardsStore.detail.issue = 'something'; boardsStore.clearDetailIssue(); expect(boardsStore.detail.issue).toEqual({}); }); }); describe('setIssueDetail', () => { it('sets issue details', () => { boardsStore.detail.issue = 'some details'; const dummyValue = 'new details'; boardsStore.setIssueDetail(dummyValue); expect(boardsStore.detail.issue).toEqual(dummyValue); }); }); describe('startMoving', () => { it('stores list and issue', () => { const dummyIssue = 'some issue'; const dummyList = 'some list'; boardsStore.startMoving(dummyList, dummyIssue); expect(boardsStore.moving.issue).toEqual(dummyIssue); expect(boardsStore.moving.list).toEqual(dummyList); }); }); describe('setTimeTrackingLimitToHours', () => { it('sets the timeTracking.LimitToHours option', () => { boardsStore.timeTracking.limitToHours = false; boardsStore.setTimeTrackingLimitToHours('true'); expect(boardsStore.timeTracking.limitToHours).toEqual(true); }); }); describe('setCurrentBoard', () => { const dummyBoard = 'hoverboard'; it('sets the current board', () => { const { state } = boardsStore; state.currentBoard = null; boardsStore.setCurrentBoard(dummyBoard); expect(state.currentBoard).toEqual(dummyBoard); }); }); describe('toggleMultiSelect', () => { let basicIssueObj; beforeAll(() => { basicIssueObj = { id: 987654 }; }); afterEach(() => { boardsStore.clearMultiSelect(); }); it('adds issue when not present', () => { boardsStore.toggleMultiSelect(basicIssueObj); const selectedIds = boardsStore.multiSelect.list.map(({ id }) => id); expect(selectedIds.includes(basicIssueObj.id)).toEqual(true); }); it('removes issue when issue is present', () => { boardsStore.toggleMultiSelect(basicIssueObj); let selectedIds = boardsStore.multiSelect.list.map(({ id }) => id); expect(selectedIds.includes(basicIssueObj.id)).toEqual(true); boardsStore.toggleMultiSelect(basicIssueObj); selectedIds = boardsStore.multiSelect.list.map(({ id }) => id); expect(selectedIds.includes(basicIssueObj.id)).toEqual(false); }); }); describe('clearMultiSelect', () => { it('clears all the multi selected issues', () => { const issue1 = { id: 12345 }; const issue2 = { id: 12346 }; boardsStore.toggleMultiSelect(issue1); boardsStore.toggleMultiSelect(issue2); expect(boardsStore.multiSelect.list.length).toEqual(2); boardsStore.clearMultiSelect(); expect(boardsStore.multiSelect.list.length).toEqual(0); }); }); describe('moveMultipleIssuesToList', () => { it('move issues on the new index', () => { const listOne = boardsStore.addList(listObj); const listTwo = boardsStore.addList(listObjDuplicate); expect(boardsStore.state.lists.length).toBe(2); return axios.waitForAll().then(() => { expect(listOne.issues.length).toBe(1); expect(listTwo.issues.length).toBe(1); boardsStore.moveMultipleIssuesToList({ listFrom: listOne, listTo: listTwo, issues: listOne.issues, newIndex: 0, }); expect(listTwo.issues.length).toBe(1); }); }); }); describe('moveMultipleIssuesInList', () => { it('moves multiple issues in list', () => { const issueObj = { title: 'Issue #1', id: 12345, iid: 2, confidential: false, labels: [], assignees: [], }; const issue1 = new ListIssue(issueObj); const issue2 = new ListIssue({ ...issueObj, title: 'Issue #2', id: 12346, }); const list = boardsStore.addList(listObj); return axios.waitForAll().then(() => { list.addIssue(issue1); list.addIssue(issue2); expect(list.issues.length).toBe(3); expect(list.issues[0].id).not.toBe(issue2.id); boardsStore.moveMultipleIssuesInList({ list, issues: [issue1, issue2], oldIndicies: [0], newIndex: 1, idArray: [1, 12345, 12346], }); expect(list.issues[0].id).toBe(issue1.id); expect(boardsStore.moveMultipleIssues).toHaveBeenCalledWith({ ids: [issue1.id, issue2.id], fromListId: null, toListId: null, moveBeforeId: 1, moveAfterId: null, }); }); }); }); describe('addListIssue', () => { let list; const issue1 = new ListIssue({ title: 'Testing', id: 2, iid: 2, confidential: false, labels: [ { color: '#ff0000', description: 'testing;', id: 5000, priority: undefined, textColor: 'white', title: 'Test', }, ], assignees: [], }); const issue2 = new ListIssue({ title: 'Testing', id: 1, iid: 1, confidential: false, labels: [ { id: 1, title: 'test', color: 'red', description: 'testing', }, ], assignees: [ { id: 1, name: 'name', username: 'username', avatar_url: 'http://avatar_url', }, ], real_path: 'path/to/issue', }); beforeEach(() => { list = new List(listObj); list.addIssue(issue1); setupDefaultResponses(); }); it('adds issues that are not already on the list', () => { expect(list.findIssue(issue2.id)).toBe(undefined); expect(list.issues).toEqual([issue1]); boardsStore.addListIssue(list, issue2); expect(list.findIssue(issue2.id)).toBe(issue2); expect(list.issues.length).toBe(2); expect(list.issues).toEqual([issue1, issue2]); }); }); describe('updateIssue', () => { let issue; let patchSpy; beforeEach(() => { issue = new ListIssue({ title: 'Testing', id: 1, iid: 1, confidential: false, labels: [ { id: 1, title: 'test', color: 'red', description: 'testing', }, ], assignees: [ { id: 1, name: 'name', username: 'username', avatar_url: 'http://avatar_url', }, ], real_path: 'path/to/issue', }); patchSpy = jest.fn().mockReturnValue([200, { labels: [] }]); axiosMock.onPatch(`path/to/issue.json`).reply(({ data }) => patchSpy(JSON.parse(data))); }); it('passes assignee ids when there are assignees', () => { boardsStore.updateIssue(issue); return boardsStore.updateIssue(issue).then(() => { expect(patchSpy).toHaveBeenCalledWith({ issue: { milestone_id: null, assignee_ids: [1], label_ids: [1], }, }); }); }); it('passes assignee ids of [0] when there are no assignees', () => { issue.removeAllAssignees(); return boardsStore.updateIssue(issue).then(() => { expect(patchSpy).toHaveBeenCalledWith({ issue: { milestone_id: null, assignee_ids: [0], label_ids: [1], }, }); }); }); }); }); });