@@ -80,6 +80,15 @@ export default class CodingRulesMock { | |||
name: 'Hot hotspot', | |||
type: 'SECURITY_HOTSPOT', | |||
lang: 'js', | |||
descriptionSections: [ | |||
{ key: RuleDescriptionSections.INTRODUCTION, content: 'Introduction to this rule' }, | |||
{ key: RuleDescriptionSections.ROOT_CAUSE, content: 'This how to fix' }, | |||
{ key: RuleDescriptionSections.ASSESS_THE_PROBLEM, content: 'Assess' }, | |||
{ | |||
key: RuleDescriptionSections.RESOURCES, | |||
content: 'Some link <a href="http://example.com">Awsome Reading</a>' | |||
} | |||
], | |||
langName: 'JavaScript' | |||
}), | |||
mockRuleDetails({ key: 'rule3', name: 'Unknown rule', lang: 'js', langName: 'JavaScript' }), |
@@ -68,7 +68,7 @@ it('should show open rule with default description section', async () => { | |||
await screen.findByRole('heading', { level: 3, name: 'Awsome java rule' }) | |||
).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('region', { name: 'coding_rules.description_section.title.root_cause' }) | |||
screen.getByRole('heading', { name: 'coding_rules.description_section.title.root_cause' }) | |||
).toBeInTheDocument(); | |||
}); | |||
@@ -80,19 +80,52 @@ it('should show open rule with no description', async () => { | |||
expect(screen.getByText('issue.external_issue_description.Bad Python rule')).toBeInTheDocument(); | |||
}); | |||
it('should show open rule advance section', async () => { | |||
it('should show hotspot rule section', async () => { | |||
renderCodingRulesApp(undefined, 'coding_rules?open=rule2'); | |||
expect(await screen.findByRole('heading', { level: 3, name: 'Hot hotspot' })).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('heading', { | |||
name: 'coding_rules.description_section.title.introduction' | |||
}) | |||
).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('heading', { | |||
name: 'coding_rules.description_section.title.root_cause.SECURITY_HOTSPOT' | |||
}) | |||
).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('heading', { | |||
name: 'coding_rules.description_section.title.assess_the_problem' | |||
}) | |||
).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('heading', { | |||
name: 'coding_rules.description_section.title.resources' | |||
}) | |||
).toBeInTheDocument(); | |||
// Check that we render plain html | |||
expect(screen.getByRole('link', { name: 'Awsome Reading' })).toBeInTheDocument(); | |||
}); | |||
it('should show rule advanced section', async () => { | |||
renderCodingRulesApp(undefined, 'coding_rules?open=rule5'); | |||
expect( | |||
await screen.findByRole('heading', { level: 3, name: 'Awsome Python rule' }) | |||
).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('region', { name: 'coding_rules.description_section.title.introduction' }) | |||
screen.getByRole('heading', { | |||
name: 'coding_rules.description_section.title.introduction' | |||
}) | |||
).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('region', { name: 'coding_rules.description_section.title.how_to_fix' }) | |||
screen.getByRole('heading', { | |||
name: 'coding_rules.description_section.title.how_to_fix' | |||
}) | |||
).toBeInTheDocument(); | |||
expect( | |||
screen.getByRole('region', { name: 'coding_rules.description_section.title.resources' }) | |||
screen.getByRole('heading', { | |||
name: 'coding_rules.description_section.title.resources' | |||
}) | |||
).toBeInTheDocument(); | |||
// Check that we render plain html | |||
expect(screen.getByRole('link', { name: 'Awsome Reading' })).toBeInTheDocument(); |
@@ -207,17 +207,34 @@ export default class RuleDetailsDescription extends React.PureComponent<Props, S | |||
</div> | |||
); | |||
renderDescription(section: RuleDescriptionSection) { | |||
renderDescription = (section: RuleDescriptionSection) => { | |||
if (section.key === RuleDescriptionSections.DEFAULT) { | |||
return ( | |||
<section | |||
className="coding-rules-detail-description rule-desc markdown" | |||
key={section.key} | |||
/* eslint-disable-next-line react/no-danger */ | |||
dangerouslySetInnerHTML={{ __html: sanitizeString(section.content) }} | |||
/> | |||
); | |||
} | |||
const { ruleDetails } = this.props; | |||
const title = | |||
section.key === RuleDescriptionSections.ROOT_CAUSE && ruleDetails.type === 'SECURITY_HOTSPOT' | |||
? translate('coding_rules.description_section.title', section.key, ruleDetails.type) | |||
: translate('coding_rules.description_section.title', section.key); | |||
return ( | |||
<section | |||
aria-label={translate('coding_rules.description_section.title', section.key)} | |||
className="coding-rules-detail-description rule-desc markdown" | |||
key={section.key} | |||
/* eslint-disable-next-line react/no-danger */ | |||
dangerouslySetInnerHTML={{ __html: sanitizeString(section.content) }} | |||
/> | |||
<section className="coding-rules-detail-description rule-desc markdown" key={section.key}> | |||
<h2>{title}</h2> | |||
<div | |||
/* eslint-disable-next-line react/no-danger */ | |||
dangerouslySetInnerHTML={{ __html: sanitizeString(section.content) }} | |||
/> | |||
</section> | |||
); | |||
} | |||
}; | |||
render() { | |||
const { ruleDetails } = this.props; |
@@ -1897,9 +1897,9 @@ coding_rules.remediation_function.constant=Constant | |||
coding_rules.external_rule.engine=Rule provided by an external rule engine: {0} | |||
coding_rules.description_section.title.default= | |||
coding_rules.description_section.title.introduction=Introduction | |||
coding_rules.description_section.title.root_cause=Why is this an issue? | |||
coding_rules.description_section.title.root_cause.SECURITY_HOTSPOT=What is the risk? | |||
coding_rules.description_section.title.assess_the_problem=Assess the risk? | |||
coding_rules.description_section.title.how_to_fix=How to fix it? | |||
coding_rules.description_section.title.resources=Resources |