aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViktor Vorona <viktor.vorona@sonarsource.com>2024-10-16 13:18:21 +0200
committersonartech <sonartech@sonarsource.com>2024-10-16 20:03:02 +0000
commite811e3183bedf03b78096012c3654da1b2ef414e (patch)
tree46b89f232f41e006903e449a607dcdae53b7a91e
parent3bb32d2694602a7a8c63f307509b85ebb6a5bdcf (diff)
downloadsonarqube-e811e3183bedf03b78096012c3654da1b2ef414e.tar.gz
sonarqube-e811e3183bedf03b78096012c3654da1b2ef414e.zip
SONAR-23250 Ignore the order of impacts on showing the customization info
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRuleDetails-it.ts38
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx171
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogContainer-it.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx9
4 files changed, 126 insertions, 95 deletions
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRuleDetails-it.ts b/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRuleDetails-it.ts
index a5010470c86..e9b4b398af5 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRuleDetails-it.ts
+++ b/server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRuleDetails-it.ts
@@ -18,14 +18,15 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { fireEvent, screen } from '@testing-library/react';
+import { byRole } from '~sonar-aligned/helpers/testSelector';
import CodingRulesServiceMock, { RULE_TAGS_MOCK } from '../../../api/mocks/CodingRulesServiceMock';
import SettingsServiceMock from '../../../api/mocks/SettingsServiceMock';
-import { RULE_1 } from '../../../api/mocks/data/ids';
-import { mockCurrentUser, mockLoggedInUser } from '../../../helpers/testMocks';
-import { byRole } from '../../../sonar-aligned/helpers/testSelector';
+import { QP_2, RULE_1, RULE_10 } from '../../../api/mocks/data/ids';
+import { mockCurrentUser, mockLoggedInUser, mockRuleActivation } from '../../../helpers/testMocks';
import {
CleanCodeAttribute,
CleanCodeAttributeCategory,
+ SoftwareImpactSeverity,
SoftwareQuality,
} from '../../../types/clean-code-taxonomy';
import { Feature } from '../../../types/features';
@@ -35,8 +36,8 @@ import { getPageObjects, renderCodingRulesApp } from '../utils-tests';
const rulesHandler = new CodingRulesServiceMock();
const settingsHandler = new SettingsServiceMock();
afterEach(() => {
- rulesHandler.reset();
settingsHandler.reset();
+ rulesHandler.reset();
});
describe('rendering', () => {
@@ -169,6 +170,33 @@ describe('rendering', () => {
expect(ui.caycNotificationButton.query()).not.toBeInTheDocument();
});
+
+ it('should not show customized severity if the order of impacts is different', async () => {
+ const { ui } = getPageObjects();
+ rulesHandler.rulesActivations = {
+ [RULE_10]: [
+ mockRuleActivation({
+ qProfile: QP_2,
+ severity: 'MINOR',
+ impacts: [
+ {
+ softwareQuality: SoftwareQuality.Reliability,
+ severity: SoftwareImpactSeverity.High,
+ },
+ {
+ softwareQuality: SoftwareQuality.Maintainability,
+ severity: SoftwareImpactSeverity.Low,
+ },
+ ],
+ }),
+ ],
+ };
+ renderCodingRulesApp(mockCurrentUser(), 'coding_rules?open=rule10');
+
+ await ui.detailsloaded();
+
+ expect(ui.newSeverityCustomizedCell.query()).not.toBeInTheDocument();
+ });
});
it('can activate/change/deactivate rule in quality profile', async () => {
@@ -240,7 +268,7 @@ it('can activate/change/deactivate rule in quality profile', async () => {
it('can activate/change/deactivate rule in quality profile for legacy mode', async () => {
const { ui, user } = getPageObjects();
- settingsHandler.set(SettingsKey.MQRMode, 'true');
+ settingsHandler.set(SettingsKey.MQRMode, 'false');
rulesHandler.setIsAdmin();
renderCodingRulesApp(mockLoggedInUser(), 'coding_rules?open=rule1', [Feature.PrioritizedRules]);
await ui.detailsloaded();
diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx
index 52a91e8babc..29b0f06e319 100644
--- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx
+++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx
@@ -44,7 +44,8 @@ import {
useActivateRuleMutation,
useDeactivateRuleMutation,
} from '../../../queries/quality-profiles';
-import { useIsLegacyCCTMode } from '../../../queries/settings';
+import { useStandardExperienceMode } from '../../../queries/settings';
+import { SoftwareImpact } from '../../../types/clean-code-taxonomy';
import { Dict, RuleActivation, RuleDetails } from '../../../types/types';
import BuiltInQualityProfileBadge from '../../quality-profiles/components/BuiltInQualityProfileBadge';
import ActivatedRuleActions from './ActivatedRuleActions';
@@ -71,7 +72,7 @@ export default function RuleDetailsProfiles(props: Readonly<Props>) {
const { activations = [], referencedProfiles, ruleDetails, canDeactivateInherited } = props;
const { mutate: activateRule } = useActivateRuleMutation(props.onActivate);
const { mutate: deactivateRule } = useDeactivateRuleMutation(props.onDeactivate);
- const { data: isLegacy } = useIsLegacyCCTMode();
+ const { data: isStandardMode } = useStandardExperienceMode();
const canActivate = Object.values(referencedProfiles).some((profile) =>
Boolean(profile.actions?.edit && profile.language === ruleDetails.lang),
@@ -144,6 +145,12 @@ export default function RuleDetailsProfiles(props: Readonly<Props>) {
)
: null;
+ const sortImpacts = (a: SoftwareImpact, b: SoftwareImpact) => {
+ const indexA = softwareQualityOrderMap.get(a.softwareQuality) ?? -1;
+ const indexB = softwareQualityOrderMap.get(b.softwareQuality) ?? -1;
+ return indexA - indexB;
+ };
+
return (
<TableRowInteractive key={profile.key}>
<ContentCell className="sw-flex sw-flex-col sw-gap-2">
@@ -163,73 +170,65 @@ export default function RuleDetailsProfiles(props: Readonly<Props>) {
<Text isSubdued>{translate('coding_rules.prioritized_rule.title')}</Text>
</>
)}
- {!isLegacy &&
+ {!isStandardMode &&
activation.impacts &&
- !isEqual(activation.impacts, ruleDetails.impacts) && (
+ !isEqual(
+ [...activation.impacts].sort(sortImpacts),
+ [...ruleDetails.impacts].sort(sortImpacts),
+ ) && (
<>
<SeparatorCircleIcon />
<Tooltip
content={
<>
- {[...activation.impacts]
- .sort((a, b) => {
- const indexA = softwareQualityOrderMap.get(a.softwareQuality) ?? -1;
- const indexB = softwareQualityOrderMap.get(b.softwareQuality) ?? -1;
- return indexA - indexB;
- })
- .map((impact) => {
- const ruleImpact = ruleDetails.impacts.find(
- (i) => i.softwareQuality === impact.softwareQuality,
- );
- if (!ruleImpact || ruleImpact.severity === impact.severity) {
- return null;
- }
- return (
- <Text
- as="div"
- colorOverride="echoes-color-text-on-color"
- key={impact.softwareQuality}
- >
- <FormattedMessage
- id="coding_rules.impact_customized.detail"
- values={{
- softwareQuality: (
- <Text
- isHighlighted
- colorOverride="echoes-color-text-on-color"
- >
- <FormattedMessage
- id={`software_quality.${impact.softwareQuality}`}
- />
- </Text>
- ),
- recommended: (
- <Text
- isHighlighted
- colorOverride="echoes-color-text-on-color"
- className="sw-lowercase"
- >
- <FormattedMessage
- id={`severity_impact.${ruleImpact?.severity}`}
- />
- </Text>
- ),
- customized: (
- <Text
- isHighlighted
- colorOverride="echoes-color-text-on-color"
- className="sw-lowercase"
- >
- <FormattedMessage
- id={`severity_impact.${impact.severity}`}
- />
- </Text>
- ),
- }}
- />
- </Text>
- );
- })}
+ {[...activation.impacts].sort(sortImpacts).map((impact) => {
+ const ruleImpact = ruleDetails.impacts.find(
+ (i) => i.softwareQuality === impact.softwareQuality,
+ );
+ if (!ruleImpact || ruleImpact.severity === impact.severity) {
+ return null;
+ }
+ return (
+ <Text
+ as="div"
+ colorOverride="echoes-color-text-on-color"
+ key={impact.softwareQuality}
+ >
+ <FormattedMessage
+ id="coding_rules.impact_customized.detail"
+ values={{
+ softwareQuality: (
+ <Text isHighlighted colorOverride="echoes-color-text-on-color">
+ <FormattedMessage
+ id={`software_quality.${impact.softwareQuality}`}
+ />
+ </Text>
+ ),
+ recommended: (
+ <Text
+ isHighlighted
+ colorOverride="echoes-color-text-on-color"
+ className="sw-lowercase"
+ >
+ <FormattedMessage
+ id={`severity_impact.${ruleImpact?.severity}`}
+ />
+ </Text>
+ ),
+ customized: (
+ <Text
+ isHighlighted
+ colorOverride="echoes-color-text-on-color"
+ className="sw-lowercase"
+ >
+ <FormattedMessage id={`severity_impact.${impact.severity}`} />
+ </Text>
+ ),
+ }}
+ />
+ </Text>
+ );
+ })}
</>
}
>
@@ -238,28 +237,30 @@ export default function RuleDetailsProfiles(props: Readonly<Props>) {
</>
)}
- {isLegacy && activation.severity && activation.severity !== ruleDetails.severity && (
- <>
- <SeparatorCircleIcon />
- <Text isSubdued>
- <FormattedMessage
- id="coding_rules.severity_customized.message"
- values={{
- recommended: (
- <Text isHighlighted className="sw-lowercase">
- <FormattedMessage id={`severity.${ruleDetails.severity}`} />
- </Text>
- ),
- customized: (
- <Text isHighlighted className="sw-lowercase">
- <FormattedMessage id={`severity.${activation.severity}`} />
- </Text>
- ),
- }}
- />
- </Text>
- </>
- )}
+ {isStandardMode &&
+ activation.severity &&
+ activation.severity !== ruleDetails.severity && (
+ <>
+ <SeparatorCircleIcon />
+ <Text isSubdued>
+ <FormattedMessage
+ id="coding_rules.severity_customized.message"
+ values={{
+ recommended: (
+ <Text isHighlighted className="sw-lowercase">
+ <FormattedMessage id={`severity.${ruleDetails.severity}`} />
+ </Text>
+ ),
+ customized: (
+ <Text isHighlighted className="sw-lowercase">
+ <FormattedMessage id={`severity.${activation.severity}`} />
+ </Text>
+ ),
+ }}
+ />
+ </Text>
+ </>
+ )}
{profile.isBuiltIn && <BuiltInQualityProfileBadge />}
</div>
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogContainer-it.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogContainer-it.tsx
index b1d4c2b24ff..66b303fb58f 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogContainer-it.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogContainer-it.tsx
@@ -21,6 +21,7 @@ import { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { byRole, byText } from '~sonar-aligned/helpers/testSelector';
import QualityProfilesServiceMock from '../../../../api/mocks/QualityProfilesServiceMock';
+import SettingsServiceMock from '../../../../api/mocks/SettingsServiceMock';
import { mockQualityProfileChangelogEvent } from '../../../../helpers/testMocks';
import { renderAppRoutes } from '../../../../helpers/testReactTestingUtils';
import routes from '../../routes';
@@ -28,6 +29,7 @@ import routes from '../../routes';
jest.mock('../../../../api/quality-profiles');
const serviceMock = new QualityProfilesServiceMock();
+const settingsMock = new SettingsServiceMock();
const ui = {
row: byRole('row'),
cell: byRole('cell'),
@@ -75,6 +77,7 @@ afterEach(() => {
jest.useRealTimers();
serviceMock.reset();
+ settingsMock.reset();
});
it('should see the changelog', async () => {
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx
index 1f66dbd9dfb..da85a1fd73c 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.tsx
@@ -233,15 +233,14 @@ type RuleCellProps = {
function RuleCell({ rule, severity, impacts }: Readonly<RuleCellProps>) {
const { data: isStandardMode } = useStandardExperienceMode();
const shouldRenderSeverity =
- isStandardMode &&Boolean(severity) &&
+ isStandardMode &&
+ Boolean(severity) &&
rule.left?.severity &&
rule.right?.severity &&
- !isEqual(rule.left.severity,
- rule.right.severity);
+ !isEqual(rule.left.severity, rule.right.severity);
const shouldRenderImpacts =
rule.impacts ||
- (rule.left?.impacts && rule.right?.impacts &&
- !isEqual(rule.left.impacts, rule.right.impacts));
+ (rule.left?.impacts && rule.right?.impacts && !isEqual(rule.left.impacts, rule.right.impacts));
return (
<div>