Skip to content

Commit

Permalink
Partial Impact Graph note (#31)
Browse files Browse the repository at this point in the history
In case the Impact Graph doesn't include all of the possible paths to the vulnerable dependency, a note about that will be shown.
  • Loading branch information
asafgabai authored Aug 7, 2023
1 parent b8bc80a commit 235aad6
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 107 deletions.
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,21 @@ window.postMessage({
]
},
"impactGraph": {
"name": "jfrog-idea-plugin",
"children": [
{
"name": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.0",
"children": [
{
"name": "org.yaml:snakeyaml:1.33"
}
]
}
]
root: {
"name": "jfrog-idea-plugin",
"children": [
{
"name": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.14.0",
"children": [
{
"name": "org.yaml:snakeyaml:1.33"
}
]
}
]
},
pathsCount: 5,
pathsLimit: 1
}
}
}, '*');
Expand Down Expand Up @@ -209,4 +213,4 @@ Please follow these steps:
4. Push your changes to your forked repository.
5. Submit a pull request with a clear description of your changes.

We appreciate your contribution to making JFrog-IDE-Webview even better!.
We appreciate your contribution to making JFrog-IDE-Webview even better!
2 changes: 1 addition & 1 deletion src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('App component', () => {
componentType: 'q',
component: 'component',
version: 'version',
impactGraph: { name: 'name', children: [] } as IImpactGraph,
impactGraph: { root: { name: 'name', children: [] } } as IImpactGraph,
severity: ISeverity.High,
edited: '0'
} as IDependencyPage
Expand Down
19 changes: 14 additions & 5 deletions src/components/Page/Dependency/Dependency.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { render, screen } from '@testing-library/react'
import Dependency from './Dependency'
import { IDependencyPage, PageType } from '../../../model/webviewPages'
import { ISeverity } from '../../../model/severity'
import { IApplicableDetails, ICve, IEvidence } from '../../../model/cve'
import { IExtendedInformation } from '../../../model/extendedInformation'
import {
IDependencyPage,
PageType,
ISeverity,
IApplicableDetails,
ICve,
IEvidence,
IExtendedInformation
} from '../../../model'

describe('Dependency page component', () => {
const mockData: IDependencyPage = {
Expand Down Expand Up @@ -40,7 +45,11 @@ describe('Dependency page component', () => {
jfrogResearchSeverityReason: []
} as IExtendedInformation,
impactGraph: {
name: 'Impact Graph'
root: {
name: 'Impact Graph'
},
pathsCount: 1,
pathsLimit: 10
},
references: [{ url: 'url' }]
}
Expand Down
42 changes: 21 additions & 21 deletions src/components/Page/Dependency/Navigator/Navigator.test.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { render, screen, fireEvent } from '@testing-library/react'
import { fireEvent, render, screen } from '@testing-library/react'
import Navigator from './Navigator'
import { ISeverity } from '../../../../model/severity'
import { IDependencyPage, PageType } from '../../../../model/webviewPages'
import { IExtendedInformation } from '../../../../model/extendedInformation'
import { IDependencyPage, IExtendedInformation, ISeverity, PageType } from '../../../../model'

describe('Navigator component', () => {
const mockData: IDependencyPage = {
Expand Down Expand Up @@ -65,23 +63,25 @@ describe('Navigator component', () => {
}
],
impactGraph: {
name: 'Root',
children: [
{
name: 'Child 1',
children: [
{
name: 'Grandchild 1'
},
{
name: 'Grandchild 2'
}
]
},
{
name: 'Child 2'
}
]
root: {
name: 'Root',
children: [
{
name: 'Child 1',
children: [
{
name: 'Grandchild 1'
},
{
name: 'Grandchild 2'
}
]
},
{
name: 'Child 2'
}
]
}
}
}

Expand Down
12 changes: 9 additions & 3 deletions src/components/Page/Dependency/Navigator/PageHolder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useState, useEffect } from 'react'
import { ActiveTab } from '../../../../model/tab'
import { TreeNode } from '../../../../model/treeNode'
import { toTreeNode } from '../../../../utils/utils'
import { IDependencyPage } from '../../../../model/webviewPages'
import { IDependencyPage } from '../../../../model'

interface Props {
activeTab: ActiveTab
Expand All @@ -22,7 +22,7 @@ export default function PageHolder(props: Props): JSX.Element {
const [treeNode, setTreeNode] = useState<TreeNode | undefined>()
let pageHolder
useEffect(() => {
setTreeNode(toTreeNode(props.data.impactGraph))
setTreeNode(toTreeNode(props.data.impactGraph.root))
}, [props.data.impactGraph])

switch (props.activeTab) {
Expand All @@ -49,7 +49,13 @@ export default function PageHolder(props: Props): JSX.Element {
break
case ActiveTab.ImpactGraph:
if (treeNode) {
pageHolder = <ImpactGraph treeNode={treeNode} />
pageHolder = (
<ImpactGraph
treeNode={treeNode}
pathsCount={props.data.impactGraph.pathsCount}
pathsLimit={props.data.impactGraph.pathsLimit}
/>
)
}

break
Expand Down
10 changes: 9 additions & 1 deletion src/components/Page/Dependency/Navigator/page/ImpactGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ import TreeContainer from '../../../../UI/TreeViewer/TreeContainer'

export interface Props {
treeNode: TreeNode
pathsCount?: number
pathsLimit?: number
}

export default function ImpactGraph(props: Props): JSX.Element {
return <TreeContainer root={props.treeNode} />
return (
<TreeContainer
root={props.treeNode}
pathsCount={props.pathsCount}
pathsLimit={props.pathsLimit}
/>
)
}
19 changes: 17 additions & 2 deletions src/components/UI/TreeViewer/TreeContainer.module.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
.container {
overflow: scroll;
}

.box {
color: rgba(255, 255, 255, 0.8);
margin: 10px 0 20px 0;
}
.box > :first-child {
margin-bottom: 20px;

.text {
color: rgba(255, 255, 255, 0.8);
line-height: 1.5;
}

.noteWrapper {
border: 1px solid #454545;
border-radius: 5px;
padding: 10px;
display: inline-block;
}

.title {
font-weight: 600;
}
34 changes: 34 additions & 0 deletions src/components/UI/TreeViewer/TreeContainer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,38 @@ describe('TreeContainer component', () => {
expect(screen.queryByText('Root Node')).not.toBeInTheDocument()
})
})

test('shows a note about the tree being partial', () => {
const root: TreeNode = new TreeNode('root', 'Root Node')
const props: Props = {
root: root,
pathsCount: 15,
pathsLimit: 10
}

render(<TreeContainer {...props} />)

expect(
screen.getByText(
'Graph size limit reached. The Impact Graph shows only 10 out of 15 paths to this dependency.'
)
).toBeInTheDocument()
})

test('does not show a note about the tree being partial', () => {
const root: TreeNode = new TreeNode('root', 'Root Node')
const props: Props = {
root: root,
pathsCount: 5,
pathsLimit: 10
}

render(<TreeContainer {...props} />)

expect(
screen.queryByText(
'Graph size limit reached. The Impact Graph shows only 10 out of 15 paths to this dependency.'
)
).not.toBeInTheDocument()
})
})
30 changes: 24 additions & 6 deletions src/components/UI/TreeViewer/TreeContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import Wrapper from '../Wrapper/Wrapper'

export interface Props {
root: TreeNode
pathsCount?: number
pathsLimit?: number
}

export default function TreeContainer(props: Props): JSX.Element {
Expand All @@ -23,13 +25,25 @@ export default function TreeContainer(props: Props): JSX.Element {

return (
<>
<Wrapper headline="DESCRIPTION">
<div className={css.box}>
<div>
This graph shows the relationship between the dependencies in the project, which are
related to the vulnerable dependencies. The dependencies on the right hand side of the
graph, are requested directly by the project and marked in red are the vulnerable ones.
<Wrapper>
<div className={css.text}>
<div className={css.box}>
<span className={css.title}>About this view: </span>
<span>
This graph shows the relationships between the dependencies in the project, which are
related to the vulnerable dependency. Starting from the root on the left, it shows the
paths to the vulnerable dependency highlighted in red.
</span>
</div>
{graphSizeLimitReached(props) && (
<div className={css.noteWrapper}>
<span className={css.title}>Note: </span>
<span>
Graph size limit reached. The Impact Graph shows only {props.pathsLimit} out of{' '}
{props.pathsCount?.toLocaleString()} paths to this dependency.
</span>
</div>
)}
</div>
</Wrapper>
<Wrapper>
Expand All @@ -46,3 +60,7 @@ export default function TreeContainer(props: Props): JSX.Element {
</>
)
}

function graphSizeLimitReached(props: Props): boolean {
return (props.pathsCount && props.pathsLimit && props.pathsCount > props.pathsLimit) as boolean
}
4 changes: 2 additions & 2 deletions src/model/impactGraph.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { IImpactGraph } from './impactGraph'
import { IImpactGraphNode } from './impactGraph'

describe('Model - IImpactGraph', () => {
test('should render the component correctly', () => {
// Define your test data
const data: IImpactGraph = {
const data: IImpactGraphNode = {
name: 'Parent',
children: [
{
Expand Down
8 changes: 7 additions & 1 deletion src/model/impactGraph.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export interface IImpactGraph {
root: IImpactGraphNode
pathsCount?: number
pathsLimit?: number
}

export interface IImpactGraphNode {
name: string
children?: IImpactGraph[]
children?: IImpactGraphNode[]
}
26 changes: 15 additions & 11 deletions src/model/webviewPages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,21 @@ describe('Model - WebviewPage', () => {
],
watchName: ['Watch Name 1', 'Watch Name 2'],
impactGraph: {
name: 'Impact Graph',
children: [
{
name: 'Child 1',
children: []
},
{
name: 'Child 2',
children: []
}
]
root: {
name: 'Impact Graph',
children: [
{
name: 'Child 1',
children: []
},
{
name: 'Child 2',
children: []
}
]
},
pathsCount: 2,
pathsLimit: 10
},
severity: ISeverity.High,
edited: '2022-01-01',
Expand Down
Loading

0 comments on commit 235aad6

Please sign in to comment.