From 590bea49eb3556e8506660694f276038385ea118 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 24 Feb 2020 11:02:37 +0100 Subject: [PATCH] SONAR-13117 Handle 403 gracefully --- server/sonar-web/src/main/js/api/issues.ts | 2 +- .../CrossComponentSourceViewerWrapper.tsx | 28 +++++++++++++++---- ...CrossComponentSourceViewerWrapper-test.tsx | 18 +++++++++--- ...ComponentSourceViewerWrapper-test.tsx.snap | 9 ++++++ 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/server/sonar-web/src/main/js/api/issues.ts b/server/sonar-web/src/main/js/api/issues.ts index 769512154d4..c4913ab6bfd 100644 --- a/server/sonar-web/src/main/js/api/issues.ts +++ b/server/sonar-web/src/main/js/api/issues.ts @@ -183,5 +183,5 @@ export function getIssueFlowSnippets(issueKey: string): Promise { @@ -65,7 +69,8 @@ export default class CrossComponentSourceViewerWrapper extends React.PureCompone state: State = { components: {}, duplicationsByLine: {}, - loading: true + loading: true, + notAccessible: false }; componentDidMount() { @@ -121,9 +126,12 @@ export default class CrossComponentSourceViewerWrapper extends React.PureCompone } } }, - () => { + ({ response }: { response: Response }) => { + if (response.status !== 403) { + throwGlobalError({ response }); + } if (this.mounted) { - this.setState({ loading: false }); + this.setState({ loading: false, notAccessible: response.status === 403 }); } } ); @@ -196,7 +204,7 @@ export default class CrossComponentSourceViewerWrapper extends React.PureCompone }; render() { - const { loading } = this.state; + const { loading, notAccessible } = this.state; if (loading) { return ( @@ -206,6 +214,14 @@ export default class CrossComponentSourceViewerWrapper extends React.PureCompone ); } + if (notAccessible) { + return ( + + {translate('code_viewer.no_source_code_displayed_due_to_security')} + + ); + } + const { components, duplications, duplicationsByLine, linePopup } = this.state; const issuesByComponent = issuesByComponentAndLine(this.props.issues); const locationsByComponent = groupLocationsByComponent(this.props.locations, components); diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/CrossComponentSourceViewerWrapper-test.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/CrossComponentSourceViewerWrapper-test.tsx index 4d283b416d1..ca19ef6b092 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/CrossComponentSourceViewerWrapper-test.tsx +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/CrossComponentSourceViewerWrapper-test.tsx @@ -17,9 +17,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import * as React from 'react'; import { shallow } from 'enzyme'; -import CrossComponentSourceViewerWrapper from '../CrossComponentSourceViewerWrapper'; +import * as React from 'react'; +import { getDuplications } from '../../../../api/components'; +import { getIssueFlowSnippets } from '../../../../api/issues'; import { mockFlowLocation, mockIssue, @@ -28,8 +29,7 @@ import { mockSourceViewerFile } from '../../../../helpers/testMocks'; import { waitAndUpdate } from '../../../../helpers/testUtils'; -import { getIssueFlowSnippets } from '../../../../api/issues'; -import { getDuplications } from '../../../../api/components'; +import CrossComponentSourceViewerWrapper from '../CrossComponentSourceViewerWrapper'; jest.mock('../../../../api/issues', () => { const { mockSnippetsByComponent } = require.requireActual('../../../../helpers/testMocks'); @@ -66,6 +66,16 @@ it('Should fetch data', async () => { expect(getIssueFlowSnippets).toBeCalledWith('foo'); }); +it('Should handle no access rights', async () => { + (getIssueFlowSnippets as jest.Mock).mockRejectedValueOnce({ response: { status: 403 } }); + + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + + expect(wrapper.state().notAccessible).toBe(true); + expect(wrapper).toMatchSnapshot(); +}); + it('should handle issue popup', () => { const wrapper = shallowRender(); // open diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/CrossComponentSourceViewerWrapper-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/CrossComponentSourceViewerWrapper-test.tsx.snap index 5f6913c5ace..c6362cb8a71 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/CrossComponentSourceViewerWrapper-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/CrossComponentSourceViewerWrapper-test.tsx.snap @@ -1,5 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Should handle no access rights 1`] = ` + + code_viewer.no_source_code_displayed_due_to_security + +`; + exports[`should handle duplication popup 1`] = ` [Function] -- 2.39.5