From 78796b6fd66d9451ac6b547f5fc30723b6d3535d Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 6 Aug 2020 15:51:57 +0200 Subject: [PATCH] SONAR-13637 Handle errors --- .../create/project/GitlabProjectCreate.tsx | 47 +++++++++++++------ .../__tests__/GitlabProjectCreate-test.tsx | 39 +++++++++++++++ 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/create/project/GitlabProjectCreate.tsx b/server/sonar-web/src/main/js/apps/create/project/GitlabProjectCreate.tsx index 87e35b9dd72..eacbe599c70 100644 --- a/server/sonar-web/src/main/js/apps/create/project/GitlabProjectCreate.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/GitlabProjectCreate.tsx @@ -111,7 +111,6 @@ export default class GitlabProjectCreate extends React.PureComponent false); }; - fetchProjects = (pageIndex = 1, query?: string) => { + handleError = () => { + if (this.mounted) { + this.setState({ tokenIsValid: false }); + } + + return undefined; + }; + + fetchProjects = async (pageIndex = 1, query?: string) => { const { settings } = this.state; if (!settings) { return Promise.resolve(undefined); } - return getGitlabProjects({ - almSetting: settings.key, - page: pageIndex, - pageSize: GITLAB_PROJECTS_PAGESIZE, - query - }).catch(() => undefined); + try { + return await getGitlabProjects({ + almSetting: settings.key, + page: pageIndex, + pageSize: GITLAB_PROJECTS_PAGESIZE, + query + }); + } catch (_) { + return this.handleError(); + } }; - handleImport = async (gitlabProjectId: string) => { + doImport = async (gitlabProjectId: string) => { const { settings } = this.state; if (!settings) { - return; + return Promise.resolve(undefined); + } + + try { + return await importGitlabProject({ + almSetting: settings.key, + gitlabProjectId + }); + } catch (_) { + return this.handleError(); } + }; + handleImport = async (gitlabProjectId: string) => { this.setState({ importingGitlabProjectId: gitlabProjectId }); - const result = await importGitlabProject({ - almSetting: settings.key, - gitlabProjectId - }).catch(() => undefined); + const result = await this.doImport(gitlabProjectId); if (this.mounted) { this.setState({ importingGitlabProjectId: undefined }); diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreate-test.tsx index b7c84ffdba4..c6d0116591c 100644 --- a/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreate-test.tsx +++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/GitlabProjectCreate-test.tsx @@ -67,6 +67,14 @@ it('should correctly check PAT when settings are added after mount', async () => it('should correctly handle a valid PAT', async () => { (checkPersonalAccessTokenIsValid as jest.Mock).mockResolvedValueOnce(true); + (getGitlabProjects as jest.Mock).mockResolvedValueOnce({ + projects: [mockGitlabProject()], + projectsPaging: { + pageIndex: 1, + pageSize: 10, + total: 1 + } + }); const wrapper = shallowRender(); await waitAndUpdate(wrapper); expect(wrapper.state().tokenIsValid).toBe(true); @@ -250,6 +258,37 @@ it('should do nothing with missing settings', async () => { expect(setAlmPersonalAccessToken).not.toHaveBeenCalled(); }); +it('should handle errors when fetching projects', async () => { + (getGitlabProjects as jest.Mock).mockRejectedValueOnce({}); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + expect(wrapper.state().tokenIsValid).toBe(false); +}); + +it('should handle errors when importing a project', async () => { + (importGitlabProject as jest.Mock).mockRejectedValueOnce({}); + (getGitlabProjects as jest.Mock).mockResolvedValueOnce({ + projects: [mockGitlabProject()], + projectsPaging: { + pageIndex: 1, + pageSize: 10, + total: 1 + } + }); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + expect(wrapper.state().tokenIsValid).toBe(true); + + await wrapper.instance().handleImport('gitlabId'); + await waitAndUpdate(wrapper); + + expect(wrapper.state().tokenIsValid).toBe(false); +}); + function shallowRender(props: Partial = {}) { return shallow(