From 85a0a1ce997c7203a290e200aebef1492a615a8d Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 9 Jan 2020 11:55:55 +0100 Subject: [PATCH] SONAR-12718 UI Fixes for the code snippet --- .../SnippetViewer.tsx | 6 + .../__tests__/SnippetViewer-test.tsx | 10 + .../__snapshots__/SnippetViewer-test.tsx.snap | 213 ++++++++++++++++++ .../HotspotSnippetContainerRenderer.tsx | 2 + ...spotSnippetContainerRenderer-test.tsx.snap | 3 + .../SourceViewer/SourceViewerHeaderSlim.tsx | 26 ++- .../__tests__/SourceViewerHeaderSlim-test.tsx | 1 + .../SourceViewerHeaderSlim-test.tsx.snap | 79 +++++++ .../SourceViewer/components/Line.tsx | 25 +- .../components/__tests__/Line-test.tsx | 1 + .../__snapshots__/Line-test.tsx.snap | 129 +++++++++++ 11 files changed, 481 insertions(+), 14 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/SnippetViewer.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/SnippetViewer.tsx index ad13be5f4b8..a40025118cd 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/SnippetViewer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/SnippetViewer.tsx @@ -37,6 +37,7 @@ import { inSnippet, LINES_BELOW_ISSUE } from './utils'; interface Props { branchLike: BranchLike | undefined; component: T.SourceViewerFile; + displaySCM?: boolean; duplications?: T.Duplication[]; duplicationsByLine?: { [line: number]: number[] }; expandBlock: (snippetIndex: number, direction: T.ExpandDirection) => Promise; @@ -110,6 +111,7 @@ export default class SnippetViewer extends React.PureComponent { renderLine({ displayDuplications, + displaySCM, index, issuesForLine, issueLocations, @@ -119,6 +121,7 @@ export default class SnippetViewer extends React.PureComponent { verticalBuffer }: { displayDuplications: boolean; + displaySCM?: boolean; index: number; issuesForLine: T.Issue[]; issueLocations: T.LinearIssueLocation[]; @@ -144,6 +147,7 @@ export default class SnippetViewer extends React.PureComponent { displayDuplications={displayDuplications} displayIssues={!isSinkLine || issuesForLine.length > 1} displayLocationMarkers={true} + displaySCM={displaySCM} duplications={lineDuplications} duplicationsCount={duplicationsCount} highlighted={false} @@ -183,6 +187,7 @@ export default class SnippetViewer extends React.PureComponent { render() { const { component, + displaySCM, issue, issuesByLine = {}, last, @@ -230,6 +235,7 @@ export default class SnippetViewer extends React.PureComponent { {snippet.map((line, index) => this.renderLine({ displayDuplications, + displaySCM, index, issuesForLine: issuesByLine[line.line] || [], issueLocations: locationsByLine[line.line] || [], diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/SnippetViewer-test.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/SnippetViewer-test.tsx index 845fbf3d611..ce0160db6e4 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/SnippetViewer-test.tsx +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/SnippetViewer-test.tsx @@ -42,6 +42,16 @@ it('should render correctly', () => { expect(wrapper).toMatchSnapshot(); }); +it('should render correctly with no SCM', () => { + const snippet = range(5, 8).map(line => mockSourceLine({ line })); + const wrapper = shallowRender({ + displaySCM: false, + snippet + }); + + expect(wrapper).toMatchSnapshot(); +}); + it('should render correctly when at the top of the file', () => { const snippet = range(1, 8).map(line => mockSourceLine({ line })); const wrapper = shallowRender({ diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/SnippetViewer-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/SnippetViewer-test.tsx.snap index 2a36a69cd18..f77a840ba37 100644 --- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/SnippetViewer-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/__tests__/__snapshots__/SnippetViewer-test.tsx.snap @@ -928,3 +928,216 @@ exports[`should render correctly when at the top of the file 1`] = ` `; + +exports[`should render correctly with no SCM 1`] = ` +
+
+
+ +
+ + + import java.util.ArrayList;", + "coverageStatus": "covered", + "coveredConditions": 2, + "duplicated": false, + "isNew": true, + "line": 5, + "scmAuthor": "simon.brandhof@sonarsource.com", + "scmDate": "2018-12-11T10:48:39+0100", + "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0", + } + } + loadDuplications={[MockFunction]} + onIssueChange={[MockFunction]} + onIssuePopupToggle={[MockFunction]} + onIssueSelect={[Function]} + onIssueUnselect={[Function]} + onIssuesClose={[MockFunction]} + onIssuesOpen={[MockFunction]} + onLinePopupToggle={[MockFunction]} + onLocationSelect={[MockFunction]} + onSymbolClick={[MockFunction]} + renderDuplicationPopup={[MockFunction]} + scroll={[Function]} + secondaryIssueLocations={Array []} + verticalBuffer={0} + /> + import java.util.ArrayList;", + "coverageStatus": "covered", + "coveredConditions": 2, + "duplicated": false, + "isNew": true, + "line": 6, + "scmAuthor": "simon.brandhof@sonarsource.com", + "scmDate": "2018-12-11T10:48:39+0100", + "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0", + } + } + loadDuplications={[MockFunction]} + onIssueChange={[MockFunction]} + onIssuePopupToggle={[MockFunction]} + onIssueSelect={[Function]} + onIssueUnselect={[Function]} + onIssuesClose={[MockFunction]} + onIssuesOpen={[MockFunction]} + onLinePopupToggle={[MockFunction]} + onLocationSelect={[MockFunction]} + onSymbolClick={[MockFunction]} + previousLine={ + Object { + "code": "import java.util.ArrayList;", + "coverageStatus": "covered", + "coveredConditions": 2, + "duplicated": false, + "isNew": true, + "line": 5, + "scmAuthor": "simon.brandhof@sonarsource.com", + "scmDate": "2018-12-11T10:48:39+0100", + "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0", + } + } + renderDuplicationPopup={[MockFunction]} + scroll={[Function]} + secondaryIssueLocations={Array []} + verticalBuffer={0} + /> + import java.util.ArrayList;", + "coverageStatus": "covered", + "coveredConditions": 2, + "duplicated": false, + "isNew": true, + "line": 7, + "scmAuthor": "simon.brandhof@sonarsource.com", + "scmDate": "2018-12-11T10:48:39+0100", + "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0", + } + } + loadDuplications={[MockFunction]} + onIssueChange={[MockFunction]} + onIssuePopupToggle={[MockFunction]} + onIssueSelect={[Function]} + onIssueUnselect={[Function]} + onIssuesClose={[MockFunction]} + onIssuesOpen={[MockFunction]} + onLinePopupToggle={[MockFunction]} + onLocationSelect={[MockFunction]} + onSymbolClick={[MockFunction]} + previousLine={ + Object { + "code": "import java.util.ArrayList;", + "coverageStatus": "covered", + "coveredConditions": 2, + "duplicated": false, + "isNew": true, + "line": 6, + "scmAuthor": "simon.brandhof@sonarsource.com", + "scmDate": "2018-12-11T10:48:39+0100", + "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0", + } + } + renderDuplicationPopup={[MockFunction]} + scroll={[Function]} + secondaryIssueLocations={Array []} + verticalBuffer={0} + /> + +
+
+ +
+
+
+`; diff --git a/server/sonar-web/src/main/js/apps/securityHotspots/components/HotspotSnippetContainerRenderer.tsx b/server/sonar-web/src/main/js/apps/securityHotspots/components/HotspotSnippetContainerRenderer.tsx index 03f708f70ac..f743bef4d05 100644 --- a/server/sonar-web/src/main/js/apps/securityHotspots/components/HotspotSnippetContainerRenderer.tsx +++ b/server/sonar-web/src/main/js/apps/securityHotspots/components/HotspotSnippetContainerRenderer.tsx @@ -61,6 +61,7 @@ export default function HotspotSnippetContainerRenderer( props.onExpandBlock(direction)} handleCloseIssues={noop} handleLinePopupToggle={props.onLinePopupToggle} diff --git a/server/sonar-web/src/main/js/apps/securityHotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/securityHotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap index a04c877efa8..08bcc2a1b2d 100644 --- a/server/sonar-web/src/main/js/apps/securityHotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/securityHotspots/components/__tests__/__snapshots__/HotspotSnippetContainerRenderer-test.tsx.snap @@ -14,6 +14,7 @@ exports[`should render correctly 1`] = ` } } expandable={false} + linkToProject={false} loading={false} onExpand={[Function]} sourceViewerFile={ @@ -54,6 +55,7 @@ exports[`should render correctly: with sourcelines 1`] = ` } } expandable={false} + linkToProject={false} loading={false} onExpand={[Function]} sourceViewerFile={ @@ -128,6 +130,7 @@ exports[`should render correctly: with sourcelines 1`] = ` "uuid": "foo-bar", } } + displaySCM={false} expandBlock={[Function]} handleCloseIssues={[Function]} handleLinePopupToggle={[MockFunction]} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.tsx index af43dbb1a5a..6a2fdb3240a 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeaderSlim.tsx @@ -31,12 +31,14 @@ import { getPathUrlAsString } from 'sonar-ui-common/helpers/urls'; import { getBranchLikeQuery, isMainBranch } from '../../helpers/branch-like'; import { getBranchLikeUrl, getComponentIssuesUrl } from '../../helpers/urls'; import { BranchLike } from '../../types/branch-like'; +import { ComponentQualifier } from '../../types/component'; import Favorite from '../controls/Favorite'; import './SourceViewerHeaderSlim.css'; export interface Props { branchLike: BranchLike | undefined; expandable?: boolean; + linkToProject?: boolean; loading?: boolean; onExpand?: () => void; sourceViewerFile: T.SourceViewerFile; @@ -45,6 +47,7 @@ export interface Props { export default function SourceViewerHeaderSlim({ branchLike, expandable, + linkToProject = true, loading, onExpand, sourceViewerFile @@ -60,20 +63,31 @@ export default function SourceViewerHeaderSlim({ subProjectName } = sourceViewerFile; + const projectNameLabel = ( + <> + {projectName} + + ); + return (
- - {projectName} - + {linkToProject ? ( + + {projectNameLabel} + + ) : ( + projectNameLabel + )}
{subProject !== undefined && ( <> - {subProjectName} + {' '} + {subProjectName} )} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeaderSlim-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeaderSlim-test.tsx index 5c0034bde2e..33b9f28e187 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeaderSlim-test.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeaderSlim-test.tsx @@ -25,6 +25,7 @@ import SourceViewerHeaderSlim, { Props } from '../SourceViewerHeaderSlim'; it('should render correctly', () => { expect(shallowRender()).toMatchSnapshot(); + expect(shallowRender({ linkToProject: false })).toMatchSnapshot('no link to project'); }); it('should allow to mark as favorite', () => { diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerHeaderSlim-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerHeaderSlim-test.tsx.snap index 29201d1a3fd..562bad0d91b 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerHeaderSlim-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerHeaderSlim-test.tsx.snap @@ -174,3 +174,82 @@ exports[`should render correctly for subproject 1`] = `
`; + +exports[`should render correctly: no link to project 1`] = ` +
+
+
+ + + + MyProject + +
+
+ + + + foo/ + + + bar.ts + +
+
+ +
+
+
+ + source_viewer.view_all_issues + +
+ +
+ + + +
+
+
+`; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx index 2c43c1d30fc..203321d80a3 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx @@ -39,6 +39,7 @@ interface Props { displayIssueLocationsLink?: boolean; displayIssues: boolean; displayLocationMarkers?: boolean; + displaySCM?: boolean; duplications: number[]; duplicationsCount: number; highlighted: boolean; @@ -97,7 +98,14 @@ export default class Line extends React.PureComponent { }; render() { - const { displayCoverage, duplications, duplicationsCount, issuePopup, line } = this.props; + const { + displayCoverage, + displaySCM = true, + duplications, + duplicationsCount, + issuePopup, + line + } = this.props; const className = classNames('source-line', { 'source-line-highlighted': this.props.highlighted, 'source-line-filtered': line.isNew, @@ -119,13 +127,14 @@ export default class Line extends React.PureComponent { popupOpen={this.isPopupOpen('line-number')} /> - - + {displaySCM && ( + + )} {this.props.displayIssues && !this.props.displayAllIssues ? ( { expect(shallowRender()).toMatchSnapshot(); + expect(shallowRender({ displaySCM: false })).toMatchSnapshot('no SCM'); }); it('should render correctly for last, new, and highlighted lines', () => { diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/Line-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/Line-test.tsx.snap index fee4f4dd800..931708c4071 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/Line-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/Line-test.tsx.snap @@ -902,3 +902,132 @@ exports[`should render correctly with issues info 1`] = ` /> `; + +exports[`should render correctly: no SCM 1`] = ` + + import java.util.ArrayList;", + "coverageStatus": "covered", + "coveredConditions": 2, + "duplicated": false, + "isNew": true, + "line": 16, + "scmAuthor": "simon.brandhof@sonarsource.com", + "scmDate": "2018-12-11T10:48:39+0100", + "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0", + } + } + onPopupToggle={[MockFunction]} + popupOpen={false} + /> + + import java.util.ArrayList;", + "coverageStatus": "covered", + "coveredConditions": 2, + "duplicated": false, + "isNew": true, + "line": 16, + "scmAuthor": "simon.brandhof@sonarsource.com", + "scmDate": "2018-12-11T10:48:39+0100", + "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0", + } + } + onIssueChange={[MockFunction]} + onIssuePopupToggle={[MockFunction]} + onIssueSelect={[MockFunction]} + onLocationSelect={[MockFunction]} + onSymbolClick={[MockFunction]} + scroll={[MockFunction]} + secondaryIssueLocations={Array []} + showIssues={false} + /> + +`; -- 2.39.5