Skip to content

Commit 9300c97

Browse files
committed
chore: add tests
1 parent 1c63744 commit 9300c97

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

test/unit/server/utils/dependency-analysis.spec.ts

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,174 @@ describe('dependency-analysis', () => {
595595
expect(result.deprecatedPackages[2]?.depth).toBe('transitive')
596596
})
597597

598+
it('extracts correct fixedIn version for the current version range', async () => {
599+
const mockResolved = new Map([
600+
[
601+
'minimist@1.0.0',
602+
{
603+
name: 'minimist',
604+
version: '1.0.0',
605+
size: 1000,
606+
optional: false,
607+
depth: 'root' as const,
608+
path: ['minimist@1.0.0'],
609+
},
610+
],
611+
])
612+
vi.mocked(resolveDependencyTree).mockResolvedValue(mockResolved)
613+
614+
// Mock OSV response with multiple affected ranges (like minimist)
615+
// Range 1: 0 - 0.2.1, Range 2: 1.0.0 - 1.2.3
616+
// Version 1.0.0 should match Range 2, so fixedIn should be 1.2.3
617+
mockOsvApi(
618+
[{ vulns: [{ id: 'GHSA-vh95-rmgr-6w4m', modified: '2024-01-01' }] }],
619+
new Map([
620+
[
621+
'minimist@1.0.0',
622+
{
623+
vulns: [
624+
{
625+
id: 'GHSA-vh95-rmgr-6w4m',
626+
summary: 'Prototype Pollution in minimist',
627+
database_specific: { severity: 'MODERATE' },
628+
affected: [
629+
{
630+
package: { ecosystem: 'npm', name: 'minimist' },
631+
ranges: [
632+
{
633+
type: 'SEMVER',
634+
events: [{ introduced: '0' }, { fixed: '0.2.1' }],
635+
},
636+
],
637+
},
638+
{
639+
package: { ecosystem: 'npm', name: 'minimist' },
640+
ranges: [
641+
{
642+
type: 'SEMVER',
643+
events: [{ introduced: '1.0.0' }, { fixed: '1.2.3' }],
644+
},
645+
],
646+
},
647+
],
648+
},
649+
],
650+
},
651+
],
652+
]),
653+
)
654+
655+
const result = await analyzeDependencyTree('minimist', '1.0.0')
656+
657+
expect(result.vulnerablePackages).toHaveLength(1)
658+
expect(result.vulnerablePackages[0]?.vulnerabilities[0]?.fixedIn).toBe('1.2.3')
659+
})
660+
661+
it('extracts correct fixedIn for prerelease versions (e.g., 16.0.0-beta.0)', async () => {
662+
const mockResolved = new Map([
663+
[
664+
'next@16.0.0-beta.0',
665+
{
666+
name: 'next',
667+
version: '16.0.0-beta.0',
668+
size: 1000,
669+
optional: false,
670+
depth: 'root' as const,
671+
path: ['next@16.0.0-beta.0'],
672+
},
673+
],
674+
])
675+
vi.mocked(resolveDependencyTree).mockResolvedValue(mockResolved)
676+
677+
// Mock OSV response with multiple ranges including prerelease
678+
// Version 16.0.0-beta.0 should NOT match 13.0.0-15.0.8, but SHOULD match 16.0.0-beta.0-16.0.11
679+
mockOsvApi(
680+
[{ vulns: [{ id: 'GHSA-test', modified: '2024-01-01' }] }],
681+
new Map([
682+
[
683+
'next@16.0.0-beta.0',
684+
{
685+
vulns: [
686+
{
687+
id: 'GHSA-test',
688+
summary: 'Test vulnerability',
689+
database_specific: { severity: 'HIGH' },
690+
affected: [
691+
{
692+
package: { ecosystem: 'npm', name: 'next' },
693+
ranges: [
694+
{
695+
type: 'SEMVER',
696+
events: [{ introduced: '13.0.0' }, { fixed: '15.0.8' }],
697+
},
698+
],
699+
},
700+
{
701+
package: { ecosystem: 'npm', name: 'next' },
702+
ranges: [
703+
{
704+
type: 'SEMVER',
705+
events: [{ introduced: '16.0.0-beta.0' }, { fixed: '16.0.11' }],
706+
},
707+
],
708+
},
709+
],
710+
},
711+
],
712+
},
713+
],
714+
]),
715+
)
716+
717+
const result = await analyzeDependencyTree('next', '16.0.0-beta.0')
718+
719+
expect(result.vulnerablePackages).toHaveLength(1)
720+
// Should match the 16.x range, not the 13-15 range
721+
expect(result.vulnerablePackages[0]?.vulnerabilities[0]?.fixedIn).toBe('16.0.11')
722+
})
723+
724+
it('returns undefined fixedIn when no matching range has a fixed version', async () => {
725+
const mockResolved = new Map([
726+
[
727+
'pkg@1.0.0',
728+
{
729+
name: 'pkg',
730+
version: '1.0.0',
731+
size: 1000,
732+
optional: false,
733+
depth: 'root' as const,
734+
path: ['pkg@1.0.0'],
735+
},
736+
],
737+
])
738+
vi.mocked(resolveDependencyTree).mockResolvedValue(mockResolved)
739+
740+
// Mock OSV response without affected data
741+
mockOsvApi(
742+
[{ vulns: [{ id: 'GHSA-no-fix', modified: '2024-01-01' }] }],
743+
new Map([
744+
[
745+
'pkg@1.0.0',
746+
{
747+
vulns: [
748+
{
749+
id: 'GHSA-no-fix',
750+
summary: 'Vuln without fix info',
751+
database_specific: { severity: 'LOW' },
752+
// No affected field
753+
},
754+
],
755+
},
756+
],
757+
]),
758+
)
759+
760+
const result = await analyzeDependencyTree('pkg', '1.0.0')
761+
762+
expect(result.vulnerablePackages).toHaveLength(1)
763+
expect(result.vulnerablePackages[0]?.vulnerabilities[0]?.fixedIn).toBeUndefined()
764+
})
765+
598766
it('returns both vulnerabilities and deprecated packages together', async () => {
599767
const mockResolved = new Map([
600768
[

0 commit comments

Comments
 (0)