From d64ee92295a48e1ce3c7af7fb7f6425bb38bada0 Mon Sep 17 00:00:00 2001 From: Revanshu Paliwal Date: Thu, 21 Jul 2022 12:00:13 +0200 Subject: [PATCH] SONAR-16598 Fixing extended rule description bug in issue page --- .../main/js/api/mocks/IssuesServiceMock.ts | 1 + .../js/apps/issues/__tests__/IssueApp-it.tsx | 6 +++- .../apps/issues/components/IssueTabViewer.tsx | 16 ---------- .../js/apps/issues/components/IssuesApp.tsx | 32 +++++++++++++++++-- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts index 0188a721882..e2da3d0c923 100644 --- a/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts @@ -254,6 +254,7 @@ export default class IssuesServiceMock { rule: mockRuleDetails({ key: parameters.key, name: 'Advanced rule', + htmlNote: '

Extended Description

', educationPrinciples: ['defense_in_depth'], descriptionSections: [ { key: RuleDescriptionSections.INTRODUCTION, content: '

Into

' }, diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx index b3bf900e1cb..ddabf99750b 100644 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx +++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx @@ -87,11 +87,15 @@ it('should open issue and navigate', async () => { expect(screen.getByText('coding_rules.context.others.description.first')).toBeInTheDocument(); expect(screen.getByText('coding_rules.context.others.description.second')).toBeInTheDocument(); - // Select the resources tab and check its content + // Select the main info tab and check its content expect(screen.getByRole('button', { name: `issue.tabs.more_info` })).toBeInTheDocument(); await user.click(screen.getByRole('button', { name: `issue.tabs.more_info` })); expect(screen.getByRole('heading', { name: 'Link' })).toBeInTheDocument(); + // check for extended description + const extendedDescriptions = screen.getAllByText('Extended Description'); + expect(extendedDescriptions).toHaveLength(1); + // Select the previous issue (with a simple rule) through keyboard shortcut await user.keyboard('{ArrowUp}'); diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssueTabViewer.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssueTabViewer.tsx index 52b264780b6..578c7faec8c 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssueTabViewer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssueTabViewer.tsx @@ -55,22 +55,6 @@ export default class IssueViewerTabs extends React.PureComponent { !!ruleDetails.educationPrinciples && ruleDetails.educationPrinciples.length > 0; const showNotification = showNotice && hasEducationPrinciples; - if (ruleDetails.htmlNote) { - if (descriptionSectionsByKey[RuleDescriptionSections.RESOURCES] !== undefined) { - // We add the extended description (htmlNote) in the first context, in case there are contexts - // Extended description will get reworked in future - descriptionSectionsByKey[RuleDescriptionSections.RESOURCES][0].content += - '
' + ruleDetails.htmlNote; - } else { - descriptionSectionsByKey[RuleDescriptionSections.RESOURCES] = [ - { - key: RuleDescriptionSections.RESOURCES, - content: ruleDetails.htmlNote - } - ]; - } - } - const rootCauseDescriptionSections = descriptionSectionsByKey[RuleDescriptionSections.DEFAULT] || descriptionSectionsByKey[RuleDescriptionSections.ROOT_CAUSE]; diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx index 79f773c9221..49dc85b3a96 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesApp.tsx @@ -19,7 +19,7 @@ */ import styled from '@emotion/styled'; import classNames from 'classnames'; -import { debounce, keyBy, omit, without } from 'lodash'; +import { debounce, groupBy, keyBy, omit, without } from 'lodash'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import { FormattedMessage } from 'react-intl'; @@ -74,6 +74,7 @@ import { import { SecurityStandard } from '../../../types/security'; import { Component, Dict, Issue, Paging, RawQuery, RuleDetails } from '../../../types/types'; import { CurrentUser, UserBase } from '../../../types/users'; +import { RuleDescriptionSections } from '../../coding-rules/rule'; import * as actions from '../actions'; import ConciseIssuesList from '../conciseIssuesList/ConciseIssuesList'; import ConciseIssuesListHeader from '../conciseIssuesList/ConciseIssuesListHeader'; @@ -354,13 +355,40 @@ export class App extends React.PureComponent { } this.setState({ loadingRule: true }); const openRuleDetails = await getRuleDetails({ key: openIssue.rule }) - .then(response => response.rule) + .then(response => { + const ruleDetails = response.rule; + this.addExtendedDescription(ruleDetails); + return ruleDetails; + }) .catch(() => undefined); if (this.mounted) { this.setState({ loadingRule: false, openRuleDetails }); } } + addExtendedDescription = (ruleDetails: RuleDetails) => { + const descriptionSectionsByKey = groupBy( + ruleDetails.descriptionSections, + section => section.key + ); + + if (ruleDetails.htmlNote) { + if (descriptionSectionsByKey[RuleDescriptionSections.RESOURCES] !== undefined) { + // We add the extended description (htmlNote) in the first context, in case there are contexts + // Extended description will get reworked in future + descriptionSectionsByKey[RuleDescriptionSections.RESOURCES][0].content += + '
' + ruleDetails.htmlNote; + } else { + descriptionSectionsByKey[RuleDescriptionSections.RESOURCES] = [ + { + key: RuleDescriptionSections.RESOURCES, + content: ruleDetails.htmlNote + } + ]; + } + } + }; + selectPreviousIssue = () => { const { issues } = this.state; const selectedIndex = this.getSelectedIndex(); -- 2.39.5