diff options
author | Mathieu Suen <mathieu.suen@sonarsource.com> | 2021-06-24 14:33:52 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2021-06-28 20:03:20 +0000 |
commit | 3cd819d9bc115b4768bb05b42630cba7b21463ac (patch) | |
tree | a71bbbedc17c045c15be338223190883256d4ef1 /server/sonar-web | |
parent | a39e52a53386f08d7a6d68e6dd77d597a110761c (diff) | |
download | sonarqube-3cd819d9bc115b4768bb05b42630cba7b21463ac.tar.gz sonarqube-3cd819d9bc115b4768bb05b42630cba7b21463ac.zip |
SONAR-14760 Fix quality gate condition link in the overview page.
Diffstat (limited to 'server/sonar-web')
3 files changed, 179 insertions, 133 deletions
diff --git a/server/sonar-web/src/main/js/apps/overview/components/QualityGateCondition.tsx b/server/sonar-web/src/main/js/apps/overview/components/QualityGateCondition.tsx index 000bda88a16..f06d652ea4d 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/QualityGateCondition.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/QualityGateCondition.tsx @@ -23,12 +23,15 @@ import { Link } from 'react-router'; import IssueTypeIcon from 'sonar-ui-common/components/icons/IssueTypeIcon'; import { translate } from 'sonar-ui-common/helpers/l10n'; import { formatMeasure } from 'sonar-ui-common/helpers/measures'; +import { Location } from 'sonar-ui-common/helpers/urls'; import Measure from '../../../components/measure/Measure'; import DrilldownLink from '../../../components/shared/DrilldownLink'; import { getBranchLikeQuery } from '../../../helpers/branch-like'; import { isDiffMetric } from '../../../helpers/measures'; -import { getComponentIssuesUrl } from '../../../helpers/urls'; +import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls'; import { BranchLike } from '../../../types/branch-like'; +import { IssueType } from '../../../types/issues'; +import { MetricKey } from '../../../types/metrics'; import { QualityGateStatusConditionEnhanced } from '../../../types/quality-gates'; interface Props { @@ -50,6 +53,16 @@ export default class QualityGateCondition extends React.PureComponent<Props> { return getComponentIssuesUrl(this.props.component.key, query); }; + getUrlForSecurityHotspot(sinceLeakPeriod: boolean) { + const query: T.Dict<string | undefined> = { + ...getBranchLikeQuery(this.props.branchLike) + }; + if (sinceLeakPeriod) { + Object.assign(query, { sinceLeakPeriod: 'true' }); + } + return getComponentSecurityHotspotsUrl(this.props.component.key, query); + } + getUrlForCodeSmells(sinceLeakPeriod: boolean) { return this.getIssuesUrl(sinceLeakPeriod, { types: 'CODE_SMELL' }); } @@ -71,12 +84,6 @@ export default class QualityGateCondition extends React.PureComponent<Props> { }); } - getUrlForType(type: string, sinceLeakPeriod: boolean) { - return type === 'CODE_SMELL' - ? this.getUrlForCodeSmells(sinceLeakPeriod) - : this.getUrlForBugsOrVulnerabilities(type, sinceLeakPeriod); - } - wrapWithLink(children: React.ReactNode) { const { branchLike, component, condition } = this.props; @@ -87,17 +94,23 @@ export default class QualityGateCondition extends React.PureComponent<Props> { const metricKey = condition.measure.metric.key; - const RATING_METRICS_MAPPING: T.Dict<[string, boolean]> = { - reliability_rating: ['BUG', false], - new_reliability_rating: ['BUG', true], - security_rating: ['VULNERABILITY', false], - new_security_rating: ['VULNERABILITY', true], - sqale_rating: ['CODE_SMELL', false], - new_maintainability_rating: ['CODE_SMELL', true] + const METRICS_TO_URL_MAPPING: T.Dict<() => Location> = { + [MetricKey.reliability_rating]: () => + this.getUrlForBugsOrVulnerabilities(IssueType.Bug, false), + [MetricKey.new_reliability_rating]: () => + this.getUrlForBugsOrVulnerabilities(IssueType.Bug, true), + [MetricKey.security_rating]: () => + this.getUrlForBugsOrVulnerabilities(IssueType.Vulnerability, false), + [MetricKey.new_security_rating]: () => + this.getUrlForBugsOrVulnerabilities(IssueType.Vulnerability, true), + [MetricKey.sqale_rating]: () => this.getUrlForCodeSmells(false), + [MetricKey.new_maintainability_rating]: () => this.getUrlForCodeSmells(true), + [MetricKey.security_hotspots_reviewed]: () => this.getUrlForSecurityHotspot(false), + [MetricKey.new_security_hotspots_reviewed]: () => this.getUrlForSecurityHotspot(true) }; - return RATING_METRICS_MAPPING[metricKey] ? ( - <Link className={className} to={this.getUrlForType(...RATING_METRICS_MAPPING[metricKey])}> + return METRICS_TO_URL_MAPPING[metricKey] ? ( + <Link className={className} to={METRICS_TO_URL_MAPPING[metricKey]()}> {children} </Link> ) : ( diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/QualityGateCondition-test.tsx b/server/sonar-web/src/main/js/apps/overview/components/__tests__/QualityGateCondition-test.tsx index 5c871847d70..d452c49885c 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/QualityGateCondition-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/QualityGateCondition-test.tsx @@ -22,63 +22,30 @@ import * as React from 'react'; import { mockBranch } from '../../../../helpers/mocks/branch-like'; import { mockQualityGateStatusConditionEnhanced } from '../../../../helpers/mocks/quality-gates'; import { mockMetric } from '../../../../helpers/testMocks'; +import { MetricKey } from '../../../../types/metrics'; import { QualityGateStatusConditionEnhanced } from '../../../../types/quality-gates'; import QualityGateCondition from '../QualityGateCondition'; -it('open_issues', () => { - const condition = quickMock('open_issues', 'INT'); - expect(shallowRender({ condition })).toMatchSnapshot(); -}); - -it('new_open_issues', () => { - const condition = quickMock('new_open_issues', 'INT', true); - expect(shallowRender({ condition })).toMatchSnapshot(); -}); - -it('reliability_rating', () => { - const condition = quickMock('reliability_rating'); - expect(shallowRender({ condition })).toMatchSnapshot(); -}); - -it('security_rating', () => { - const condition = quickMock('security_rating'); - expect(shallowRender({ condition })).toMatchSnapshot(); -}); - -it('sqale_rating', () => { - const condition = quickMock('sqale_rating'); - expect(shallowRender({ condition })).toMatchSnapshot(); -}); - -it('new_reliability_rating', () => { - const condition = quickMock('new_reliability_rating', 'RATING', true); - expect(shallowRender({ condition })).toMatchSnapshot(); -}); - -it('new_security_rating', () => { - const condition = quickMock('new_security_rating', 'RATING', true); - expect(shallowRender({ condition })).toMatchSnapshot(); -}); - -it('new_maintainability_rating', () => { - const condition = quickMock('new_maintainability_rating', 'RATING', true); +it.each([ + [quickMock(MetricKey.open_issues, 'INT')], + [quickMock(MetricKey.reliability_rating)], + [quickMock(MetricKey.security_rating)], + [quickMock(MetricKey.sqale_rating)], + [quickMock(MetricKey.new_reliability_rating, 'RATING', true)], + [quickMock(MetricKey.new_security_rating, 'RATING', true)], + [quickMock(MetricKey.new_maintainability_rating, 'RATING', true)], + [quickMock(MetricKey.security_hotspots_reviewed)], + [quickMock(MetricKey.new_security_hotspots_reviewed, 'RATING', true)] +])('should render correclty', condition => { expect(shallowRender({ condition })).toMatchSnapshot(); }); it('should work with branch', () => { - const condition = quickMock('new_maintainability_rating'); - expect( - shallow( - <QualityGateCondition - branchLike={mockBranch()} - component={{ key: 'abcd-key' }} - condition={condition} - /> - ) - ).toMatchSnapshot(); + const condition = quickMock(MetricKey.new_maintainability_rating); + expect(shallowRender({ branchLike: mockBranch(), condition })).toMatchSnapshot(); }); -function shallowRender(props = {}) { +function shallowRender(props: Partial<QualityGateCondition['props']>) { return shallow( <QualityGateCondition component={{ key: 'abcd-key' }} @@ -89,7 +56,7 @@ function shallowRender(props = {}) { } function quickMock( - metric: string, + metric: MetricKey, type = 'RATING', addPeriod = false ): QualityGateStatusConditionEnhanced { diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/QualityGateCondition-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/QualityGateCondition-test.tsx.snap index 533338ad407..dd6aa7a6dd1 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/QualityGateCondition-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/QualityGateCondition-test.tsx.snap @@ -1,6 +1,48 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`new_maintainability_rating 1`] = ` +exports[`should render correclty 1`] = ` +<DrilldownLink + className="overview-quality-gate-condition overview-quality-gate-condition-error" + component="abcd-key" + metric="open_issues" + sinceLeakPeriod={false} +> + <div + className="overview-quality-gate-condition-container display-flex-center" + > + <div + className="overview-quality-gate-condition-value text-center spacer-right" + > + <Measure + decimals={2} + metricKey="open_issues" + metricType="INT" + value="3" + /> + </div> + <div> + <span + className="overview-quality-gate-condition-metric little-spacer-right" + > + <IssueTypeIcon + className="little-spacer-right" + query="open_issues" + /> + open_issues + </span> + <span + className="little-spacer-top small text-muted" + > + quality_gates.operator.GT + + 1 + </span> + </div> + </div> +</DrilldownLink> +`; + +exports[`should render correclty 2`] = ` <Link className="overview-quality-gate-condition overview-quality-gate-condition-error" onlyActiveOnIndex={false} @@ -11,8 +53,8 @@ exports[`new_maintainability_rating 1`] = ` "query": Object { "id": "abcd-key", "resolved": "false", - "sinceLeakPeriod": "true", - "types": "CODE_SMELL", + "severities": "BLOCKER,CRITICAL,MAJOR,MINOR", + "types": "BUG", }, } } @@ -25,7 +67,7 @@ exports[`new_maintainability_rating 1`] = ` > <Measure decimals={2} - metricKey="new_maintainability_rating" + metricKey="reliability_rating" metricType="RATING" value="3" /> @@ -36,9 +78,9 @@ exports[`new_maintainability_rating 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="new_maintainability_rating" + query="reliability_rating" /> - new_maintainability_rating + reliability_rating </span> <span className="little-spacer-top small text-muted" @@ -52,12 +94,22 @@ exports[`new_maintainability_rating 1`] = ` </Link> `; -exports[`new_open_issues 1`] = ` -<DrilldownLink +exports[`should render correclty 3`] = ` +<Link className="overview-quality-gate-condition overview-quality-gate-condition-error" - component="abcd-key" - metric="new_open_issues" - sinceLeakPeriod={true} + onlyActiveOnIndex={false} + style={Object {}} + to={ + Object { + "pathname": "/project/issues", + "query": Object { + "id": "abcd-key", + "resolved": "false", + "severities": "BLOCKER,CRITICAL,MAJOR,MINOR", + "types": "VULNERABILITY", + }, + } + } > <div className="overview-quality-gate-condition-container display-flex-center" @@ -67,8 +119,8 @@ exports[`new_open_issues 1`] = ` > <Measure decimals={2} - metricKey="new_open_issues" - metricType="INT" + metricKey="security_rating" + metricType="RATING" value="3" /> </div> @@ -78,23 +130,23 @@ exports[`new_open_issues 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="new_open_issues" + query="security_rating" /> - new_open_issues + security_rating </span> <span className="little-spacer-top small text-muted" > - quality_gates.operator.GT + quality_gates.operator.GT.rating - 1 + A </span> </div> </div> -</DrilldownLink> +</Link> `; -exports[`new_reliability_rating 1`] = ` +exports[`should render correclty 4`] = ` <Link className="overview-quality-gate-condition overview-quality-gate-condition-error" onlyActiveOnIndex={false} @@ -105,9 +157,7 @@ exports[`new_reliability_rating 1`] = ` "query": Object { "id": "abcd-key", "resolved": "false", - "severities": "BLOCKER,CRITICAL,MAJOR,MINOR", - "sinceLeakPeriod": "true", - "types": "BUG", + "types": "CODE_SMELL", }, } } @@ -120,7 +170,7 @@ exports[`new_reliability_rating 1`] = ` > <Measure decimals={2} - metricKey="new_reliability_rating" + metricKey="sqale_rating" metricType="RATING" value="3" /> @@ -131,9 +181,9 @@ exports[`new_reliability_rating 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="new_reliability_rating" + query="sqale_rating" /> - new_reliability_rating + sqale_rating </span> <span className="little-spacer-top small text-muted" @@ -147,7 +197,7 @@ exports[`new_reliability_rating 1`] = ` </Link> `; -exports[`new_security_rating 1`] = ` +exports[`should render correclty 5`] = ` <Link className="overview-quality-gate-condition overview-quality-gate-condition-error" onlyActiveOnIndex={false} @@ -160,7 +210,7 @@ exports[`new_security_rating 1`] = ` "resolved": "false", "severities": "BLOCKER,CRITICAL,MAJOR,MINOR", "sinceLeakPeriod": "true", - "types": "VULNERABILITY", + "types": "BUG", }, } } @@ -173,7 +223,7 @@ exports[`new_security_rating 1`] = ` > <Measure decimals={2} - metricKey="new_security_rating" + metricKey="new_reliability_rating" metricType="RATING" value="3" /> @@ -184,9 +234,9 @@ exports[`new_security_rating 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="new_security_rating" + query="new_reliability_rating" /> - new_security_rating + new_reliability_rating </span> <span className="little-spacer-top small text-muted" @@ -200,12 +250,23 @@ exports[`new_security_rating 1`] = ` </Link> `; -exports[`open_issues 1`] = ` -<DrilldownLink +exports[`should render correclty 6`] = ` +<Link className="overview-quality-gate-condition overview-quality-gate-condition-error" - component="abcd-key" - metric="open_issues" - sinceLeakPeriod={false} + onlyActiveOnIndex={false} + style={Object {}} + to={ + Object { + "pathname": "/project/issues", + "query": Object { + "id": "abcd-key", + "resolved": "false", + "severities": "BLOCKER,CRITICAL,MAJOR,MINOR", + "sinceLeakPeriod": "true", + "types": "VULNERABILITY", + }, + } + } > <div className="overview-quality-gate-condition-container display-flex-center" @@ -215,8 +276,8 @@ exports[`open_issues 1`] = ` > <Measure decimals={2} - metricKey="open_issues" - metricType="INT" + metricKey="new_security_rating" + metricType="RATING" value="3" /> </div> @@ -226,23 +287,23 @@ exports[`open_issues 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="open_issues" + query="new_security_rating" /> - open_issues + new_security_rating </span> <span className="little-spacer-top small text-muted" > - quality_gates.operator.GT + quality_gates.operator.GT.rating - 1 + A </span> </div> </div> -</DrilldownLink> +</Link> `; -exports[`reliability_rating 1`] = ` +exports[`should render correclty 7`] = ` <Link className="overview-quality-gate-condition overview-quality-gate-condition-error" onlyActiveOnIndex={false} @@ -253,8 +314,8 @@ exports[`reliability_rating 1`] = ` "query": Object { "id": "abcd-key", "resolved": "false", - "severities": "BLOCKER,CRITICAL,MAJOR,MINOR", - "types": "BUG", + "sinceLeakPeriod": "true", + "types": "CODE_SMELL", }, } } @@ -267,7 +328,7 @@ exports[`reliability_rating 1`] = ` > <Measure decimals={2} - metricKey="reliability_rating" + metricKey="new_maintainability_rating" metricType="RATING" value="3" /> @@ -278,9 +339,9 @@ exports[`reliability_rating 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="reliability_rating" + query="new_maintainability_rating" /> - reliability_rating + new_maintainability_rating </span> <span className="little-spacer-top small text-muted" @@ -294,19 +355,21 @@ exports[`reliability_rating 1`] = ` </Link> `; -exports[`security_rating 1`] = ` +exports[`should render correclty 8`] = ` <Link className="overview-quality-gate-condition overview-quality-gate-condition-error" onlyActiveOnIndex={false} style={Object {}} to={ Object { - "pathname": "/project/issues", + "pathname": "/security_hotspots", "query": Object { + "assignedToMe": undefined, + "branch": undefined, + "hotspots": undefined, "id": "abcd-key", - "resolved": "false", - "severities": "BLOCKER,CRITICAL,MAJOR,MINOR", - "types": "VULNERABILITY", + "pullRequest": undefined, + "sinceLeakPeriod": undefined, }, } } @@ -319,7 +382,7 @@ exports[`security_rating 1`] = ` > <Measure decimals={2} - metricKey="security_rating" + metricKey="security_hotspots_reviewed" metricType="RATING" value="3" /> @@ -330,9 +393,9 @@ exports[`security_rating 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="security_rating" + query="security_hotspots_reviewed" /> - security_rating + security_hotspots_reviewed </span> <span className="little-spacer-top small text-muted" @@ -346,20 +409,21 @@ exports[`security_rating 1`] = ` </Link> `; -exports[`should work with branch 1`] = ` +exports[`should render correclty 9`] = ` <Link className="overview-quality-gate-condition overview-quality-gate-condition-error" onlyActiveOnIndex={false} style={Object {}} to={ Object { - "pathname": "/project/issues", + "pathname": "/security_hotspots", "query": Object { - "branch": "branch-6.7", + "assignedToMe": undefined, + "branch": undefined, + "hotspots": undefined, "id": "abcd-key", - "resolved": "false", + "pullRequest": undefined, "sinceLeakPeriod": "true", - "types": "CODE_SMELL", }, } } @@ -372,7 +436,7 @@ exports[`should work with branch 1`] = ` > <Measure decimals={2} - metricKey="new_maintainability_rating" + metricKey="new_security_hotspots_reviewed" metricType="RATING" value="3" /> @@ -383,9 +447,9 @@ exports[`should work with branch 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="new_maintainability_rating" + query="new_security_hotspots_reviewed" /> - new_maintainability_rating + new_security_hotspots_reviewed </span> <span className="little-spacer-top small text-muted" @@ -399,7 +463,7 @@ exports[`should work with branch 1`] = ` </Link> `; -exports[`sqale_rating 1`] = ` +exports[`should work with branch 1`] = ` <Link className="overview-quality-gate-condition overview-quality-gate-condition-error" onlyActiveOnIndex={false} @@ -408,8 +472,10 @@ exports[`sqale_rating 1`] = ` Object { "pathname": "/project/issues", "query": Object { + "branch": "branch-6.7", "id": "abcd-key", "resolved": "false", + "sinceLeakPeriod": "true", "types": "CODE_SMELL", }, } @@ -423,7 +489,7 @@ exports[`sqale_rating 1`] = ` > <Measure decimals={2} - metricKey="sqale_rating" + metricKey="new_maintainability_rating" metricType="RATING" value="3" /> @@ -434,9 +500,9 @@ exports[`sqale_rating 1`] = ` > <IssueTypeIcon className="little-spacer-right" - query="sqale_rating" + query="new_maintainability_rating" /> - sqale_rating + new_maintainability_rating </span> <span className="little-spacer-top small text-muted" |