]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16256 Add RTL test to SourceViewer
authorMathieu Suen <mathieu.suen@sonarsource.com>
Wed, 13 Apr 2022 11:36:33 +0000 (13:36 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 19 Apr 2022 20:03:07 +0000 (20:03 +0000)
29 files changed:
server/sonar-web/src/main/js/api/mocks/SourceViewerServiceMock.ts [new file with mode: 0644]
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx
server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerBase-test.tsx
server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerCode-test.tsx
server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerCode-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/Line-test.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCoverage-test.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplicationBlock-test.tsx [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesList-test.tsx [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.tsx
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineOptionsPopup-test.tsx [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineSCM-test.tsx [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/SCMPopup-test.tsx [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/Line-test.tsx.snap
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineCoverage-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineDuplicationBlock-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssuesList-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineNumber-test.tsx.snap
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineOptionsPopup-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineSCM-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/SCMPopup-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/components/SourceViewer/helpers/lines.ts
server/sonar-web/src/main/js/components/issue/IssueView.tsx
server/sonar-web/src/main/js/components/issue/__tests__/__snapshots__/IssueView-test.tsx.snap
server/sonar-web/src/main/js/helpers/testReactTestingUtils.tsx

diff --git a/server/sonar-web/src/main/js/api/mocks/SourceViewerServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/SourceViewerServiceMock.ts
new file mode 100644 (file)
index 0000000..636c304
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.
+ */
+/* eslint-disable no-template-curly-in-string */
+
+import { cloneDeep, pick, times } from 'lodash';
+import {
+  getComponentData,
+  getComponentForSourceViewer,
+  getDuplications,
+  getSources
+} from '../../api/components';
+import { mockSourceLine } from '../../helpers/testMocks';
+import { BranchParameters } from '../../types/branch-like';
+import { Dict } from '../../types/types';
+
+function mockSourceFileView(name: string) {
+  return {
+    component: {
+      key: `project:${name}`,
+      name,
+      qualifier: 'FIL',
+      path: name,
+      language: 'js',
+      analysisDate: '2019-08-08T12:15:12+0200',
+      leakPeriodDate: '2018-08-07T11:22:22+0200',
+      version: '1.2-SNAPSHOT',
+      needIssueSync: false
+    },
+    sourceFileView: {
+      key: `project:${name}`,
+      uuid: 'AWMgNpveti8CNlpVyHAm',
+      path: name,
+      name,
+      longName: name,
+      q: 'FIL',
+      project: 'project',
+      projectName: 'Test project',
+      fav: false,
+      canMarkAsFavorite: true,
+      measures: { lines: '0', issues: '0' }
+    }
+  };
+}
+
+const ANCESTORS = [
+  {
+    key: 'project',
+    name: 'Test project',
+    description: '',
+    qualifier: 'TRK',
+    analysisDate: '2019-08-08T12:15:12+0200',
+    tags: [],
+    visibility: 'public',
+    leakPeriodDate: '2018-08-07T11:22:22+0200',
+    version: '1.2-SNAPSHOT',
+    needIssueSync: false
+  }
+];
+const FILES: Dict<any> = {
+  'project:test3.js': {
+    ...mockSourceFileView('test3.js'),
+    sources: [],
+    ancestors: ANCESTORS
+  },
+  'project:test2.js': {
+    ...mockSourceFileView('test2.js'),
+    sources: times(200, n =>
+      mockSourceLine({
+        line: n,
+        code: `\u003cspan class\u003d"cd"\u003eLine ${n}\u003c/span\u003e`
+      })
+    ),
+    ancestors: ANCESTORS
+  },
+  'project:test.js': {
+    ...mockSourceFileView('test.js'),
+    sources: [
+      {
+        line: 1,
+        code: '\u003cspan class\u003d"cd"\u003e/*\u003c/span\u003e',
+        scmRevision: 'f09ee6b610528aa37b7b51be395c93524cebae8f',
+        scmAuthor: 'stas.vilchik@sonarsource.com',
+        scmDate: '2018-07-10T20:21:20+0200',
+        duplicated: false,
+        isNew: false,
+        lineHits: 1,
+        coveredConditions: 1
+      },
+      {
+        line: 2,
+        code: '\u003cspan class\u003d"cd"\u003e * SonarQube\u003c/span\u003e',
+        scmRevision: 'f09ee6b610528aa37b7b51be395c93524cebae8f',
+        scmAuthor: 'stas.vilchik@sonarsource.com',
+        scmDate: '2018-07-10T20:21:20+0200',
+        duplicated: false,
+        isNew: false,
+        lineHits: 0,
+        conditions: 1
+      },
+      {
+        line: 3,
+        code: '\u003cspan class\u003d"cd"\u003e * Copyright\u003c/span\u003e',
+        scmRevision: '89a3d21bc28f2fa6201b5e8b1185d5358481b3dd',
+        scmAuthor: 'pierre.guillot@sonarsource.com',
+        scmDate: '2022-01-28T21:03:07+0100',
+        duplicated: false,
+        isNew: false,
+        lineHits: 1
+      },
+      {
+        line: 4,
+        code:
+          '\u003cspan class\u003d"cd"\u003e * mailto:info AT sonarsource DOT com\u003c/span\u003e',
+        scmRevision: 'f09ee6b610528aa37b7b51be395c93524cebae8f',
+        scmAuthor: 'stas.vilchik@sonarsource.com',
+        duplicated: false,
+        isNew: false,
+        lineHits: 1,
+        conditions: 1,
+        coveredConditions: 1
+      },
+      {
+        line: 5,
+        code: '\u003cspan class\u003d"cd"\u003e * 5\u003c/span\u003e',
+        scmRevision: 'f04ee6b610528aa37b7b51be395c93524cebae8f',
+        duplicated: false,
+        isNew: false,
+        lineHits: 2,
+        conditions: 2,
+        coveredConditions: 1
+      },
+      {
+        line: 6,
+        code: '\u003cspan class\u003d"cd"\u003e * 6\u003c/span\u003e',
+        scmRevision: 'f04ee6b610528aa37b7b51be395c93524cebae8f',
+        duplicated: false,
+        isNew: false,
+        lineHits: 0
+      },
+      {
+        line: 7,
+        code: '\u003cspan class\u003d"cd"\u003e * 7\u003c/span\u003e',
+        scmRevision: 'f04ee6b610528aa37b7b51be395c93524cebae8f',
+        duplicated: true,
+        isNew: true
+      },
+      {
+        code:
+          '\u003cspan class\u003d"cd"\u003e * This program is free software; you can redistribute it and/or\u003c/span\u003e',
+        scmRevision: 'f09ee6b610528aa37b7b51be395c93524cebae8f',
+        scmAuthor: 'stas.vilchik@sonarsource.com',
+        scmDate: '2018-07-10T20:21:20+0200',
+        duplicated: false,
+        isNew: false
+      }
+    ],
+    ancestors: ANCESTORS,
+    duplications: [
+      {
+        blocks: [
+          { from: 7, size: 1, _ref: '1' },
+          { from: 1, size: 1, _ref: '2' }
+        ]
+      }
+    ],
+    files: {
+      '1': {
+        key: 'project:test.js',
+        name: 'test.js',
+        uuid: 'AX8NSmj8EGYw5-dyy63J',
+        project: 'project',
+        projectUuid: 'AX7juKJqVeQLJMPyb_b-',
+        projectName: 'project'
+      },
+      '2': {
+        key: 'project:test2.js',
+        name: 'test2.js',
+        uuid: 'BX8NSmj8EGYw5-dyy63J',
+        project: 'project',
+        projectUuid: 'AX7juKJqVeQLJMPyb_b-',
+        projectName: 'project'
+      }
+    }
+  }
+};
+
+export class SourceViewerServiceMock {
+  constructor() {
+    (getComponentData as jest.Mock).mockImplementation(this.handleGetComponentData);
+    (getComponentForSourceViewer as jest.Mock).mockImplementation(
+      this.handleGetComponentForSourceViewer
+    );
+    (getDuplications as jest.Mock).mockImplementation(this.handleGetDuplications);
+    (getSources as jest.Mock).mockImplementation(this.handleGetSources);
+  }
+
+  getHugeFile(): string {
+    return 'project:test2.js';
+  }
+
+  getEmptyFile(): string {
+    return 'project:test3.js';
+  }
+
+  getFileWithSource(): string {
+    return 'project:test.js';
+  }
+
+  handleGetSources = (data: { key: string; from?: number; to?: number } & BranchParameters) => {
+    const { sources } = FILES[data.key];
+    const from = data.from || 1;
+    const to = data.to || sources.length;
+    return this.reply(sources.slice(from - 1, to));
+  };
+
+  handleGetDuplications = (data: { key: string } & BranchParameters) => {
+    return this.reply(pick(FILES[data.key], ['duplications', 'files']));
+  };
+
+  handleGetComponentForSourceViewer = (data: { component: string } & BranchParameters) => {
+    return this.reply(FILES[data.component]['sourceFileView']);
+  };
+
+  handleGetComponentData = (data: { component: string } & BranchParameters) => {
+    return this.reply(pick(FILES[data.component], ['component', 'ancestor']));
+  };
+
+  reply<T>(response: T): Promise<T> {
+    return Promise.resolve(cloneDeep(response));
+  }
+}
index e2e41a161657adfc9f3da4f5013a741652f0d28b..ba2f5faee8530dfa1ab779e5778762ee3c9a29b6 100644 (file)
@@ -54,6 +54,7 @@ import {
   locationsByLine,
   symbolsByLine
 } from './helpers/indexing';
+import { LINES_TO_LOAD } from './helpers/lines';
 import defaultLoadIssues from './helpers/loadIssues';
 import SourceViewerCode from './SourceViewerCode';
 import { SourceViewerContext } from './SourceViewerContext';
@@ -77,22 +78,12 @@ export interface Props {
   // but kept to maintaint the location indexes
   highlightedLocations?: (FlowLocation | undefined)[];
   highlightedLocationMessage?: { index: number; text: string | undefined };
-  loadComponent?: (
-    component: string,
-    branchLike: BranchLike | undefined
-  ) => Promise<SourceViewerFile>;
   loadIssues?: (
     component: string,
     from: number,
     to: number,
     branchLike: BranchLike | undefined
   ) => Promise<Issue[]>;
-  loadSources?: (
-    component: string,
-    from: number,
-    to: number,
-    branchLike: BranchLike | undefined
-  ) => Promise<SourceLine[]>;
   onLoaded?: (component: SourceViewerFile, sources: SourceLine[], issues: Issue[]) => void;
   onLocationSelect?: (index: number) => void;
   onIssueChange?: (issue: Issue) => void;
@@ -128,8 +119,6 @@ interface State {
   symbolsByLine: { [line: number]: string[] };
 }
 
-const LINES = 500;
-
 export default class SourceViewerBase extends React.PureComponent<Props, State> {
   node?: HTMLElement | null;
   mounted = false;
@@ -195,7 +184,27 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
       prevProps.aroundLine !== this.props.aroundLine &&
       this.isLineOutsideOfRange(this.props.aroundLine)
     ) {
-      this.fetchSources();
+      this.fetchSources().then(
+        sources => {
+          if (this.mounted) {
+            const finalSources = sources.slice(0, LINES_TO_LOAD);
+            this.setState(
+              {
+                sources: sources.slice(0, LINES_TO_LOAD),
+                hasSourcesAfter: sources.length > LINES_TO_LOAD
+              },
+              () => {
+                if (this.props.onLoaded && this.state.component && this.state.issues) {
+                  this.props.onLoaded(this.state.component, finalSources, this.state.issues);
+                }
+              }
+            );
+          }
+        },
+        () => {
+          // TODO
+        }
+      );
     } else {
       const { selectedIssue } = this.props;
       const { issues } = this.state;
@@ -213,16 +222,27 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
     this.mounted = false;
   }
 
-  get loadComponent() {
-    return this.props.loadComponent || defaultLoadComponent;
+  loadComponent(component: string, branchLike?: BranchLike) {
+    return Promise.all([
+      getComponentForSourceViewer({ component, ...getBranchLikeQuery(branchLike) }),
+      getComponentData({ component, ...getBranchLikeQuery(branchLike) })
+    ]).then(([sourceViewerComponent, { component }]) => ({
+      ...sourceViewerComponent,
+      leakPeriodDate: component.leakPeriodDate
+    }));
   }
 
-  get loadIssues() {
-    return this.props.loadIssues || defaultLoadIssues;
+  loadSources(
+    key: string,
+    from: number | undefined,
+    to: number | undefined,
+    branchLike: BranchLike | undefined
+  ) {
+    return getSources({ key, from, to, ...getBranchLikeQuery(branchLike) });
   }
 
-  get propsLoadSources() {
-    return this.props.loadSources || defaultLoadSources;
+  get loadIssues() {
+    return this.props.loadIssues || defaultLoadIssues;
   }
 
   computeCoverageStatus(lines: SourceLine[]) {
@@ -243,20 +263,19 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
   fetchComponent() {
     this.setState({ loading: true });
 
-    const to = (this.props.aroundLine || 0) + LINES;
+    const to = (this.props.aroundLine || 0) + LINES_TO_LOAD;
     const loadIssues = (component: SourceViewerFile, sources: SourceLine[]) => {
       this.loadIssues(this.props.component, 1, to, this.props.branchLike).then(
         issues => {
           if (this.mounted) {
-            const finalSources = sources.slice(0, LINES);
-
+            const finalSources = sources.slice(0, LINES_TO_LOAD);
             this.setState(
               {
                 component,
                 duplicatedFiles: undefined,
                 duplications: undefined,
                 duplicationsByLine: {},
-                hasSourcesAfter: sources.length > LINES,
+                hasSourcesAfter: sources.length > LINES_TO_LOAD,
                 highlightedSymbols: [],
                 issueLocationsByLine: locationsByLine(issues),
                 issues,
@@ -268,7 +287,7 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
                 issuePopup: undefined,
                 sourceRemoved: false,
                 sources: this.computeCoverageStatus(finalSources),
-                symbolsByLine: symbolsByLine(sources.slice(0, LINES))
+                symbolsByLine: symbolsByLine(sources.slice(0, LINES_TO_LOAD))
               },
               () => {
                 if (this.props.onLoaded) {
@@ -308,7 +327,7 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
 
     const onResolve = (component: SourceViewerFile) => {
       const sourcesRequest =
-        component.q === 'FIL' || component.q === 'UTS' ? this.loadSources() : Promise.resolve([]);
+        component.q === 'FIL' || component.q === 'UTS' ? this.fetchSources() : Promise.resolve([]);
       sourcesRequest.then(
         sources => loadIssues(component, sources),
         response => onFailLoadSources(response, component)
@@ -321,30 +340,6 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
     );
   }
 
-  fetchSources() {
-    this.loadSources().then(
-      sources => {
-        if (this.mounted) {
-          const finalSources = sources.slice(0, LINES);
-          this.setState(
-            {
-              sources: sources.slice(0, LINES),
-              hasSourcesAfter: sources.length > LINES
-            },
-            () => {
-              if (this.props.onLoaded && this.state.component && this.state.issues) {
-                this.props.onLoaded(this.state.component, finalSources, this.state.issues);
-              }
-            }
-          );
-        }
-      },
-      () => {
-        // TODO
-      }
-    );
-  }
-
   reloadIssues() {
     if (!this.state.sources) {
       return;
@@ -372,7 +367,7 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
     );
   }
 
-  loadSources = (): Promise<SourceLine[]> => {
+  fetchSources = (): Promise<SourceLine[]> => {
     return new Promise((resolve, reject) => {
       const onFailLoadSources = (response: Response) => {
         // TODO handle other statuses
@@ -385,17 +380,21 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
         }
       };
 
-      const from = this.props.aroundLine ? Math.max(1, this.props.aroundLine - LINES / 2 + 1) : 1;
+      const from = this.props.aroundLine
+        ? Math.max(1, this.props.aroundLine - LINES_TO_LOAD / 2 + 1)
+        : 1;
 
-      let to = this.props.aroundLine ? this.props.aroundLine + LINES / 2 + 1 : LINES + 1;
+      let to = this.props.aroundLine
+        ? this.props.aroundLine + LINES_TO_LOAD / 2 + 1
+        : LINES_TO_LOAD + 1;
       // make sure we try to download `LINES` lines
-      if (from === 1 && to < LINES) {
-        to = LINES;
+      if (from === 1 && to < LINES_TO_LOAD) {
+        to = LINES_TO_LOAD;
       }
       // request one additional line to define `hasSourcesAfter`
       to++;
 
-      this.propsLoadSources(this.props.component, from, to, this.props.branchLike).then(sources => {
+      this.loadSources(this.props.component, from, to, this.props.branchLike).then(sources => {
         resolve(sources);
       }, onFailLoadSources);
     });
@@ -407,14 +406,9 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
     }
     const firstSourceLine = this.state.sources[0];
     this.setState({ loadingSourcesBefore: true });
-    const from = Math.max(1, firstSourceLine.line - LINES);
+    const from = Math.max(1, firstSourceLine.line - LINES_TO_LOAD);
     Promise.all([
-      this.propsLoadSources(
-        this.props.component,
-        from,
-        firstSourceLine.line - 1,
-        this.props.branchLike
-      ),
+      this.loadSources(this.props.component, from, firstSourceLine.line - 1, this.props.branchLike),
       this.loadIssues(this.props.component, from, firstSourceLine.line - 1, this.props.branchLike)
     ]).then(
       ([sources, issues]) => {
@@ -446,9 +440,9 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
     this.setState({ loadingSourcesAfter: true });
     const fromLine = lastSourceLine.line + 1;
     // request one additional line to define `hasSourcesAfter`
-    const toLine = lastSourceLine.line + LINES + 1;
+    const toLine = lastSourceLine.line + LINES_TO_LOAD + 1;
     Promise.all([
-      this.propsLoadSources(this.props.component, fromLine, toLine, this.props.branchLike),
+      this.loadSources(this.props.component, fromLine, toLine, this.props.branchLike),
       this.loadIssues(this.props.component, fromLine, toLine, this.props.branchLike)
     ]).then(
       ([sources, issues]) => {
@@ -459,15 +453,15 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
               issues: nextIssues,
               issuesByLine: issuesByLine(nextIssues),
               issueLocationsByLine: locationsByLine(nextIssues),
-              hasSourcesAfter: sources.length > LINES,
+              hasSourcesAfter: sources.length > LINES_TO_LOAD,
               loadingSourcesAfter: false,
               sources: [
                 ...(prevState.sources || []),
-                ...this.computeCoverageStatus(sources.slice(0, LINES))
+                ...this.computeCoverageStatus(sources.slice(0, LINES_TO_LOAD))
               ],
               symbolsByLine: {
                 ...prevState.symbolsByLine,
-                ...symbolsByLine(sources.slice(0, LINES))
+                ...symbolsByLine(sources.slice(0, LINES_TO_LOAD))
               }
             };
           });
@@ -688,25 +682,3 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
     );
   }
 }
-
-function defaultLoadComponent(
-  component: string,
-  branchLike: BranchLike | undefined
-): Promise<SourceViewerFile> {
-  return Promise.all([
-    getComponentForSourceViewer({ component, ...getBranchLikeQuery(branchLike) }),
-    getComponentData({ component, ...getBranchLikeQuery(branchLike) })
-  ]).then(([sourceViewerComponent, { component }]) => ({
-    ...sourceViewerComponent,
-    leakPeriodDate: component.leakPeriodDate
-  }));
-}
-
-function defaultLoadSources(
-  key: string,
-  from: number | undefined,
-  to: number | undefined,
-  branchLike: BranchLike | undefined
-) {
-  return getSources({ key, from, to, ...getBranchLikeQuery(branchLike) });
-}
index e3e604671b6cbf609b1c7a29bd89ecf1a9afb53c..dead6b916ac46db10ead7bec7af8c72f4a8ae4d6 100644 (file)
@@ -176,7 +176,7 @@ export default class SourceViewerCode extends React.PureComponent<Props> {
         issueLocations={this.getIssueLocationsForLine(line)}
         issuePopup={this.props.issuePopup}
         issues={issuesForLine}
-        key={line.line}
+        key={line.line || line.code}
         last={index === this.props.sources.length - 1 && !this.props.hasSourcesAfter}
         line={line}
         loadDuplications={this.props.loadDuplications}
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewer-it.tsx
new file mode 100644 (file)
index 0000000..257c881
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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 { queryHelpers, screen, within } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import * as React from 'react';
+import { SourceViewerServiceMock } from '../../../api/mocks/SourceViewerServiceMock';
+import { mockIssue } from '../../../helpers/testMocks';
+import { renderComponent } from '../../../helpers/testReactTestingUtils';
+import SourceViewer from '../SourceViewer';
+import SourceViewerBase from '../SourceViewerBase';
+
+jest.mock('../../../api/components');
+jest.mock('../helpers/lines', () => {
+  const lines = jest.requireActual('../helpers/lines');
+  return {
+    ...lines,
+    LINES_TO_LOAD: 20
+  };
+});
+
+jest.setTimeout(30_000);
+const handler = new SourceViewerServiceMock();
+
+it('should show a permalink on line number', async () => {
+  const user = userEvent.setup();
+  renderSourceViewer();
+  let row = await screen.findByRole('row', { name: /\/\*$/ });
+  expect(row).toBeInTheDocument();
+  const rowScreen = within(row);
+  await user.click(
+    rowScreen.getByRole('button', {
+      name: 'source_viewer.line_X.1'
+    })
+  );
+  await user.click(
+    rowScreen.getByRole('link', {
+      name: 'component_viewer.copy_permalink'
+    })
+  );
+
+  expect(
+    /* eslint-disable-next-line testing-library/prefer-presence-queries */
+    queryHelpers.queryByAttribute(
+      'data-clipboard-text',
+      row,
+      'http://localhost/code?id=project&selected=project%3Atest.js&line=1'
+    )
+  ).toBeInTheDocument();
+
+  await user.keyboard('[Escape]');
+
+  expect(
+    /* eslint-disable-next-line testing-library/prefer-presence-queries */
+    queryHelpers.queryByAttribute(
+      'data-clipboard-text',
+      row,
+      'http://localhost/code?id=project&selected=project%3Atest.js&line=1'
+    )
+  ).not.toBeInTheDocument();
+
+  row = await screen.findByRole('row', { name: / \* 6$/ });
+  expect(row).toBeInTheDocument();
+  const lowerRowScreen = within(row);
+  await user.click(
+    lowerRowScreen.getByRole('button', {
+      name: 'source_viewer.line_X.6'
+    })
+  );
+
+  expect(
+    lowerRowScreen.getByRole('link', {
+      name: 'component_viewer.copy_permalink'
+    })
+  ).toBeInTheDocument();
+
+  await user.keyboard('[Escape]');
+});
+
+it('should show issue on empty file', async () => {
+  renderSourceViewer({
+    component: handler.getEmptyFile(),
+    loadIssues: jest.fn().mockResolvedValue([
+      mockIssue(false, {
+        key: 'first-issue',
+        message: 'First Issue',
+        line: undefined,
+        textRange: undefined
+      })
+    ])
+  });
+  expect(await screen.findByRole('table')).toBeInTheDocument();
+  expect(await screen.findByRole('row', { name: 'First Issue' })).toBeInTheDocument();
+});
+
+it('should load line when looking arround unloaded line', async () => {
+  const { rerender } = renderSourceViewer({
+    aroundLine: 50,
+    component: handler.getHugeFile()
+  });
+  expect(await screen.findByRole('row', { name: /Line 50$/ })).toBeInTheDocument();
+  rerender(getSourceViewerUi({ aroundLine: 100, component: handler.getHugeFile() }));
+
+  expect(await screen.findByRole('row', { name: /Line 100$/ })).toBeInTheDocument();
+});
+
+it('should show SCM information', async () => {
+  const user = userEvent.setup();
+  renderSourceViewer();
+  let row = await screen.findByRole('row', { name: /\/\*$/ });
+  expect(row).toBeInTheDocument();
+  const firstRowScreen = within(row);
+  expect(
+    firstRowScreen.getByRole('cell', { name: 'stas.vilchik@sonarsource.com' })
+  ).toBeInTheDocument();
+  await user.click(
+    firstRowScreen.getByRole('button', {
+      name: 'source_viewer.author_X.stas.vilchik@sonarsource.com, source_viewer.click_for_scm_info'
+    })
+  );
+
+  expect(
+    await firstRowScreen.findByRole('heading', { level: 4, name: 'author' })
+  ).toBeInTheDocument();
+  expect(
+    firstRowScreen.getByRole('heading', { level: 4, name: 'source_viewer.tooltip.scm.commited_on' })
+  ).toBeInTheDocument();
+  expect(
+    firstRowScreen.getByRole('heading', { level: 4, name: 'source_viewer.tooltip.scm.revision' })
+  ).toBeInTheDocument();
+
+  row = screen.getByRole('row', { name: /\* SonarQube$/ });
+  expect(row).toBeInTheDocument();
+  const secondRowScreen = within(row);
+  expect(
+    secondRowScreen.queryByRole('cell', { name: 'stas.vilchik@sonarsource.com' })
+  ).not.toBeInTheDocument();
+
+  // SCM with no date
+  row = await screen.findByRole('row', { name: /\* mailto:info AT sonarsource DOT com$/ });
+  expect(row).toBeInTheDocument();
+  const thirdRowScreen = within(row);
+  await user.click(
+    thirdRowScreen.getByRole('button', {
+      name: 'source_viewer.author_X.stas.vilchik@sonarsource.com, source_viewer.click_for_scm_info'
+    })
+  );
+
+  expect(
+    await thirdRowScreen.findByRole('heading', { level: 4, name: 'author' })
+  ).toBeInTheDocument();
+  expect(
+    thirdRowScreen.queryByRole('heading', {
+      level: 4,
+      name: 'source_viewer.tooltip.scm.commited_on'
+    })
+  ).not.toBeInTheDocument();
+  expect(
+    thirdRowScreen.getByRole('heading', { level: 4, name: 'source_viewer.tooltip.scm.revision' })
+  ).toBeInTheDocument();
+
+  // SCM with no date no author
+  row = await screen.findByRole('row', { name: /\* 5$/ });
+  expect(row).toBeInTheDocument();
+  const fourthRowScreen = within(row);
+  expect(fourthRowScreen.getByText('…')).toBeInTheDocument();
+  await user.click(
+    fourthRowScreen.getByRole('button', {
+      name: 'source_viewer.click_for_scm_info'
+    })
+  );
+
+  expect(
+    fourthRowScreen.queryByRole('heading', { level: 4, name: 'author' })
+  ).not.toBeInTheDocument();
+  expect(
+    fourthRowScreen.queryByRole('heading', {
+      level: 4,
+      name: 'source_viewer.tooltip.scm.commited_on'
+    })
+  ).not.toBeInTheDocument();
+  expect(
+    fourthRowScreen.getByRole('heading', { level: 4, name: 'source_viewer.tooltip.scm.revision' })
+  ).toBeInTheDocument();
+
+  // No SCM Popup
+  row = await screen.findByRole('row', {
+    name: /\* This program is free software; you can redistribute it and\/or$/
+  });
+  expect(row).toBeInTheDocument();
+  expect(within(row).queryByRole('button')).not.toBeInTheDocument();
+});
+
+it('should show issue indicator', async () => {
+  const user = userEvent.setup();
+  const onIssueSelect = jest.fn();
+  renderSourceViewer({
+    onIssueSelect,
+    displayAllIssues: false,
+    loadIssues: jest.fn().mockResolvedValue([
+      mockIssue(false, {
+        key: 'first-issue',
+        message: 'First Issue',
+        line: 1,
+        textRange: { startLine: 1, endLine: 1, startOffset: 0, endOffset: 1 }
+      }),
+      mockIssue(false, {
+        key: 'second-issue',
+        message: 'Second Issue',
+        line: 1,
+        textRange: { startLine: 1, endLine: 1, startOffset: 1, endOffset: 2 }
+      })
+    ])
+  });
+  const row = await screen.findByRole('row', { name: /.*\/ \*$/ });
+  const issueRow = within(row);
+  expect(issueRow.getByText('2')).toBeInTheDocument();
+  await user.click(issueRow.getByRole('button', { name: 'source_viewer.issues_on_line.show' }));
+  const firstIssueBox = issueRow.getByRole('region', { name: 'First Issue' });
+  const secondIssueBox = issueRow.getByRole('region', { name: 'Second Issue' });
+  expect(firstIssueBox).toBeInTheDocument();
+  expect(secondIssueBox).toBeInTheDocument();
+
+  await user.click(firstIssueBox);
+  expect(onIssueSelect).toBeCalledWith('first-issue');
+
+  await user.click(secondIssueBox);
+  expect(onIssueSelect).toBeCalledWith('second-issue');
+});
+
+it('should show coverage information', async () => {
+  renderSourceViewer();
+  const coverdLine = within(
+    await screen.findByRole('row', { name: /\* mailto:info AT sonarsource DOT com$/ })
+  );
+  expect(
+    coverdLine.getByLabelText('source_viewer.tooltip.covered.conditions.1')
+  ).toBeInTheDocument();
+
+  const partialyCoveredWithConditionLine = within(
+    await screen.findByRole('row', { name: / \* 5$/ })
+  );
+  expect(
+    partialyCoveredWithConditionLine.getByLabelText(
+      'source_viewer.tooltip.partially-covered.conditions.1.2'
+    )
+  ).toBeInTheDocument();
+
+  const partialyCoveredLine = within(await screen.findByRole('row', { name: /\/\*$/ }));
+  expect(
+    partialyCoveredLine.getByLabelText('source_viewer.tooltip.partially-covered')
+  ).toBeInTheDocument();
+
+  const uncoveredLine = within(await screen.findByRole('row', { name: / \* 6$/ }));
+  expect(uncoveredLine.getByLabelText('source_viewer.tooltip.uncovered')).toBeInTheDocument();
+
+  const uncoveredWithConditionLine = within(
+    await screen.findByRole('row', { name: / \* SonarQube$/ })
+  );
+  expect(
+    uncoveredWithConditionLine.getByLabelText('source_viewer.tooltip.uncovered.conditions.1')
+  ).toBeInTheDocument();
+
+  const coveredWithNoCondition = within(await screen.findByRole('row', { name: /\* Copyright$/ }));
+  expect(
+    coveredWithNoCondition.getByLabelText('source_viewer.tooltip.covered')
+  ).toBeInTheDocument();
+});
+
+it('should show duplication block', async () => {
+  const user = userEvent.setup();
+  renderSourceViewer();
+  const duplicateLine = within(await screen.findByRole('row', { name: /\* 7$/ }));
+  expect(
+    duplicateLine.getByLabelText('source_viewer.tooltip.duplicated_block')
+  ).toBeInTheDocument();
+
+  await user.click(
+    duplicateLine.getByRole('button', { name: 'source_viewer.tooltip.duplicated_block' })
+  );
+
+  expect(duplicateLine.getAllByRole('link', { name: 'test2.js' })[0]).toBeInTheDocument();
+  await user.keyboard('[Escape]');
+  expect(duplicateLine.queryByRole('link', { name: 'test2.js' })).not.toBeInTheDocument();
+});
+
+function renderSourceViewer(override?: Partial<SourceViewerBase['props']>) {
+  return renderComponent(getSourceViewerUi(override));
+}
+
+function getSourceViewerUi(override?: Partial<SourceViewerBase['props']>) {
+  return (
+    <SourceViewer
+      aroundLine={1}
+      branchLike={undefined}
+      component={handler.getFileWithSource()}
+      displayAllIssues={true}
+      displayIssueLocationsCount={true}
+      displayIssueLocationsLink={false}
+      displayLocationMarkers={true}
+      loadIssues={jest.fn().mockResolvedValue([])}
+      onIssueChange={jest.fn()}
+      onIssueSelect={jest.fn()}
+      onLoaded={jest.fn()}
+      onLocationSelect={jest.fn()}
+      scroll={jest.fn()}
+      slimHeader={true}
+      {...override}
+    />
+  );
+}
index 4c24a5c981984158ab5805aadf3d0573a5c2f72d..75a56e77b15a80be5df4228d4829e01318eb4900 100644 (file)
@@ -57,16 +57,12 @@ it('should render correctly', async () => {
 });
 
 it('should use load props if provided', () => {
-  const loadComponent = jest.fn().mockResolvedValue({});
   const loadIssues = jest.fn().mockResolvedValue([]);
-  const loadSources = jest.fn().mockResolvedValue([]);
   const wrapper = shallowRender({
-    loadComponent,
-    loadIssues,
-    loadSources
+    loadIssues
   });
 
-  expect(wrapper.instance().loadComponent).toBe(loadComponent);
+  expect(wrapper.instance().loadIssues).toBe(loadIssues);
 });
 
 it('should reload', async () => {
index e51a763b9df8f2c1aba39ec731389487cda3dce3..df85f4381f596d5fc5a1107247feded032f8c9e8 100644 (file)
@@ -25,19 +25,6 @@ import { MetricKey } from '../../../types/metrics';
 import Line from '../components/Line';
 import SourceViewerCode from '../SourceViewerCode';
 
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(shallowRender({ issues: [mockIssue(false, { textRange: undefined })] })).toMatchSnapshot(
-    'has file level issues'
-  );
-  expect(shallowRender({ hasSourcesAfter: true, hasSourcesBefore: true })).toMatchSnapshot(
-    'has more sources'
-  );
-  expect(
-    shallowRender({ sources: [], issues: [mockIssue(false, { textRange: undefined })] })
-  ).toMatchSnapshot('only file issues');
-});
-
 it('should correctly flag a line for scrolling', () => {
   const sources = [
     mockSourceLine({ line: 1, coverageStatus: 'covered', isNew: false }),
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerCode-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerCode-test.tsx.snap
deleted file mode 100644 (file)
index cc589e8..0000000
+++ /dev/null
@@ -1,669 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<div
-  className="source-viewer-code"
->
-  <table
-    className="source-table"
-  >
-    <tbody>
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={false}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={false}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        previousLine={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={true}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        previousLine={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-    </tbody>
-  </table>
-</div>
-`;
-
-exports[`should render correctly: has file level issues 1`] = `
-<div
-  className="source-viewer-code"
->
-  <table
-    className="source-table"
-  >
-    <tbody>
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="0"
-        last={false}
-        line={
-          Object {
-            "code": "",
-            "duplicated": false,
-            "isNew": false,
-            "line": 0,
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={false}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={false}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        previousLine={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={true}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        previousLine={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-    </tbody>
-  </table>
-</div>
-`;
-
-exports[`should render correctly: has more sources 1`] = `
-<div
-  className="source-viewer-code"
->
-  <div
-    className="source-viewer-more-code"
-  >
-    <Button
-      className="js-component-viewer-source-before"
-      onClick={[MockFunction]}
-    >
-      source_viewer.load_more_code
-    </Button>
-  </div>
-  <table
-    className="source-table"
-  >
-    <tbody>
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={false}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={false}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        previousLine={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={true}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={true}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={16}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="16"
-        last={false}
-        line={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        previousLine={
-          Object {
-            "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-            "coverageStatus": "covered",
-            "coveredConditions": 2,
-            "duplicated": false,
-            "isNew": true,
-            "line": 16,
-            "scmAuthor": "simon.brandhof@sonarsource.com",
-            "scmDate": "2018-12-11T10:48:39+0100",
-            "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-          }
-        }
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-    </tbody>
-  </table>
-  <div
-    className="source-viewer-more-code"
-  >
-    <Button
-      className="js-component-viewer-source-after"
-      onClick={[MockFunction]}
-    >
-      source_viewer.load_more_code
-    </Button>
-  </div>
-</div>
-`;
-
-exports[`should render correctly: only file issues 1`] = `
-<div
-  className="source-viewer-code"
->
-  <table
-    className="source-table"
-  >
-    <tbody>
-      <Line
-        branchLike={
-          Object {
-            "analysisDate": "2018-01-01",
-            "excludedFromPurge": true,
-            "isMain": false,
-            "name": "branch-6.7",
-          }
-        }
-        displayCoverage={false}
-        displayDuplications={false}
-        displayIssues={true}
-        displaySCM={false}
-        duplications={Array []}
-        duplicationsCount={0}
-        firstLineNumber={0}
-        highlighted={false}
-        issueLocations={Array []}
-        issues={Array []}
-        key="0"
-        last={true}
-        line={
-          Object {
-            "code": "",
-            "duplicated": false,
-            "isNew": false,
-            "line": 0,
-          }
-        }
-        loadDuplications={[MockFunction]}
-        onIssueChange={[MockFunction]}
-        onIssuePopupToggle={[MockFunction]}
-        onIssueSelect={[MockFunction]}
-        onIssueUnselect={[MockFunction]}
-        onIssuesClose={[MockFunction]}
-        onIssuesOpen={[MockFunction]}
-        onLocationSelect={[MockFunction]}
-        onSymbolClick={[MockFunction]}
-        openIssues={false}
-        renderDuplicationPopup={[MockFunction]}
-        scrollToUncoveredLine={false}
-        secondaryIssueLocations={Array []}
-      />
-    </tbody>
-  </table>
-</div>
-`;
index 590160f141b1eb5bf485967fdd8cfb3c674d2004..29df74831bda15e82b4dd0d02b04c374dbbe7c17 100644 (file)
@@ -135,7 +135,6 @@ export default class Line extends React.PureComponent<Props> {
 
     // default is true
     const displayOptions = displayLineNumberOptions !== false;
-
     return (
       <tr className={className} data-line-number={line.line}>
         <LineNumber displayOptions={displayOptions} firstLineNumber={firstLineNumber} line={line} />
index 48a39e73de023397edde8b20cb0d065a336186ea..713f02a6c066afb0bfbc91f09f62202e82d914c9 100644 (file)
@@ -55,13 +55,12 @@ export function LineSCM({ line, previousLine }: LineSCMProps) {
         </Dropdown>
       </td>
     );
-  } else {
-    return (
-      <td className="source-meta source-line-scm" data-line-number={line.line}>
-        {cell}
-      </td>
-    );
   }
+  return (
+    <td className="source-meta source-line-scm" data-line-number={line.line}>
+      {cell}
+    </td>
+  );
 }
 
 function isSCMChanged(s: SourceLine, p: SourceLine | undefined) {
index 3576622165773fa1386abc35823717a6dded94f4..e16954906d842b69d3a0ff050b2afe77b6a3dc6f 100644 (file)
@@ -23,11 +23,6 @@ import { mockPullRequest } from '../../../../helpers/mocks/branch-like';
 import { mockIssue, mockSourceLine } from '../../../../helpers/testMocks';
 import Line from '../Line';
 
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot();
-  expect(shallowRender({ displaySCM: false })).toMatchSnapshot('no SCM');
-});
-
 it('should render correctly for last, new, and highlighted lines', () => {
   expect(
     shallowRender({
@@ -38,27 +33,6 @@ it('should render correctly for last, new, and highlighted lines', () => {
   ).toMatchSnapshot();
 });
 
-it('should render correctly with coverage', () => {
-  expect(
-    shallowRender({
-      displayCoverage: true
-    })
-  ).toMatchSnapshot();
-});
-
-it('should render correctly with duplication information', () => {
-  expect(
-    shallowRender({
-      displayDuplications: true,
-      duplicationsCount: 3
-    })
-  ).toMatchSnapshot();
-});
-
-it('should render correctly with issues info', () => {
-  expect(shallowRender({ displayIssues: true })).toMatchSnapshot();
-});
-
 it('handles the opening and closing of issues', () => {
   const line = mockSourceLine();
   const issue = mockIssue();
index 7d598977245215e8f87a119b67855cded4ef4c12..68bb9399d3fa8ab0b11bb6ca7cb0f77f12af28ac 100644 (file)
@@ -29,22 +29,6 @@ jest.mock('react', () => {
   };
 });
 
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('covered');
-  expect(shallowRender({ line: { line: 3, coverageStatus: 'uncovered' } })).toMatchSnapshot(
-    'uncovered'
-  );
-  expect(shallowRender({ line: { line: 3, coverageStatus: 'partially-covered' } })).toMatchSnapshot(
-    'partially covered, 0 conditions'
-  );
-  expect(
-    shallowRender({ line: { line: 3, coverageStatus: 'partially-covered', coveredConditions: 10 } })
-  ).toMatchSnapshot('partially covered, 10 conditions');
-  expect(shallowRender({ line: { line: 3, coverageStatus: undefined } })).toMatchSnapshot(
-    'no data'
-  );
-});
-
 it('should correctly trigger a scroll', () => {
   const element = { current: {} };
   (React.useEffect as jest.Mock).mockImplementation(f => f());
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplicationBlock-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplicationBlock-test.tsx
deleted file mode 100644 (file)
index c307a62..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import Toggler from '../../../../components/controls/Toggler';
-import { click } from '../../../../helpers/testUtils';
-import { LineDuplicationBlock, LineDuplicationBlockProps } from '../LineDuplicationBlock';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(
-    shallowRender({ line: { line: 3, duplicated: false }, duplicated: false })
-  ).toMatchSnapshot('not duplicated');
-});
-
-it('should correctly open/close the dropdown', () => {
-  const wrapper = shallowRender();
-  click(wrapper.find('div[role="button"]'));
-  expect(wrapper.find(Toggler).prop('open')).toBe(true);
-  wrapper.find(Toggler).prop('onRequestClose')();
-  expect(wrapper.find(Toggler).prop('open')).toBe(false);
-});
-
-it('should correctly call the onCick prop', () => {
-  const line = { line: 1, duplicated: true };
-  const onClick = jest.fn();
-  const wrapper = shallowRender({ line, onClick });
-
-  // Propagate if blocks aren't loaded.
-  click(wrapper.find('div[role="button"]'));
-  expect(onClick).toBeCalledWith(line);
-
-  // Don't propagate if blocks were loaded.
-  onClick.mockClear();
-  wrapper.setProps({ blocksLoaded: true });
-  click(wrapper.find('div[role="button"]'));
-  expect(onClick).not.toBeCalled();
-});
-
-function shallowRender(props: Partial<LineDuplicationBlockProps> = {}) {
-  return shallow<LineDuplicationBlockProps>(
-    <LineDuplicationBlock
-      blocksLoaded={false}
-      duplicated={true}
-      index={1}
-      line={{ line: 3, duplicated: true }}
-      renderDuplicationPopup={jest.fn()}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesList-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesList-test.tsx
deleted file mode 100644 (file)
index 9b968b2..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { Issue } from '../../../../types/types';
-import LineIssuesList from '../LineIssuesList';
-
-const issueBase: Issue = {
-  actions: [],
-  component: '',
-  componentLongName: '',
-  componentQualifier: '',
-  componentUuid: '',
-  creationDate: '',
-  key: '',
-  flows: [],
-  fromHotspot: false,
-  message: '',
-  project: '',
-  projectName: '',
-  projectKey: '',
-  rule: '',
-  ruleName: '',
-  secondaryLocations: [],
-  severity: '',
-  status: '',
-  transitions: [],
-  type: 'BUG'
-};
-
-it('render issues list', () => {
-  const issues: Issue[] = [
-    { ...issueBase, key: 'foo' },
-    { ...issueBase, key: 'bar' }
-  ];
-  const onIssueClick = jest.fn();
-  const wrapper = shallow(
-    <LineIssuesList
-      branchLike={undefined}
-      issuePopup={undefined}
-      issues={issues}
-      onIssueChange={jest.fn()}
-      onIssueClick={onIssueClick}
-      onIssuePopupToggle={jest.fn()}
-      selectedIssue="foo"
-    />
-  );
-  expect(wrapper).toMatchSnapshot();
-});
index 4581194ff941c30f3bce64ccc7f04de40d78706b..9cdf83ba7c9f2bae2a3f668a417035606cf35e93 100644 (file)
@@ -22,9 +22,6 @@ import * as React from 'react';
 import { LineNumber, LineNumberProps } from '../LineNumber';
 
 it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(shallowRender({ line: { line: 0 } })).toMatchSnapshot('no line number');
-  expect(shallowRender({ line: { line: 12 } })).toMatchSnapshot('first line');
   expect(shallowRender({ displayOptions: false, line: { line: 12 } })).toMatchSnapshot(
     'no options'
   );
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineOptionsPopup-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineOptionsPopup-test.tsx
deleted file mode 100644 (file)
index ae20a16..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { mockBranch } from '../../../../helpers/mocks/branch-like';
-import { mockSourceLine } from '../../../../helpers/testMocks';
-import { LineOptionsPopup, LineOptionsPopupProps } from '../LineOptionsPopup';
-
-jest.mock('../../SourceViewerContext', () => ({
-  SourceViewerContext: {
-    Consumer: (props: any) =>
-      props.children({
-        branchLike: mockBranch({ name: 'feature' }),
-        file: { project: 'prj', key: 'foo' }
-      })
-  }
-}));
-
-it('should render correctly', () => {
-  expect(shallowRender({ line: { line: 10 } }).dive()).toMatchSnapshot();
-  expect(shallowRender({ line: { line: 2 } }).dive()).toMatchSnapshot('first line');
-});
-
-function shallowRender(props: Partial<LineOptionsPopupProps> = {}) {
-  return shallow(<LineOptionsPopup firstLineNumber={1} line={mockSourceLine()} {...props} />);
-}
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineSCM-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineSCM-test.tsx
deleted file mode 100644 (file)
index 4e44db6..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { LineSCM, LineSCMProps } from '../LineSCM';
-
-it('should render correctly', () => {
-  const scmInfo = { scmRevision: 'foo', scmAuthor: 'foo', scmDate: '2017-01-01' };
-
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(
-    shallowRender({ line: { line: 3, ...scmInfo }, previousLine: { line: 2, ...scmInfo } })
-  ).toMatchSnapshot('same commit');
-  expect(shallowRender({ line: { line: 3, scmDate: '2017-01-01' } })).toMatchSnapshot('no author');
-});
-
-function shallowRender(props: Partial<LineSCMProps> = {}) {
-  return shallow(
-    <LineSCM
-      line={{ line: 3, scmAuthor: 'foo', scmDate: '2017-01-01' }}
-      previousLine={{ line: 2, scmAuthor: 'bar', scmDate: '2017-01-02' }}
-      {...props}
-    />
-  );
-}
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/SCMPopup-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/SCMPopup-test.tsx
deleted file mode 100644 (file)
index 121f9a4..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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 { shallow } from 'enzyme';
-import * as React from 'react';
-import { SCMPopup, SCMPopupProps } from '../SCMPopup';
-
-it('should render correctly', () => {
-  expect(shallowRender()).toMatchSnapshot('default');
-  expect(
-    shallowRender({ line: { line: 3, scmDate: '2017-01-01', scmRevision: 'bar' } })
-  ).toMatchSnapshot('no author');
-  expect(
-    shallowRender({ line: { line: 3, scmAuthor: 'foo', scmRevision: 'bar' } })
-  ).toMatchSnapshot('no date');
-  expect(
-    shallowRender({ line: { line: 3, scmAuthor: 'foo', scmDate: '2017-01-01' } })
-  ).toMatchSnapshot('no revision');
-});
-
-function shallowRender(props: Partial<SCMPopupProps> = {}) {
-  return shallow(
-    <SCMPopup
-      line={{ line: 3, scmAuthor: 'foo', scmDate: '2017-01-01', scmRevision: 'bar' }}
-      {...props}
-    />
-  );
-}
index 13ea52d94d85c5c15252e84ffe4e462537f30edd..e916b9827dbc7aea5b196c76db57a0148535ce07 100644 (file)
@@ -1,145 +1,5 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should render correctly 1`] = `
-<tr
-  className="source-line source-line-filtered"
-  data-line-number={16}
->
-  <Memo(LineNumber)
-    displayOptions={true}
-    firstLineNumber={1}
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <Memo(LineSCM)
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <td
-    className="source-meta source-line-issues"
-  />
-  <LineCode
-    branchLike={
-      Object {
-        "analysisDate": "2018-01-01",
-        "base": "master",
-        "branch": "feature/foo/bar",
-        "key": "1001",
-        "target": "master",
-        "title": "Foo Bar feature",
-      }
-    }
-    displayLocationMarkers={false}
-    issueLocations={Array []}
-    issues={
-      Array [
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "BUG",
-        },
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "VULNERABILITY",
-        },
-      ]
-    }
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "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}
-  />
-</tr>
-`;
-
 exports[`should render correctly for last, new, and highlighted lines 1`] = `
 <tr
   className="source-line source-line-highlighted source-line-filtered source-line-last"
@@ -279,701 +139,3 @@ exports[`should render correctly for last, new, and highlighted lines 1`] = `
   />
 </tr>
 `;
-
-exports[`should render correctly with coverage 1`] = `
-<tr
-  className="source-line source-line-filtered"
-  data-line-number={16}
->
-  <Memo(LineNumber)
-    displayOptions={true}
-    firstLineNumber={1}
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <Memo(LineSCM)
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <td
-    className="source-meta source-line-issues"
-  />
-  <Memo(LineCoverage)
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-    scroll={[MockFunction]}
-  />
-  <LineCode
-    branchLike={
-      Object {
-        "analysisDate": "2018-01-01",
-        "base": "master",
-        "branch": "feature/foo/bar",
-        "key": "1001",
-        "target": "master",
-        "title": "Foo Bar feature",
-      }
-    }
-    displayLocationMarkers={false}
-    issueLocations={Array []}
-    issues={
-      Array [
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "BUG",
-        },
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "VULNERABILITY",
-        },
-      ]
-    }
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "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}
-  />
-</tr>
-`;
-
-exports[`should render correctly with duplication information 1`] = `
-<tr
-  className="source-line source-line-filtered"
-  data-line-number={16}
->
-  <Memo(LineNumber)
-    displayOptions={true}
-    firstLineNumber={1}
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <Memo(LineSCM)
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <td
-    className="source-meta source-line-issues"
-  />
-  <Memo(LineDuplicationBlock)
-    blocksLoaded={true}
-    duplicated={true}
-    index={0}
-    key="0"
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-    onClick={[MockFunction]}
-    renderDuplicationPopup={[MockFunction]}
-  />
-  <Memo(LineDuplicationBlock)
-    blocksLoaded={true}
-    duplicated={false}
-    index={1}
-    key="1"
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-    renderDuplicationPopup={[MockFunction]}
-  />
-  <Memo(LineDuplicationBlock)
-    blocksLoaded={true}
-    duplicated={false}
-    index={2}
-    key="2"
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-    renderDuplicationPopup={[MockFunction]}
-  />
-  <LineCode
-    branchLike={
-      Object {
-        "analysisDate": "2018-01-01",
-        "base": "master",
-        "branch": "feature/foo/bar",
-        "key": "1001",
-        "target": "master",
-        "title": "Foo Bar feature",
-      }
-    }
-    displayLocationMarkers={false}
-    issueLocations={Array []}
-    issues={
-      Array [
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "BUG",
-        },
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "VULNERABILITY",
-        },
-      ]
-    }
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "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}
-  />
-</tr>
-`;
-
-exports[`should render correctly with issues info 1`] = `
-<tr
-  className="source-line source-line-filtered"
-  data-line-number={16}
->
-  <Memo(LineNumber)
-    displayOptions={true}
-    firstLineNumber={1}
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <Memo(LineSCM)
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <Memo(LineIssuesIndicator)
-    issues={
-      Array [
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "BUG",
-        },
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "VULNERABILITY",
-        },
-      ]
-    }
-    issuesOpen={false}
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-    onClick={[Function]}
-  />
-  <LineCode
-    branchLike={
-      Object {
-        "analysisDate": "2018-01-01",
-        "base": "master",
-        "branch": "feature/foo/bar",
-        "key": "1001",
-        "target": "master",
-        "title": "Foo Bar feature",
-      }
-    }
-    displayLocationMarkers={false}
-    issueLocations={Array []}
-    issues={
-      Array [
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "BUG",
-        },
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "VULNERABILITY",
-        },
-      ]
-    }
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "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}
-  />
-</tr>
-`;
-
-exports[`should render correctly: no SCM 1`] = `
-<tr
-  className="source-line source-line-filtered"
-  data-line-number={16}
->
-  <Memo(LineNumber)
-    displayOptions={true}
-    firstLineNumber={1}
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "coverageStatus": "covered",
-        "coveredConditions": 2,
-        "duplicated": false,
-        "isNew": true,
-        "line": 16,
-        "scmAuthor": "simon.brandhof@sonarsource.com",
-        "scmDate": "2018-12-11T10:48:39+0100",
-        "scmRevision": "80f564becc0c0a1c9abaa006eca83a4fd278c3f0",
-      }
-    }
-  />
-  <td
-    className="source-meta source-line-issues"
-  />
-  <LineCode
-    branchLike={
-      Object {
-        "analysisDate": "2018-01-01",
-        "base": "master",
-        "branch": "feature/foo/bar",
-        "key": "1001",
-        "target": "master",
-        "title": "Foo Bar feature",
-      }
-    }
-    displayLocationMarkers={false}
-    issueLocations={Array []}
-    issues={
-      Array [
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "BUG",
-        },
-        Object {
-          "actions": Array [],
-          "component": "main.js",
-          "componentLongName": "main.js",
-          "componentQualifier": "FIL",
-          "componentUuid": "foo1234",
-          "creationDate": "2017-03-01T09:36:01+0100",
-          "flows": Array [],
-          "fromHotspot": false,
-          "key": "AVsae-CQS-9G3txfbFN2",
-          "line": 25,
-          "message": "Reduce the number of conditional operators (4) used in the expression",
-          "project": "myproject",
-          "projectKey": "foo",
-          "projectName": "Foo",
-          "rule": "javascript:S1067",
-          "ruleName": "foo",
-          "secondaryLocations": Array [],
-          "severity": "MAJOR",
-          "status": "OPEN",
-          "textRange": Object {
-            "endLine": 26,
-            "endOffset": 15,
-            "startLine": 25,
-            "startOffset": 0,
-          },
-          "transitions": Array [],
-          "type": "VULNERABILITY",
-        },
-      ]
-    }
-    line={
-      Object {
-        "code": "<span class=\\"k\\">import</span> java.util.<span class=\\"sym-9 sym\\">ArrayList</span>;",
-        "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}
-  />
-</tr>
-`;
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineCoverage-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineCoverage-test.tsx.snap
deleted file mode 100644 (file)
index f145547..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: covered 1`] = `
-<td
-  className="source-meta source-line-coverage source-line-covered"
-  data-line-number={3}
->
-  <Tooltip
-    overlay="source_viewer.tooltip.covered"
-    placement="bottom"
-  >
-    <div
-      aria-label="source_viewer.tooltip.covered"
-      className="source-line-bar"
-    />
-  </Tooltip>
-</td>
-`;
-
-exports[`should render correctly: no data 1`] = `
-<td
-  className="source-meta source-line-coverage"
-  data-line-number={3}
->
-  <Tooltip
-    placement="bottom"
-  >
-    <div
-      className="source-line-bar"
-    />
-  </Tooltip>
-</td>
-`;
-
-exports[`should render correctly: partially covered, 0 conditions 1`] = `
-<td
-  className="source-meta source-line-coverage source-line-partially-covered"
-  data-line-number={3}
->
-  <Tooltip
-    overlay="source_viewer.tooltip.partially-covered"
-    placement="bottom"
-  >
-    <div
-      aria-label="source_viewer.tooltip.partially-covered"
-      className="source-line-bar"
-    />
-  </Tooltip>
-</td>
-`;
-
-exports[`should render correctly: partially covered, 10 conditions 1`] = `
-<td
-  className="source-meta source-line-coverage source-line-partially-covered"
-  data-line-number={3}
->
-  <Tooltip
-    overlay="source_viewer.tooltip.partially-covered"
-    placement="bottom"
-  >
-    <div
-      aria-label="source_viewer.tooltip.partially-covered"
-      className="source-line-bar"
-    />
-  </Tooltip>
-</td>
-`;
-
-exports[`should render correctly: uncovered 1`] = `
-<td
-  className="source-meta source-line-coverage source-line-uncovered"
-  data-line-number={3}
->
-  <Tooltip
-    overlay="source_viewer.tooltip.uncovered"
-    placement="bottom"
-  >
-    <div
-      aria-label="source_viewer.tooltip.uncovered"
-      className="source-line-bar"
-    />
-  </Tooltip>
-</td>
-`;
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineDuplicationBlock-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineDuplicationBlock-test.tsx.snap
deleted file mode 100644 (file)
index 2be051a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<td
-  className="source-meta source-line-duplications source-line-duplicated"
-  data-index={1}
-  data-line-number={3}
->
-  <Tooltip
-    overlay="source_viewer.tooltip.duplicated_block"
-    placement="right"
-  >
-    <div>
-      <Toggler
-        onRequestClose={[Function]}
-        open={false}
-        overlay={
-          <DropdownOverlay
-            placement="right-top"
-          />
-        }
-      >
-        <div
-          aria-label="source_viewer.tooltip.duplicated_block"
-          className="source-line-bar"
-          onClick={[Function]}
-          role="button"
-          tabIndex={0}
-        />
-      </Toggler>
-    </div>
-  </Tooltip>
-</td>
-`;
-
-exports[`should render correctly: not duplicated 1`] = `
-<td
-  className="source-meta source-line-duplications"
-  data-index={1}
-  data-line-number={3}
->
-  <div
-    className="source-line-bar"
-  />
-</td>
-`;
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssuesList-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineIssuesList-test.tsx.snap
deleted file mode 100644 (file)
index a5ed57f..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`render issues list 1`] = `
-<div
-  className="issue-list"
->
-  <Issue
-    issue={
-      Object {
-        "actions": Array [],
-        "component": "",
-        "componentLongName": "",
-        "componentQualifier": "",
-        "componentUuid": "",
-        "creationDate": "",
-        "flows": Array [],
-        "fromHotspot": false,
-        "key": "foo",
-        "message": "",
-        "project": "",
-        "projectKey": "",
-        "projectName": "",
-        "rule": "",
-        "ruleName": "",
-        "secondaryLocations": Array [],
-        "severity": "",
-        "status": "",
-        "transitions": Array [],
-        "type": "BUG",
-      }
-    }
-    key="foo"
-    onChange={[MockFunction]}
-    onClick={[MockFunction]}
-    onPopupToggle={[MockFunction]}
-    selected={true}
-  />
-  <Issue
-    issue={
-      Object {
-        "actions": Array [],
-        "component": "",
-        "componentLongName": "",
-        "componentQualifier": "",
-        "componentUuid": "",
-        "creationDate": "",
-        "flows": Array [],
-        "fromHotspot": false,
-        "key": "bar",
-        "message": "",
-        "project": "",
-        "projectKey": "",
-        "projectName": "",
-        "rule": "",
-        "ruleName": "",
-        "secondaryLocations": Array [],
-        "severity": "",
-        "status": "",
-        "transitions": Array [],
-        "type": "BUG",
-      }
-    }
-    key="bar"
-    onChange={[MockFunction]}
-    onClick={[MockFunction]}
-    onPopupToggle={[MockFunction]}
-    selected={false}
-  />
-</div>
-`;
index 553567189c892f3e43b0388ec862f8e483346b58..4d1071f9d80972dc498bbfd4875d9638a0d47544 100644 (file)
@@ -1,79 +1,5 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`should render correctly: default 1`] = `
-<td
-  className="source-meta source-line-number"
-  data-line-number={20}
->
-  <Toggler
-    closeOnClickOutside={true}
-    onRequestClose={[Function]}
-    open={false}
-    overlay={
-      <Memo(LineOptionsPopup)
-        firstLineNumber={10}
-        line={
-          Object {
-            "line": 20,
-          }
-        }
-      />
-    }
-  >
-    <span
-      aria-expanded={false}
-      aria-haspopup={true}
-      aria-label="source_viewer.line_X.20"
-      onClick={[Function]}
-      role="button"
-      tabIndex={0}
-    >
-      20
-    </span>
-  </Toggler>
-</td>
-`;
-
-exports[`should render correctly: first line 1`] = `
-<td
-  className="source-meta source-line-number"
-  data-line-number={12}
->
-  <Toggler
-    closeOnClickOutside={true}
-    onRequestClose={[Function]}
-    open={false}
-    overlay={
-      <Memo(LineOptionsPopup)
-        firstLineNumber={10}
-        line={
-          Object {
-            "line": 12,
-          }
-        }
-      />
-    }
-  >
-    <span
-      aria-expanded={false}
-      aria-haspopup={true}
-      aria-label="source_viewer.line_X.12"
-      onClick={[Function]}
-      role="button"
-      tabIndex={0}
-    >
-      12
-    </span>
-  </Toggler>
-</td>
-`;
-
-exports[`should render correctly: no line number 1`] = `
-<td
-  className="source-meta source-line-number"
-/>
-`;
-
 exports[`should render correctly: no options 1`] = `
 <td
   className="source-meta source-line-number"
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineOptionsPopup-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineOptionsPopup-test.tsx.snap
deleted file mode 100644 (file)
index 76fe0f1..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<DropdownOverlay
-  className="big-spacer-left"
-  noPadding={true}
-  placement="top-left"
->
-  <ul
-    className="padded source-viewer-bubble-popup nowrap"
-  >
-    <ActionsDropdownItem
-      copyValue="http://localhost/code?id=prj&branch=feature&selected=foo&line=10"
-    >
-      component_viewer.copy_permalink
-    </ActionsDropdownItem>
-  </ul>
-</DropdownOverlay>
-`;
-
-exports[`should render correctly: first line 1`] = `
-<DropdownOverlay
-  className="big-spacer-left"
-  noPadding={true}
-  placement="bottom-left"
->
-  <ul
-    className="padded source-viewer-bubble-popup nowrap"
-  >
-    <ActionsDropdownItem
-      copyValue="http://localhost/code?id=prj&branch=feature&selected=foo&line=2"
-    >
-      component_viewer.copy_permalink
-    </ActionsDropdownItem>
-  </ul>
-</DropdownOverlay>
-`;
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineSCM-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/LineSCM-test.tsx.snap
deleted file mode 100644 (file)
index 87b8700..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<td
-  className="source-meta source-line-scm"
-  data-line-number={3}
->
-  <Dropdown
-    overlay={
-      <Memo(SCMPopup)
-        line={
-          Object {
-            "line": 3,
-            "scmAuthor": "foo",
-            "scmDate": "2017-01-01",
-          }
-        }
-      />
-    }
-    overlayPlacement="right-top"
-  >
-    <div
-      aria-label="source_viewer.author_X.foo, source_viewer.click_for_scm_info"
-      role="button"
-    >
-      <div
-        className="source-line-scm-inner"
-      >
-        foo
-      </div>
-    </div>
-  </Dropdown>
-</td>
-`;
-
-exports[`should render correctly: no author 1`] = `
-<td
-  className="source-meta source-line-scm"
-  data-line-number={3}
->
-  <Dropdown
-    overlay={
-      <Memo(SCMPopup)
-        line={
-          Object {
-            "line": 3,
-            "scmDate": "2017-01-01",
-          }
-        }
-      />
-    }
-    overlayPlacement="right-top"
-  >
-    <div
-      aria-label="source_viewer.click_for_scm_info"
-      role="button"
-    >
-      <div
-        className="source-line-scm-inner"
-      >
-        …
-      </div>
-    </div>
-  </Dropdown>
-</td>
-`;
-
-exports[`should render correctly: same commit 1`] = `
-<td
-  className="source-meta source-line-scm"
-  data-line-number={3}
->
-  <Dropdown
-    overlay={
-      <Memo(SCMPopup)
-        line={
-          Object {
-            "line": 3,
-            "scmAuthor": "foo",
-            "scmDate": "2017-01-01",
-            "scmRevision": "foo",
-          }
-        }
-      />
-    }
-    overlayPlacement="right-top"
-  >
-    <div
-      aria-label="source_viewer.author_X.foo, source_viewer.click_for_scm_info"
-      role="button"
-    >
-      <div
-        className="source-line-scm-inner"
-      >
-         
-      </div>
-    </div>
-  </Dropdown>
-</td>
-`;
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/SCMPopup-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/__snapshots__/SCMPopup-test.tsx.snap
deleted file mode 100644 (file)
index a05f410..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<div
-  className="source-viewer-bubble-popup abs-width-400"
->
-  <div>
-    <h4>
-      author
-    </h4>
-    foo
-  </div>
-  <div
-    className="spacer-top"
-  >
-    <h4>
-      source_viewer.tooltip.scm.commited_on
-    </h4>
-    <DateFormatter
-      date="2017-01-01"
-    />
-  </div>
-  <div
-    className="spacer-top"
-  >
-    <h4>
-      source_viewer.tooltip.scm.revision
-    </h4>
-    bar
-  </div>
-</div>
-`;
-
-exports[`should render correctly: no author 1`] = `
-<div
-  className="source-viewer-bubble-popup abs-width-400"
->
-  <div
-    className=""
-  >
-    <h4>
-      source_viewer.tooltip.scm.commited_on
-    </h4>
-    <DateFormatter
-      date="2017-01-01"
-    />
-  </div>
-  <div
-    className="spacer-top"
-  >
-    <h4>
-      source_viewer.tooltip.scm.revision
-    </h4>
-    bar
-  </div>
-</div>
-`;
-
-exports[`should render correctly: no date 1`] = `
-<div
-  className="source-viewer-bubble-popup abs-width-400"
->
-  <div>
-    <h4>
-      author
-    </h4>
-    foo
-  </div>
-  <div
-    className="spacer-top"
-  >
-    <h4>
-      source_viewer.tooltip.scm.revision
-    </h4>
-    bar
-  </div>
-</div>
-`;
-
-exports[`should render correctly: no revision 1`] = `
-<div
-  className="source-viewer-bubble-popup abs-width-400"
->
-  <div>
-    <h4>
-      author
-    </h4>
-    foo
-  </div>
-  <div
-    className="spacer-top"
-  >
-    <h4>
-      source_viewer.tooltip.scm.commited_on
-    </h4>
-    <DateFormatter
-      date="2017-01-01"
-    />
-  </div>
-</div>
-`;
index 17ed7b23bc5cb61916d12baf3f6d6db504c4f20f..ac520aca377ca7c4e15c59383a4f37a0bec7e88b 100644 (file)
@@ -20,6 +20,8 @@
 import { intersection } from 'lodash';
 import { Issue, LinearIssueLocation } from '../../../types/types';
 
+export const LINES_TO_LOAD = 500;
+
 export function optimizeHighlightedSymbols(
   symbolsForLine: string[] = [],
   highlightedSymbols: string[] = []
index 550c64fef19c9e97a46f908a3bee2209b6779231..e42903a8c15d10aac4f4af1be2173feefb285ae6 100644 (file)
@@ -79,7 +79,12 @@ export default class IssueView extends React.PureComponent<Props> {
     });
 
     return (
-      <div className={issueClass} data-issue={issue.key} onClick={this.handleClick} role="group">
+      <div
+        className={issueClass}
+        data-issue={issue.key}
+        onClick={this.handleClick}
+        role="region"
+        aria-label={issue.message}>
         <IssueTitleBar
           branchLike={this.props.branchLike}
           currentPopup={this.props.currentPopup}
index a8463a07f3d5ae9ace6728c01570081c2e260f89..2a6454178971556f7c622a175565e02bc3429f81 100644 (file)
@@ -2,10 +2,11 @@
 
 exports[`should render hotspots correctly 1`] = `
 <div
+  aria-label="Reduce the number of conditional operators (4) used in the expression"
   className="issue hotspot selected"
   data-issue="AVsae-CQS-9G3txfbFN2"
   onClick={[Function]}
-  role="group"
+  role="region"
 >
   <IssueTitleBar
     issue={
@@ -82,10 +83,11 @@ exports[`should render hotspots correctly 1`] = `
 
 exports[`should render issues correctly 1`] = `
 <div
+  aria-label="Reduce the number of conditional operators (4) used in the expression"
   className="issue selected"
   data-issue="AVsae-CQS-9G3txfbFN2"
   onClick={[Function]}
-  role="group"
+  role="region"
 >
   <IssueTitleBar
     issue={
index da81b4285eddbd23e6775dcd2e649551c749a271..989783705fbba7a4bf3e8070218df3a0ea368653 100644 (file)
@@ -94,6 +94,18 @@ export function renderAdminApp(
   );
 }
 
+export function renderComponent(component: React.ReactElement) {
+  function Wrapper({ children }: { children: React.ReactElement }) {
+    return (
+      <IntlProvider defaultLocale="en" locale="en">
+        {children}
+      </IntlProvider>
+    );
+  }
+
+  return render(component, { wrapper: Wrapper });
+}
+
 export function renderComponentApp(
   indexPath: string,
   component: RouteComponent,