From c39ab47130cf79261312b7b08afbcb2c79441f9c Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 12 Aug 2020 09:59:44 +0200 Subject: [PATCH] SONAR-12749 DRYer SourceViewerHeader --- .../apps/overview/branches/MeasuresPanel.tsx | 3 +- .../branches/MeasuresPanelIssueMeasureRow.tsx | 2 +- .../MeasuresPanelIssueMeasureRow-test.tsx | 2 +- .../apps/overview/components/IssueLabel.tsx | 3 +- .../apps/overview/components/IssueRating.tsx | 3 +- .../components/__tests__/IssueLabel-test.tsx | 2 +- .../components/__tests__/IssueRating-test.tsx | 2 +- .../pullRequests/PullRequestOverview.tsx | 3 +- .../src/main/js/apps/overview/utils.ts | 60 ++++--------------- .../SourceViewer/SourceViewerHeader.tsx | 13 ++-- .../__tests__/SourceViewerHeader-test.tsx | 9 +-- .../src/main/js/helpers/constants.ts | 9 +-- .../sonar-web/src/main/js/helpers/issues.ts | 41 +++++++++++++ server/sonar-web/src/main/js/types/issues.ts | 26 ++++++++ 14 files changed, 103 insertions(+), 75 deletions(-) create mode 100644 server/sonar-web/src/main/js/types/issues.ts diff --git a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanel.tsx b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanel.tsx index 0dddf9776bb..977153b70ae 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanel.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanel.tsx @@ -27,9 +27,10 @@ import { findMeasure } from '../../../helpers/measures'; import { ApplicationPeriod } from '../../../types/application'; import { BranchLike } from '../../../types/branch-like'; import { ComponentQualifier } from '../../../types/component'; +import { IssueType } from '../../../types/issues'; import { MetricKey } from '../../../types/metrics'; import MeasurementLabel from '../components/MeasurementLabel'; -import { IssueType, MeasurementType } from '../utils'; +import { MeasurementType } from '../utils'; import { DrilldownMeasureValue } from './DrilldownMeasureValue'; import { LeakPeriodInfo } from './LeakPeriodInfo'; import MeasuresPanelIssueMeasureRow from './MeasuresPanelIssueMeasureRow'; diff --git a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelIssueMeasureRow.tsx b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelIssueMeasureRow.tsx index dfe8795ce2c..a1c1d291cd1 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelIssueMeasureRow.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelIssueMeasureRow.tsx @@ -20,9 +20,9 @@ import * as React from 'react'; import { BranchLike } from '../../../types/branch-like'; import { ComponentQualifier } from '../../../types/component'; +import { IssueType } from '../../../types/issues'; import IssueLabel from '../components/IssueLabel'; import IssueRating from '../components/IssueRating'; -import { IssueType } from '../utils'; import DebtValue from './DebtValue'; import SecurityHotspotsReviewed from './SecurityHotspotsReviewed'; diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/MeasuresPanelIssueMeasureRow-test.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/MeasuresPanelIssueMeasureRow-test.tsx index 2503108b0a0..1efc4349978 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/MeasuresPanelIssueMeasureRow-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/MeasuresPanelIssueMeasureRow-test.tsx @@ -22,8 +22,8 @@ import * as React from 'react'; import { mockMainBranch } from '../../../../helpers/mocks/branch-like'; import { mockComponent, mockMeasureEnhanced, mockMetric } from '../../../../helpers/testMocks'; import { ComponentQualifier } from '../../../../types/component'; +import { IssueType } from '../../../../types/issues'; import { MetricKey } from '../../../../types/metrics'; -import { IssueType } from '../../utils'; import MeasuresPanelIssueMeasureRow, { MeasuresPanelIssueMeasureRowProps } from '../MeasuresPanelIssueMeasureRow'; diff --git a/server/sonar-web/src/main/js/apps/overview/components/IssueLabel.tsx b/server/sonar-web/src/main/js/apps/overview/components/IssueLabel.tsx index 89c2405c569..f2c86205aa6 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/IssueLabel.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/IssueLabel.tsx @@ -27,7 +27,8 @@ import { getBranchLikeQuery } from '../../../helpers/branch-like'; import { findMeasure } from '../../../helpers/measures'; import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls'; import { BranchLike } from '../../../types/branch-like'; -import { getIssueIconClass, getIssueMetricKey, IssueType } from '../utils'; +import { IssueType } from '../../../types/issues'; +import { getIssueIconClass, getIssueMetricKey } from '../utils'; export interface IssueLabelProps { branchLike?: BranchLike; diff --git a/server/sonar-web/src/main/js/apps/overview/components/IssueRating.tsx b/server/sonar-web/src/main/js/apps/overview/components/IssueRating.tsx index 05279460952..830c0a531e5 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/IssueRating.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/IssueRating.tsx @@ -24,7 +24,8 @@ import { getLeakValue, getRatingTooltip } from '../../../components/measure/util import DrilldownLink from '../../../components/shared/DrilldownLink'; import { findMeasure } from '../../../helpers/measures'; import { BranchLike } from '../../../types/branch-like'; -import { getIssueRatingMetricKey, getIssueRatingName, IssueType } from '../utils'; +import { IssueType } from '../../../types/issues'; +import { getIssueRatingMetricKey, getIssueRatingName } from '../utils'; export interface IssueRatingProps { branchLike?: BranchLike; diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueLabel-test.tsx b/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueLabel-test.tsx index 17b9f42fcb7..40f07a5621c 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueLabel-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueLabel-test.tsx @@ -21,8 +21,8 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { mockPullRequest } from '../../../../helpers/mocks/branch-like'; import { mockComponent, mockMeasureEnhanced, mockMetric } from '../../../../helpers/testMocks'; +import { IssueType } from '../../../../types/issues'; import { MetricKey } from '../../../../types/metrics'; -import { IssueType } from '../../utils'; import { IssueLabel, IssueLabelProps } from '../IssueLabel'; it('should render correctly for bugs', () => { diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueRating-test.tsx b/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueRating-test.tsx index 1b660f3c124..d85efbd06c5 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueRating-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/IssueRating-test.tsx @@ -21,8 +21,8 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { mockPullRequest } from '../../../../helpers/mocks/branch-like'; import { mockComponent, mockMeasureEnhanced, mockMetric } from '../../../../helpers/testMocks'; +import { IssueType } from '../../../../types/issues'; import { MetricKey } from '../../../../types/metrics'; -import { IssueType } from '../../utils'; import { IssueRating, IssueRatingProps } from '../IssueRating'; it('should render correctly for bugs', () => { diff --git a/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx b/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx index 176ede6361f..df49eb32417 100644 --- a/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx +++ b/server/sonar-web/src/main/js/apps/overview/pullRequests/PullRequestOverview.tsx @@ -32,13 +32,14 @@ import { enhanceConditionWithMeasure, enhanceMeasuresWithMetrics } from '../../. import { fetchBranchStatus } from '../../../store/rootActions'; import { getBranchStatusByBranchLike, Store } from '../../../store/rootReducer'; import { BranchLike, PullRequest } from '../../../types/branch-like'; +import { IssueType } from '../../../types/issues'; import { QualityGateStatusCondition } from '../../../types/quality-gates'; import IssueLabel from '../components/IssueLabel'; import IssueRating from '../components/IssueRating'; import MeasurementLabel from '../components/MeasurementLabel'; import QualityGateConditions from '../components/QualityGateConditions'; import '../styles.css'; -import { IssueType, MeasurementType, PR_METRICS } from '../utils'; +import { MeasurementType, PR_METRICS } from '../utils'; import AfterMergeEstimate from './AfterMergeEstimate'; import LargeQualityGateBadge from './LargeQualityGateBadge'; diff --git a/server/sonar-web/src/main/js/apps/overview/utils.ts b/server/sonar-web/src/main/js/apps/overview/utils.ts index 39e122d0a0d..eadd034a437 100644 --- a/server/sonar-web/src/main/js/apps/overview/utils.ts +++ b/server/sonar-web/src/main/js/apps/overview/utils.ts @@ -17,13 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import BugIcon from 'sonar-ui-common/components/icons/BugIcon'; -import CodeSmellIcon from 'sonar-ui-common/components/icons/CodeSmellIcon'; -import SecurityHotspotIcon from 'sonar-ui-common/components/icons/SecurityHotspotIcon'; -import VulnerabilityIcon from 'sonar-ui-common/components/icons/VulnerabilityIcon'; import DuplicationsRating from 'sonar-ui-common/components/ui/DuplicationsRating'; import { translate } from 'sonar-ui-common/helpers/l10n'; import CoverageRating from '../../components/ui/CoverageRating'; +import { ISSUETYPE_METRIC_KEYS_MAP } from '../../helpers/issues'; +import { IssueType } from '../../types/issues'; import { MetricKey } from '../../types/metrics'; export const METRICS: string[] = [ @@ -136,62 +134,24 @@ const MEASUREMENTS_MAP = { } }; -export enum IssueType { - CodeSmell = 'CODE_SMELL', - Vulnerability = 'VULNERABILITY', - Bug = 'BUG', - SecurityHotspot = 'SECURITY_HOTSPOT' -} - -const ISSUETYPE_MAP = { - [IssueType.CodeSmell]: { - metric: MetricKey.code_smells, - newMetric: MetricKey.new_code_smells, - rating: MetricKey.sqale_rating, - newRating: MetricKey.new_maintainability_rating, - ratingName: 'Maintainability', - iconClass: CodeSmellIcon - }, - [IssueType.Vulnerability]: { - metric: MetricKey.vulnerabilities, - newMetric: MetricKey.new_vulnerabilities, - rating: MetricKey.security_rating, - newRating: MetricKey.new_security_rating, - ratingName: 'Security', - iconClass: VulnerabilityIcon - }, - [IssueType.Bug]: { - metric: MetricKey.bugs, - newMetric: MetricKey.new_bugs, - rating: MetricKey.reliability_rating, - newRating: MetricKey.new_reliability_rating, - ratingName: 'Reliability', - iconClass: BugIcon - }, - [IssueType.SecurityHotspot]: { - metric: MetricKey.security_hotspots, - newMetric: MetricKey.new_security_hotspots, - rating: MetricKey.security_review_rating, - newRating: MetricKey.new_security_review_rating, - ratingName: 'SecurityReview', - iconClass: SecurityHotspotIcon - } -}; - export function getIssueRatingName(type: IssueType) { - return translate('metric_domain', ISSUETYPE_MAP[type].ratingName); + return translate('metric_domain', ISSUETYPE_METRIC_KEYS_MAP[type].ratingName); } export function getIssueIconClass(type: IssueType) { - return ISSUETYPE_MAP[type].iconClass; + return ISSUETYPE_METRIC_KEYS_MAP[type].iconClass; } export function getIssueMetricKey(type: IssueType, useDiffMetric: boolean) { - return useDiffMetric ? ISSUETYPE_MAP[type].newMetric : ISSUETYPE_MAP[type].metric; + return useDiffMetric + ? ISSUETYPE_METRIC_KEYS_MAP[type].newMetric + : ISSUETYPE_METRIC_KEYS_MAP[type].metric; } export function getIssueRatingMetricKey(type: IssueType, useDiffMetric: boolean) { - return useDiffMetric ? ISSUETYPE_MAP[type].newRating : ISSUETYPE_MAP[type].rating; + return useDiffMetric + ? ISSUETYPE_METRIC_KEYS_MAP[type].newRating + : ISSUETYPE_METRIC_KEYS_MAP[type].rating; } export function getMeasurementIconClass(type: MeasurementType) { diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx index 9c4be2d5a84..63f01ef746c 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.tsx @@ -32,6 +32,8 @@ import { collapsedDirFromPath, fileFromPath } from 'sonar-ui-common/helpers/path import { omitNil } from 'sonar-ui-common/helpers/request'; import { getBaseUrl, getPathUrlAsString } from 'sonar-ui-common/helpers/urls'; import { getBranchLikeQuery } from '../../helpers/branch-like'; +import { ISSUE_TYPES } from '../../helpers/constants'; +import { ISSUETYPE_METRIC_KEYS_MAP } from '../../helpers/issues'; import { getBranchLikeUrl, getCodeUrl, getComponentIssuesUrl } from '../../helpers/urls'; import { BranchLike } from '../../types/branch-like'; import { ComponentQualifier } from '../../types/component'; @@ -50,13 +52,6 @@ interface State { measuresOverlay: boolean; } -const METRIC_KEY_FOR_ISSUE_TYPE: { [type in T.IssueType]: string } = { - BUG: 'bugs', - VULNERABILITY: 'vulnerabilities', - CODE_SMELL: 'code_smells', - SECURITY_HOTSPOT: 'security_hotspots' -}; - export default class SourceViewerHeader extends React.PureComponent { state: State = { measuresOverlay: false }; @@ -83,7 +78,7 @@ export default class SourceViewerHeader extends React.PureComponent
- {['BUG', 'VULNERABILITY', 'CODE_SMELL', 'SECURITY_HOTSPOT'].map((type: T.IssueType) => { + {ISSUE_TYPES.map((type: T.IssueType) => { const params = { ...getBranchLikeQuery(branchLike), fileUuids: sourceViewerFile.uuid, @@ -92,7 +87,7 @@ export default class SourceViewerHeader extends React.PureComponent m.metric === METRIC_KEY_FOR_ISSUE_TYPE[type] + m => m.metric === ISSUETYPE_METRIC_KEYS_MAP[type].metric ); return (
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeader-test.tsx b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeader-test.tsx index 00f10dee620..5b50fd23e86 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeader-test.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/SourceViewerHeader-test.tsx @@ -21,6 +21,7 @@ import { shallow } from 'enzyme'; import * as React from 'react'; import { mockMainBranch } from '../../../helpers/mocks/branch-like'; import { mockSourceViewerFile } from '../../../helpers/testMocks'; +import { MetricKey } from '../../../types/metrics'; import SourceViewerHeader from '../SourceViewerHeader'; it('should render correctly for a regular file', () => { @@ -38,10 +39,10 @@ it('should render correctly for a unit test', () => { it('should render correctly if issue details are passed', () => { const componentMeasures: T.Measure[] = [ - { metric: 'code_smells', value: '1' }, - { metric: 'unused_metric_to_be_ignored', value: '42' }, - { metric: 'security_hotspots', value: '2' }, - { metric: 'vulnerabilities', value: '2' } + { metric: MetricKey.code_smells, value: '1' }, + { metric: MetricKey.file_complexity_distribution, value: '42' }, // unused, should be ignored + { metric: MetricKey.security_hotspots, value: '2' }, + { metric: MetricKey.vulnerabilities, value: '2' } ]; expect( diff --git a/server/sonar-web/src/main/js/helpers/constants.ts b/server/sonar-web/src/main/js/helpers/constants.ts index f0d60622137..2e101a490d0 100644 --- a/server/sonar-web/src/main/js/helpers/constants.ts +++ b/server/sonar-web/src/main/js/helpers/constants.ts @@ -18,14 +18,15 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { colors } from '../app/theme'; +import { IssueType } from '../types/issues'; export const SEVERITIES = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO']; export const STATUSES = ['OPEN', 'REOPENED', 'CONFIRMED', 'RESOLVED', 'CLOSED']; export const ISSUE_TYPES: T.IssueType[] = [ - 'BUG', - 'VULNERABILITY', - 'CODE_SMELL', - 'SECURITY_HOTSPOT' + IssueType.Bug, + IssueType.Vulnerability, + IssueType.CodeSmell, + IssueType.SecurityHotspot ]; export const RULE_TYPES: T.RuleType[] = ['BUG', 'VULNERABILITY', 'CODE_SMELL', 'SECURITY_HOTSPOT']; export const RULE_STATUSES = ['READY', 'BETA', 'DEPRECATED']; diff --git a/server/sonar-web/src/main/js/helpers/issues.ts b/server/sonar-web/src/main/js/helpers/issues.ts index dc84f8d64fb..68a5d9ee2f0 100644 --- a/server/sonar-web/src/main/js/helpers/issues.ts +++ b/server/sonar-web/src/main/js/helpers/issues.ts @@ -18,6 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { flatten, sortBy } from 'lodash'; +import BugIcon from 'sonar-ui-common/components/icons/BugIcon'; +import CodeSmellIcon from 'sonar-ui-common/components/icons/CodeSmellIcon'; +import SecurityHotspotIcon from 'sonar-ui-common/components/icons/SecurityHotspotIcon'; +import VulnerabilityIcon from 'sonar-ui-common/components/icons/VulnerabilityIcon'; +import { IssueType } from '../types/issues'; +import { MetricKey } from '../types/metrics'; import { ISSUE_TYPES } from './constants'; interface Comment { @@ -170,3 +176,38 @@ export function parseIssueFromResponse( ...ensureTextRange(issue) } as T.Issue; } + +export const ISSUETYPE_METRIC_KEYS_MAP = { + [IssueType.CodeSmell]: { + metric: MetricKey.code_smells, + newMetric: MetricKey.new_code_smells, + rating: MetricKey.sqale_rating, + newRating: MetricKey.new_maintainability_rating, + ratingName: 'Maintainability', + iconClass: CodeSmellIcon + }, + [IssueType.Vulnerability]: { + metric: MetricKey.vulnerabilities, + newMetric: MetricKey.new_vulnerabilities, + rating: MetricKey.security_rating, + newRating: MetricKey.new_security_rating, + ratingName: 'Security', + iconClass: VulnerabilityIcon + }, + [IssueType.Bug]: { + metric: MetricKey.bugs, + newMetric: MetricKey.new_bugs, + rating: MetricKey.reliability_rating, + newRating: MetricKey.new_reliability_rating, + ratingName: 'Reliability', + iconClass: BugIcon + }, + [IssueType.SecurityHotspot]: { + metric: MetricKey.security_hotspots, + newMetric: MetricKey.new_security_hotspots, + rating: MetricKey.security_review_rating, + newRating: MetricKey.new_security_review_rating, + ratingName: 'SecurityReview', + iconClass: SecurityHotspotIcon + } +}; diff --git a/server/sonar-web/src/main/js/types/issues.ts b/server/sonar-web/src/main/js/types/issues.ts new file mode 100644 index 00000000000..a9d2ae5cb8b --- /dev/null +++ b/server/sonar-web/src/main/js/types/issues.ts @@ -0,0 +1,26 @@ +/* + * SonarQube + * Copyright (C) 2009-2020 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. + */ + +export enum IssueType { + CodeSmell = 'CODE_SMELL', + Vulnerability = 'VULNERABILITY', + Bug = 'BUG', + SecurityHotspot = 'SECURITY_HOTSPOT' +} -- 2.39.5