Skip to content

Commit b2b9354

Browse files
committed
chore: tests
1 parent 2d78f6f commit b2b9354

2 files changed

Lines changed: 250 additions & 0 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import { describe, expect, it } from 'vitest'
2+
import type { PackageVulnerabilities } from '../../shared/types'
3+
import {
4+
getVulnerabilityTooltip,
5+
getVulnerabilitySeverityClass,
6+
} from '../../app/composables/useVulnerableDependencies'
7+
8+
const mockVulnerabilities: PackageVulnerabilities = {
9+
package: 'test-pkg',
10+
version: '1.0.0',
11+
vulnerabilities: [
12+
{
13+
id: 'GHSA-1234',
14+
summary: 'Test vuln 1',
15+
severity: 'critical',
16+
aliases: ['CVE-2024-1234'],
17+
url: 'https://example.com/1',
18+
},
19+
{
20+
id: 'GHSA-5678',
21+
summary: 'Test vuln 2',
22+
severity: 'high',
23+
aliases: [],
24+
url: 'https://example.com/2',
25+
},
26+
],
27+
counts: { total: 2, critical: 1, high: 1, moderate: 0, low: 0 },
28+
}
29+
30+
describe('vulnerability helpers', () => {
31+
describe('getVulnerabilityTooltip', () => {
32+
it('formats single vulnerability correctly', () => {
33+
const info: PackageVulnerabilities = {
34+
package: 'pkg',
35+
version: '1.0.0',
36+
vulnerabilities: [
37+
{ id: 'GHSA-1234', summary: 'Test', severity: 'high', aliases: [], url: '' },
38+
],
39+
counts: { total: 1, critical: 0, high: 1, moderate: 0, low: 0 },
40+
}
41+
const tooltip = getVulnerabilityTooltip(info)
42+
expect(tooltip).toContain('1 vulnerability')
43+
expect(tooltip).toContain('1 high')
44+
expect(tooltip).toContain('GHSA-1234')
45+
})
46+
47+
it('formats multiple vulnerabilities correctly', () => {
48+
const tooltip = getVulnerabilityTooltip(mockVulnerabilities)
49+
expect(tooltip).toContain('2 vulnerabilities')
50+
expect(tooltip).toContain('1 critical')
51+
expect(tooltip).toContain('1 high')
52+
})
53+
54+
it('includes vulnerability IDs in tooltip', () => {
55+
const tooltip = getVulnerabilityTooltip(mockVulnerabilities)
56+
expect(tooltip).toContain('GHSA-1234')
57+
expect(tooltip).toContain('GHSA-5678')
58+
})
59+
60+
it('limits IDs to 3', () => {
61+
const info: PackageVulnerabilities = {
62+
package: 'pkg',
63+
version: '1.0.0',
64+
vulnerabilities: [
65+
{ id: 'GHSA-1', summary: '', severity: 'low', aliases: [], url: '' },
66+
{ id: 'GHSA-2', summary: '', severity: 'low', aliases: [], url: '' },
67+
{ id: 'GHSA-3', summary: '', severity: 'low', aliases: [], url: '' },
68+
{ id: 'GHSA-4', summary: '', severity: 'low', aliases: [], url: '' },
69+
],
70+
counts: { total: 4, critical: 0, high: 0, moderate: 0, low: 4 },
71+
}
72+
const tooltip = getVulnerabilityTooltip(info)
73+
expect(tooltip).toContain('GHSA-1')
74+
expect(tooltip).toContain('GHSA-2')
75+
expect(tooltip).toContain('GHSA-3')
76+
expect(tooltip).not.toContain('GHSA-4')
77+
})
78+
79+
it('handles all severity levels', () => {
80+
const info: PackageVulnerabilities = {
81+
package: 'pkg',
82+
version: '1.0.0',
83+
vulnerabilities: [],
84+
counts: { total: 10, critical: 2, high: 3, moderate: 4, low: 1 },
85+
}
86+
const tooltip = getVulnerabilityTooltip(info)
87+
expect(tooltip).toContain('2 critical')
88+
expect(tooltip).toContain('3 high')
89+
expect(tooltip).toContain('4 moderate')
90+
expect(tooltip).toContain('1 low')
91+
})
92+
93+
it('excludes zero counts from breakdown', () => {
94+
const info: PackageVulnerabilities = {
95+
package: 'pkg',
96+
version: '1.0.0',
97+
vulnerabilities: [],
98+
counts: { total: 1, critical: 0, high: 0, moderate: 1, low: 0 },
99+
}
100+
const tooltip = getVulnerabilityTooltip(info)
101+
expect(tooltip).not.toContain('critical')
102+
expect(tooltip).not.toContain('high')
103+
expect(tooltip).toContain('moderate')
104+
expect(tooltip).not.toContain('low')
105+
})
106+
})
107+
108+
describe('getVulnerabilitySeverityClass', () => {
109+
it('returns critical color for critical severity', () => {
110+
const info: PackageVulnerabilities = {
111+
package: 'pkg',
112+
version: '1.0.0',
113+
vulnerabilities: [],
114+
counts: { total: 1, critical: 1, high: 0, moderate: 0, low: 0 },
115+
}
116+
expect(getVulnerabilitySeverityClass(info)).toContain('red')
117+
})
118+
119+
it('returns high color for high severity', () => {
120+
const info: PackageVulnerabilities = {
121+
package: 'pkg',
122+
version: '1.0.0',
123+
vulnerabilities: [],
124+
counts: { total: 1, critical: 0, high: 1, moderate: 0, low: 0 },
125+
}
126+
expect(getVulnerabilitySeverityClass(info)).toContain('orange')
127+
})
128+
129+
it('returns moderate color for moderate severity', () => {
130+
const info: PackageVulnerabilities = {
131+
package: 'pkg',
132+
version: '1.0.0',
133+
vulnerabilities: [],
134+
counts: { total: 1, critical: 0, high: 0, moderate: 1, low: 0 },
135+
}
136+
expect(getVulnerabilitySeverityClass(info)).toContain('yellow')
137+
})
138+
139+
it('returns low color for low severity', () => {
140+
const info: PackageVulnerabilities = {
141+
package: 'pkg',
142+
version: '1.0.0',
143+
vulnerabilities: [],
144+
counts: { total: 1, critical: 0, high: 0, moderate: 0, low: 1 },
145+
}
146+
expect(getVulnerabilitySeverityClass(info)).toContain('blue')
147+
})
148+
149+
it('prioritizes highest severity', () => {
150+
const info: PackageVulnerabilities = {
151+
package: 'pkg',
152+
version: '1.0.0',
153+
vulnerabilities: [],
154+
counts: { total: 10, critical: 1, high: 5, moderate: 3, low: 1 },
155+
}
156+
expect(getVulnerabilitySeverityClass(info)).toContain('red')
157+
})
158+
})
159+
})

test/unit/severity.spec.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { describe, expect, it } from 'vitest'
2+
import {
3+
SEVERITY_COLORS,
4+
SEVERITY_TEXT_COLORS,
5+
SEVERITY_BADGE_COLORS,
6+
getHighestSeverity,
7+
} from '../../shared/utils/severity'
8+
9+
describe('severity utils', () => {
10+
describe('SEVERITY_COLORS', () => {
11+
it('has colors for all severity levels', () => {
12+
expect(SEVERITY_COLORS.critical).toBeDefined()
13+
expect(SEVERITY_COLORS.high).toBeDefined()
14+
expect(SEVERITY_COLORS.moderate).toBeDefined()
15+
expect(SEVERITY_COLORS.low).toBeDefined()
16+
expect(SEVERITY_COLORS.unknown).toBeDefined()
17+
})
18+
19+
it('critical has red colors', () => {
20+
expect(SEVERITY_COLORS.critical).toContain('red')
21+
})
22+
23+
it('high has orange colors', () => {
24+
expect(SEVERITY_COLORS.high).toContain('orange')
25+
})
26+
27+
it('moderate has yellow colors', () => {
28+
expect(SEVERITY_COLORS.moderate).toContain('yellow')
29+
})
30+
31+
it('low has blue colors', () => {
32+
expect(SEVERITY_COLORS.low).toContain('blue')
33+
})
34+
})
35+
36+
describe('SEVERITY_TEXT_COLORS', () => {
37+
it('has text colors for all severity levels', () => {
38+
expect(SEVERITY_TEXT_COLORS.critical).toContain('text-')
39+
expect(SEVERITY_TEXT_COLORS.high).toContain('text-')
40+
expect(SEVERITY_TEXT_COLORS.moderate).toContain('text-')
41+
expect(SEVERITY_TEXT_COLORS.low).toContain('text-')
42+
expect(SEVERITY_TEXT_COLORS.unknown).toContain('text-')
43+
})
44+
})
45+
46+
describe('SEVERITY_BADGE_COLORS', () => {
47+
it('has badge colors for all severity levels', () => {
48+
expect(SEVERITY_BADGE_COLORS.critical).toBeDefined()
49+
expect(SEVERITY_BADGE_COLORS.high).toBeDefined()
50+
expect(SEVERITY_BADGE_COLORS.moderate).toBeDefined()
51+
expect(SEVERITY_BADGE_COLORS.low).toBeDefined()
52+
expect(SEVERITY_BADGE_COLORS.unknown).toBeDefined()
53+
})
54+
})
55+
56+
describe('getHighestSeverity', () => {
57+
it('returns critical when critical count > 0', () => {
58+
expect(getHighestSeverity({ critical: 1, high: 0, moderate: 0, low: 0 })).toBe('critical')
59+
})
60+
61+
it('returns high when high is highest', () => {
62+
expect(getHighestSeverity({ critical: 0, high: 2, moderate: 1, low: 0 })).toBe('high')
63+
})
64+
65+
it('returns moderate when moderate is highest', () => {
66+
expect(getHighestSeverity({ critical: 0, high: 0, moderate: 3, low: 1 })).toBe('moderate')
67+
})
68+
69+
it('returns low when only low', () => {
70+
expect(getHighestSeverity({ critical: 0, high: 0, moderate: 0, low: 5 })).toBe('low')
71+
})
72+
73+
it('returns unknown when all counts are 0', () => {
74+
expect(getHighestSeverity({ critical: 0, high: 0, moderate: 0, low: 0 })).toBe('unknown')
75+
})
76+
77+
it('returns unknown for empty object', () => {
78+
expect(getHighestSeverity({})).toBe('unknown')
79+
})
80+
81+
it('prioritizes critical over all others', () => {
82+
expect(getHighestSeverity({ critical: 1, high: 10, moderate: 20, low: 30 })).toBe('critical')
83+
})
84+
85+
it('handles missing keys gracefully', () => {
86+
expect(getHighestSeverity({ high: 1 })).toBe('high')
87+
expect(getHighestSeverity({ moderate: 1 })).toBe('moderate')
88+
expect(getHighestSeverity({ low: 1 })).toBe('low')
89+
})
90+
})
91+
})

0 commit comments

Comments
 (0)