Skip to content

Commit

Permalink
Adding webview logic for non applicable vulnerabilities. (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
dortam888 authored Nov 20, 2024
1 parent 7614726 commit 5d7ecaf
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 30 deletions.
17 changes: 0 additions & 17 deletions src/components/Page/Dependency/ApplicabilityEvidence.module.css

This file was deleted.

1 change: 1 addition & 0 deletions src/components/Page/Dependency/Dependency.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ describe('Dependency page component', () => {

const expectedTexts = [
TABS.WHAT_CAN_I_DO.label,
TABS.CONTEXTUAL_ANALYSIS.label,
TABS.CVE_INFORMATION.label,
TABS.IMPACT_GRAPH.label
]
Expand Down
13 changes: 6 additions & 7 deletions src/components/Page/Dependency/Dependency.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@ import css from './Dependency.module.css'
import Header from '../../UI/Header/Header'
import { IDependencyPage } from '../../../model'
import InformationTabs, { TABS } from '../../UI/InformationTabs/InformationTabs'
import ApplicabilityEvidence from './ApplicabilityEvidence'
export interface Props {
data: IDependencyPage
}

export default function Dependency(props: Props): JSX.Element {
const showApplicabilityEvidence =
props.data.cve?.applicableData?.evidence ?? props.data.cve?.applicableData?.searchTarget
return (
<div className={css.PageContainer}>
<Header pageData={props.data} text={props.data.cve?.id ? props.data.cve.id : props.data.id} />
{props.data.cve?.applicableData && showApplicabilityEvidence && (
<ApplicabilityEvidence data={props.data.cve.applicableData} />
)}
<InformationTabs
data={props.data}
tabs={[TABS.WHAT_CAN_I_DO.key, TABS.CVE_INFORMATION.key, TABS.IMPACT_GRAPH.key]}
tabs={[
TABS.WHAT_CAN_I_DO.key,
TABS.CVE_INFORMATION.key,
TABS.IMPACT_GRAPH.key,
TABS.CONTEXTUAL_ANALYSIS.key
]}
/>
</div>
)
Expand Down
41 changes: 41 additions & 0 deletions src/components/UI/InformationTabs/ApplicabilityEvidence.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.rowList {
display: flex;
flex-direction: column;
gap: 16px;
}
.defaultContainer {
display: flex;
flex-direction: column;
gap: 16px;
}
.subtitle {
color: #f0f0f0;
font-size: 12px;
font-style: normal;
font-weight: 600;
line-height: normal;
}

ul.bulletList {
list-style-type: disc;
padding-left: 20px;
}
ul.bulletList li {
color: white;
font-family: 'Arial', sans-serif;
margin-bottom: 10px;
display: flex;
align-items: center;
}
ul {
list-style-type: disc;
margin-left: 20px;
}

ol {
list-style-type: decimal;
margin-left: 20px;
}
li {
margin-bottom: 20px;
}
80 changes: 80 additions & 0 deletions src/components/UI/InformationTabs/ApplicabilityEvidence.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { render, screen } from '@testing-library/react'
import ApplicabilityEvidence from './ApplicabilityEvidence'
import { IApplicableDetails, IEvidence } from '../../../model'

// Sample data for testing
const applicableData: IApplicableDetails = {
isApplicable: true,
searchTarget: 'Example search target',
evidence: [
{
filePathEvidence: 'file/path/evidence',
codeEvidence: 'const example = "example";',
reason: 'Reason for applicability'
} as IEvidence
]
}

const notApplicableData: IApplicableDetails = {
isApplicable: false,
searchTarget: 'Example search target',
evidence: [
{
reason: 'Reason for non-applicability'
} as IEvidence
]
}

describe('ApplicabilityEvidence component', () => {
test('renders applicable CVE information correctly', () => {
render(<ApplicabilityEvidence data={applicableData} />)
expect(screen.getByText('Contextual Analysis')).toBeInTheDocument()
expect(screen.getByText('Why is this CVE applicable?')).toBeInTheDocument()
expect(screen.getByText('Reason for applicability')).toBeInTheDocument()
expect(screen.getByText('file/path/evidence')).toBeInTheDocument()
expect(screen.getByText('const example = "example";')).toBeInTheDocument()
expect(screen.getByText('What does the scanner check/look for?')).toBeInTheDocument()
expect(screen.getByText('Example search target')).toBeInTheDocument()
})

test('renders non-applicable CVE information correctly', () => {
render(<ApplicabilityEvidence data={notApplicableData} />)
expect(screen.getByText('Contextual Analysis')).toBeInTheDocument()
expect(screen.getByText('Why is this CVE not applicable?')).toBeInTheDocument()
expect(screen.getByText('Reason for non-applicability')).toBeInTheDocument()
expect(screen.getByText('What does the scanner check/look for?')).toBeInTheDocument()
expect(screen.getByText('Example search target')).toBeInTheDocument()
})

test('renders evidence section correctly when no evidence provided', () => {
const noEvidenceData: IApplicableDetails = {
isApplicable: true,
searchTarget: 'Example search target',
evidence: []
}
render(<ApplicabilityEvidence data={noEvidenceData} />)
expect(screen.getByText('Contextual Analysis')).toBeInTheDocument()
expect(screen.getByText('Why is this CVE applicable?')).toBeInTheDocument()
expect(screen.getByText('What does the scanner check/look for?')).toBeInTheDocument()
expect(screen.getByText('Example search target')).toBeInTheDocument()
})

test('renders correctly without searchTarget', () => {
const noSearchTargetData: IApplicableDetails = {
isApplicable: true,
evidence: [
{
filePathEvidence: 'file/path/evidence',
codeEvidence: 'const example = "example";',
reason: 'Reason for applicability'
} as IEvidence
]
}
render(<ApplicabilityEvidence data={noSearchTargetData} />)
expect(screen.getByText('Contextual Analysis')).toBeInTheDocument()
expect(screen.getByText('Why is this CVE applicable?')).toBeInTheDocument()
expect(screen.getByText('file/path/evidence')).toBeInTheDocument()
expect(screen.getByText('const example = "example";')).toBeInTheDocument()
expect(screen.queryByText('What does the scanner check/look for?')).not.toBeInTheDocument()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ export default function ApplicabilityEvidence(props: Props): JSX.Element {
expanded
header={
<h1>
<EvidenceSvg /> Applicability Evidence
<EvidenceSvg /> Contextual Analysis
</h1>
}
>
<div className={css.defaultContainer}>
{props.data.isApplicable && (
{/* If CVE is applicable */}
{props.data.isApplicable ? (
<>
<h6 className={css.subtitle}>Why is this CVE applicable?</h6>
<div>
Expand All @@ -37,6 +38,21 @@ export default function ApplicabilityEvidence(props: Props): JSX.Element {
</div>
<Divider />
</>
) : (
// If CVE is not applicable
<>
<h6 className={css.subtitle}>Why is this CVE not applicable?</h6>
<div>
<div className={css.rowList}>
{props.data.evidence?.map((evidence, i) => (
<div key={i}>
<Row title="Reason" data={evidence.reason} />
</div>
))}
</div>
</div>
<Divider />
</>
)}
{props.data.searchTarget && (
<>
Expand Down
7 changes: 6 additions & 1 deletion src/components/UI/InformationTabs/InformationTabs.module.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
.tabsContainer {
display: flex;
flex-direction: column;
gap: 16px;
justify-content: space-between;
gap: 8px;
flex-wrap: wrap;
overflow: hidden;
}

.container {
display: flex;
flex-direction: column;
align-items: flex-start;
flex: 1;
text-align: center;
gap: 16px;
width: 100%;
cursor: pointer;
}

.alignCenterFlex {
Expand Down
31 changes: 28 additions & 3 deletions src/components/UI/InformationTabs/InformationTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { TreeNode } from '../../../model/treeNode'
import { toTreeNode } from '../../../utils/utils'
import WhatCanIDoTab from './WhatCanIDoTab'
import Markdown from '../Markdown/Markdown'
import ApplicabilityEvidence from './ApplicabilityEvidence'

export const TABS = {
WHAT_CAN_I_DO: {
Expand All @@ -40,6 +41,10 @@ export const TABS = {
IMPACT_GRAPH: {
label: 'Impact Graph',
key: 'impact_graph'
},
CONTEXTUAL_ANALYSIS: {
label: 'Contextual Analysis',
key: 'contextual_analysis'
}
}
export const LABELS = {
Expand Down Expand Up @@ -138,6 +143,12 @@ function InformationTabs(props: Props): JSX.Element {

const showMoreInformationTab =
props.tabs.includes(TABS.MORE_INFORMATION.key) && (props.data as ISastPage).description
const pageTypeDependency = props.data as IDependencyPage
const showApplicabilityEvidence =
pageTypeDependency.cve?.applicableData?.evidence ??
pageTypeDependency.cve?.applicableData?.searchTarget
const showContextualAnalysisTab =
showApplicabilityEvidence && props.tabs.includes(TABS.CONTEXTUAL_ANALYSIS.key)

return (
<div className={css.tabsContainer}>
Expand All @@ -154,6 +165,13 @@ function InformationTabs(props: Props): JSX.Element {
label={TABS.WHAT_CAN_I_DO.label}
/>
)}
{showContextualAnalysisTab && (
<Tab
className={tabClass(TABS.CONTEXTUAL_ANALYSIS.key)}
value={TABS.CONTEXTUAL_ANALYSIS.key}
label={TABS.CONTEXTUAL_ANALYSIS.label}
/>
)}
{showCveInformationTab && (
<Tab
className={tabClass(TABS.CVE_INFORMATION.key)}
Expand All @@ -180,13 +198,20 @@ function InformationTabs(props: Props): JSX.Element {
<CustomTabPanel value={selectedTabIndex} index={TABS.WHAT_CAN_I_DO.key}>
<WhatCanIDoTab
pageType={props.data.pageType}
component={(props.data as IDependencyPage).component}
impactGraph={(props.data as IDependencyPage).impactGraph}
fixedVersion={(props.data as IDependencyPage).fixedVersion}
component={pageTypeDependency.component}
impactGraph={pageTypeDependency.impactGraph}
fixedVersion={pageTypeDependency.fixedVersion}
remediation={remediation}
/>
</CustomTabPanel>
)}
{showContextualAnalysisTab && (
<CustomTabPanel value={selectedTabIndex} index={TABS.CONTEXTUAL_ANALYSIS.key}>
{pageTypeDependency.cve?.applicableData && showApplicabilityEvidence && (
<ApplicabilityEvidence data={pageTypeDependency.cve.applicableData} />
)}
</CustomTabPanel>
)}
{showMoreInformationTab && (
<CustomTabPanel value={selectedTabIndex} index={TABS.MORE_INFORMATION.key}>
<Collapse
Expand Down

0 comments on commit 5d7ecaf

Please sign in to comment.