diff options
author | Jeremy Davis <jeremy.davis@sonarsource.com> | 2020-12-01 14:39:15 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-12-03 20:06:38 +0000 |
commit | 19c1858b5e72a19332e6a77fd532712e07b47a77 (patch) | |
tree | 826b780f051756db31d8a789149015b8bc506610 | |
parent | 9261d0a1d167022244856dd7949b57fa1f0b68f5 (diff) | |
download | sonarqube-19c1858b5e72a19332e6a77fd532712e07b47a77.tar.gz sonarqube-19c1858b5e72a19332e6a77fd532712e07b47a77.zip |
SONAR-14130 Always underline Primary Location in snippets
4 files changed, 34 insertions, 3 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/ComponentSourceSnippetGroupViewer.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/ComponentSourceSnippetGroupViewer.tsx index c70d98dd813..d007ec132b4 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/ComponentSourceSnippetGroupViewer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/ComponentSourceSnippetGroupViewer.tsx @@ -40,6 +40,7 @@ interface Props { duplications?: T.Duplication[]; duplicationsByLine?: { [line: number]: number[] }; highlightedLocationMessage: { index: number; text: string | undefined } | undefined; + isLastOccurenceOfPrimaryComponent: boolean; issue: T.Issue; issuePopup?: { issue: string; name: string }; issuesByLine: T.IssuesByLine; @@ -348,6 +349,7 @@ export default class ComponentSourceSnippetGroupViewer extends React.PureCompone render() { const { branchLike, + isLastOccurenceOfPrimaryComponent, issue, issuesByLine, issuePopup, @@ -372,8 +374,7 @@ export default class ComponentSourceSnippetGroupViewer extends React.PureCompone }); const isFlow = issue.secondaryLocations.length === 0; - const includeIssueLocation = (snippetIndex: number) => - isFlow ? lastSnippetGroup && snippetIndex === snippets.length - 1 : snippetIndex === 0; + const includeIssueLocation = isFlow ? isLastOccurenceOfPrimaryComponent : true; return ( <div className="component-source-container" ref={this.rootNodeRef}> @@ -402,7 +403,7 @@ export default class ComponentSourceSnippetGroupViewer extends React.PureCompone snippet, index: snippets[index].index, issuesByLine, - locationsByLine: includeIssueLocation(index) ? locations : {}, + locationsByLine: includeIssueLocation ? locations : {}, lastSnippetOfLastGroup: lastSnippetGroup && index === snippets.length - 1 })} </div> diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx index be54678e2ff..f97ecebc951 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { findLastIndex } from 'lodash'; import * as React from 'react'; import { Alert } from 'sonar-ui-common/components/ui/Alert'; import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner'; @@ -194,6 +195,11 @@ export default class CrossComponentSourceViewerWrapper extends React.PureCompone const issuesByComponent = issuesByComponentAndLine(this.props.issues); const locationsByComponent = groupLocationsByComponent(issue, locations, components); + const lastOccurenceOfPrimaryComponent = findLastIndex( + locationsByComponent, + ({ component }) => component.key === issue.component + ); + return ( <div> {locationsByComponent.map((snippetGroup, i) => { @@ -210,6 +216,7 @@ export default class CrossComponentSourceViewerWrapper extends React.PureCompone issue={issue} issuePopup={this.state.issuePopup} issuesByLine={issuesByComponent[snippetGroup.component.key] || {}} + isLastOccurenceOfPrimaryComponent={i === lastOccurenceOfPrimaryComponent} lastSnippetGroup={i === locationsByComponent.length - 1} loadDuplications={this.fetchDuplications} locations={snippetGroup.locations || []} diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/ComponentSourceSnippetGroupViewer-test.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/ComponentSourceSnippetGroupViewer-test.tsx index 7cbb22843f9..fe373363117 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/ComponentSourceSnippetGroupViewer-test.tsx +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/ComponentSourceSnippetGroupViewer-test.tsx @@ -32,6 +32,7 @@ import { mockSourceViewerFile } from '../../../../helpers/testMocks'; import ComponentSourceSnippetGroupViewer from '../ComponentSourceSnippetGroupViewer'; +import SnippetViewer from '../SnippetViewer'; jest.mock('../../../../api/components', () => ({ getSources: jest.fn().mockResolvedValue([]) @@ -104,6 +105,24 @@ it('should render correctly with flows', () => { expect(wrapper.state('snippets')).toHaveLength(2); expect(wrapper.state('snippets')[0]).toEqual({ index: 0, start: 29, end: 39 }); expect(wrapper.state('snippets')[1]).toEqual({ index: 1, start: 69, end: 79 }); + + // Check that locationsByLine is defined when isLastOccurenceOfPrimaryComponent + expect( + wrapper + .find(SnippetViewer) + .at(0) + .props().locationsByLine + ).not.toEqual({}); + + // If not, it should be an empty object: + const snippets = shallowRender({ + isLastOccurenceOfPrimaryComponent: false, + issue, + snippetGroup + }).find(SnippetViewer); + + expect(snippets.at(0).props().locationsByLine).toEqual({}); + expect(snippets.at(1).props().locationsByLine).toEqual({}); }); it('should render file-level issue correctly', () => { @@ -281,6 +300,7 @@ describe('getNodes', () => { <ComponentSourceSnippetGroupViewer branchLike={mockMainBranch()} highlightedLocationMessage={{ index: 0, text: '' }} + isLastOccurenceOfPrimaryComponent={true} issue={mockIssue()} issuesByLine={{}} lastSnippetGroup={false} @@ -335,6 +355,7 @@ describe('getHeight', () => { <ComponentSourceSnippetGroupViewer branchLike={mockMainBranch()} highlightedLocationMessage={{ index: 0, text: '' }} + isLastOccurenceOfPrimaryComponent={true} issue={mockIssue()} issuesByLine={{}} lastSnippetGroup={false} @@ -385,6 +406,7 @@ function shallowRender(props: Partial<ComponentSourceSnippetGroupViewer['props'] <ComponentSourceSnippetGroupViewer branchLike={mockMainBranch()} highlightedLocationMessage={{ index: 0, text: '' }} + isLastOccurenceOfPrimaryComponent={true} issue={mockIssue()} issuesByLine={{}} lastSnippetGroup={false} 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 5c8d46ab238..277d63d0309 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 @@ -47,6 +47,7 @@ exports[`should render correctly 2`] = ` > <ComponentSourceSnippetGroupViewer duplicationsByLine={Object {}} + isLastOccurenceOfPrimaryComponent={true} issue={ Object { "actions": Array [], |