From 10e6b8ee65ecc77738bfab13fd3be135e8e4ab85 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 10 Jan 2023 14:35:17 +0100 Subject: [PATCH] SONAR-17816 Warn user about non-cayc-compliant QG on the project overview --- .../branches/QualityGatePanelSection.tsx | 122 ++++++------------ .../__tests__/BranchOverview-test.tsx | 27 ---- .../QualityGatePanelSection-test.tsx | 1 + .../QualityGatePanelSection-test.tsx.snap | 100 ++++---------- .../src/main/js/apps/overview/styles.css | 7 - .../src/main/js/apps/overview/utils.ts | 10 -- .../resources/org/sonar/l10n/core.properties | 11 +- 7 files changed, 71 insertions(+), 207 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx b/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx index d67432add26..ac9bc243030 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/QualityGatePanelSection.tsx @@ -21,18 +21,16 @@ import * as React from 'react'; import { ButtonPlain } from '../../../components/controls/buttons'; import ChevronDownIcon from '../../../components/icons/ChevronDownIcon'; import ChevronRightIcon from '../../../components/icons/ChevronRightIcon'; -import { Alert } from '../../../components/ui/Alert'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { isDiffMetric } from '../../../helpers/measures'; import { BranchLike } from '../../../types/branch-like'; -import { ComponentQualifier } from '../../../types/component'; +import { isApplication } from '../../../types/component'; import { QualityGateStatus, QualityGateStatusConditionEnhanced, } from '../../../types/quality-gates'; import { Component } from '../../../types/types'; import QualityGateConditions from '../components/QualityGateConditions'; -import { CAYC_METRICS } from '../utils'; import CleanAsYouCodeWarning from './CleanAsYouCodeWarning'; export interface QualityGatePanelSectionProps { @@ -41,22 +39,21 @@ export interface QualityGatePanelSectionProps { qgStatus: QualityGateStatus; } -function splitConditions(conditions: QualityGateStatusConditionEnhanced[]) { - const caycConditions = []; +function splitConditions( + conditions: QualityGateStatusConditionEnhanced[] +): [QualityGateStatusConditionEnhanced[], QualityGateStatusConditionEnhanced[]] { const newCodeFailedConditions = []; const overallFailedConditions = []; for (const condition of conditions) { - if (CAYC_METRICS.includes(condition.metric)) { - caycConditions.push(condition); - } else if (isDiffMetric(condition.metric)) { + if (isDiffMetric(condition.metric)) { newCodeFailedConditions.push(condition); } else { overallFailedConditions.push(condition); } } - return [caycConditions, newCodeFailedConditions, overallFailedConditions]; + return [newCodeFailedConditions, overallFailedConditions]; } function displayConditions(conditions: number) { @@ -84,24 +81,15 @@ export function QualityGatePanelSection(props: QualityGatePanelSectionProps) { return null; } - const [caycConditions, newCodeFailedConditions, overallFailedConditions] = splitConditions( + const [newCodeFailedConditions, overallFailedConditions] = splitConditions( qgStatus.failedConditions ); - /* - * Show Clean as You Code if: - * - The QG is not CAYC-compliant - * - There are *any* failing conditions, we either show: - * - the cayc-specific failures - * - that cayc is passing and only other conditions are failing - */ - const showCayc = !qgStatus.isCaycCompliant || qgStatus.failedConditions.length > 0; + const showName = isApplication(component.qualifier); - const showSuccessfulCayc = caycConditions.length === 0 && qgStatus.isCaycCompliant; - - const hasOtherConditions = newCodeFailedConditions.length + overallFailedConditions.length > 0; - - const showName = component.qualifier === ComponentQualifier.Application; + const showSectionTitles = + !qgStatus.isCaycCompliant || + (overallFailedConditions.length > 0 && newCodeFailedConditions.length > 0); const toggleLabel = collapsed ? translateWithParameters('overview.quality_gate.show_project_conditions_x', qgStatus.name) @@ -131,69 +119,45 @@ export function QualityGatePanelSection(props: QualityGatePanelSectionProps) { {!collapsed && ( <> - {showCayc && ( - <> -
-

{translate('quality_gates.conditions.cayc')}

- {displayConditions(caycConditions.length)} -
- - {!qgStatus.isCaycCompliant && ( -
- -
- )} - - {showSuccessfulCayc && ( -
- - {translate('overview.quality_gate.conditions.cayc.passed')} - -
- )} + {!qgStatus.isCaycCompliant && ( +
+ +
+ )} - {caycConditions.length > 0 && ( - + {newCodeFailedConditions.length > 0 && ( + <> + {showSectionTitles && ( +

+ {translateWithParameters( + 'quality_gates.conditions.new_code_x', + newCodeFailedConditions.length.toString() + )} +

)} + )} - {hasOtherConditions && ( + {overallFailedConditions.length > 0 && ( <> -
-

{translate('quality_gates.conditions.other_conditions')}

- {displayConditions(newCodeFailedConditions.length + overallFailedConditions.length)} -
- - {newCodeFailedConditions.length > 0 && ( - <> -
- {translate('quality_gates.conditions.new_code')} -
- - - )} - - {overallFailedConditions.length > 0 && ( - <> -
- {translate('quality_gates.conditions.overall_code')} -
- - + {showSectionTitles && ( +

+ {translateWithParameters( + 'quality_gates.conditions.overall_code_x', + overallFailedConditions.length.toString() + )} +

)} + )} diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-test.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-test.tsx index be4171f53e2..7b0e14a91f4 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/BranchOverview-test.tsx @@ -34,7 +34,6 @@ import { mockQualityGateProjectStatus } from '../../../../helpers/mocks/quality- import { mockLoggedInUser, mockPeriod } from '../../../../helpers/testMocks'; import { renderComponent } from '../../../../helpers/testReactTestingUtils'; import { ComponentQualifier } from '../../../../types/component'; -import { MetricKey } from '../../../../types/metrics'; import { GraphType } from '../../../../types/project-activity'; import { Measure, Metric } from '../../../../types/types'; import BranchOverview, { BRANCH_OVERVIEW_ACTIVITY_GRAPH, NO_CI_DETECTED } from '../BranchOverview'; @@ -231,32 +230,6 @@ describe('project overview', () => { expect(await screen.findByText('metric.level.ERROR')).toBeInTheDocument(); expect(screen.getByText('overview.X_conditions_failed.2')).toBeInTheDocument(); - - expect( - screen.queryByText('overview.quality_gate.conditions.cayc.passed') - ).not.toBeInTheDocument(); - }); - - it('should show a failed QG with passing CAYC conditions', async () => { - jest.mocked(getQualityGateProjectStatus).mockResolvedValueOnce( - mockQualityGateProjectStatus({ - status: 'ERROR', - conditions: [ - { - actualValue: '12', - comparator: 'GT', - errorThreshold: '10', - metricKey: MetricKey.new_bugs, - periodIndex: 1, - status: 'ERROR', - }, - ], - }) - ); - renderBranchOverview(); - - expect(await screen.findByText('metric.level.ERROR')).toBeInTheDocument(); - expect(screen.getByText('overview.quality_gate.conditions.cayc.passed')).toBeInTheDocument(); }); it('should correctly show a project as empty', async () => { diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/QualityGatePanelSection-test.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/QualityGatePanelSection-test.tsx index 251e2730e72..6d151b5bff1 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/QualityGatePanelSection-test.tsx +++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/QualityGatePanelSection-test.tsx @@ -55,6 +55,7 @@ function shallowRender(props: Partial = {}) { mockQualityGateStatusConditionEnhanced({ metric: MetricKey.new_bugs }), ], status: 'ERROR', + isCaycCompliant: false, })} {...props} /> diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap index c49d5435550..dd37526a134 100644 --- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/__snapshots__/QualityGatePanelSection-test.tsx.snap @@ -4,44 +4,16 @@ exports[`should render correctly 1`] = `
-
-

- quality_gates.conditions.cayc -

-
- - overview.quality_gate.conditions.cayc.passed - -
-
-

- quality_gates.conditions.other_conditions -

- - overview.X_conditions_failed.2 - +
-
- quality_gates.conditions.new_code -
+ quality_gates.conditions.new_code_x.1 + -
- quality_gates.conditions.overall_code -
+ quality_gates.conditions.overall_code_x.1 +
-
-

- quality_gates.conditions.cayc -

-
- - overview.quality_gate.conditions.cayc.passed - -
-
-

- quality_gates.conditions.other_conditions -

- - overview.X_conditions_failed.2 - +
-
- quality_gates.conditions.new_code -
+ quality_gates.conditions.new_code_x.1 + -
- quality_gates.conditions.overall_code -
+ quality_gates.conditions.overall_code_x.1 +