From 07cd210069bba37cc26a7bbadfcc7e99bd6bbe98 Mon Sep 17 00:00:00 2001 From: Wouter Admiraal Date: Mon, 30 Nov 2020 11:59:05 +0100 Subject: [PATCH] SONAR-14154 Report API errors when updating issues --- .../issue/__tests__/actions-test.ts | 83 +++++++++++++++++++ .../src/main/js/components/issue/actions.ts | 4 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts diff --git a/server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts b/server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts new file mode 100644 index 00000000000..bcc1845bfa8 --- /dev/null +++ b/server/sonar-web/src/main/js/components/issue/__tests__/actions-test.ts @@ -0,0 +1,83 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import throwGlobalError from '../../../app/utils/throwGlobalError'; +import { parseIssueFromResponse } from '../../../helpers/issues'; +import { mockComponent, mockIssue } from '../../../helpers/testMocks'; +import { updateIssue } from '../actions'; + +jest.mock('../../../app/utils/throwGlobalError', () => ({ + default: jest.fn() +})); + +jest.mock('../../../helpers/issues', () => ({ + parseIssueFromResponse: jest.fn() +})); + +describe('updateIssue', () => { + const onChange = jest.fn(); + const oldIssue = mockIssue(false, { key: 'old' }); + const newIssue = mockIssue(false, { key: 'new' }); + const parsedIssue = mockIssue(false, { key: 'parsed' }); + const successPromise = jest.fn().mockResolvedValue({ + issue: mockIssue(), + components: [mockComponent()] + }); + const errorPromise = jest.fn().mockRejectedValue(null); + (parseIssueFromResponse as jest.Mock).mockReturnValue(parsedIssue); + + beforeEach(jest.clearAllMocks); + + it('makes successful optimistic updates', async () => { + updateIssue(onChange, successPromise(), oldIssue, newIssue); + expect(onChange).toBeCalledWith(newIssue); + + await new Promise(setImmediate); + + expect(onChange).toBeCalledTimes(1); + }); + + it('makes successful non-optimistic updates', async () => { + updateIssue(onChange, successPromise()); + expect(onChange).not.toBeCalled(); + + await new Promise(setImmediate); + expect(onChange).toBeCalledWith(parsedIssue); + expect(onChange).toBeCalledTimes(1); + }); + + it('makes unsuccessful optimistic updates', async () => { + updateIssue(onChange, errorPromise(), oldIssue, newIssue); + expect(onChange).toBeCalledWith(newIssue); + + await new Promise(setImmediate); + + expect(onChange).toBeCalledWith(oldIssue); + expect(onChange).toBeCalledTimes(2); + }); + + it('makes unsuccessful non-optimistic updates', async () => { + updateIssue(onChange, errorPromise()); + expect(onChange).not.toBeCalled(); + + await new Promise(setImmediate); + expect(parseIssueFromResponse).not.toBeCalled(); + expect(throwGlobalError).toBeCalled(); + }); +}); diff --git a/server/sonar-web/src/main/js/components/issue/actions.ts b/server/sonar-web/src/main/js/components/issue/actions.ts index e59a57e8c8e..978512ca3d4 100644 --- a/server/sonar-web/src/main/js/components/issue/actions.ts +++ b/server/sonar-web/src/main/js/components/issue/actions.ts @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { IssueResponse } from '../../api/issues'; +import throwGlobalError from '../../app/utils/throwGlobalError'; import { parseIssueFromResponse } from '../../helpers/issues'; export const updateIssue = ( @@ -43,10 +44,11 @@ export const updateIssue = ( onChange(issue); } }, - () => { + param => { if (optimisticUpdate) { onChange(oldIssue!); } + throwGlobalError(param); } ); }; -- 2.39.5