From d84750e98809e5623646fa4de32197dbaaadb9c3 Mon Sep 17 00:00:00 2001 From: miccy <9729864+miccy@users.noreply.github.com> Date: Tue, 28 Apr 2026 12:59:03 +0000 Subject: [PATCH] test: add unit tests for osvToThreatProfile --- packages/engine/tests/osv.test.ts | 124 ++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 packages/engine/tests/osv.test.ts diff --git a/packages/engine/tests/osv.test.ts b/packages/engine/tests/osv.test.ts new file mode 100644 index 0000000..9f81e15 --- /dev/null +++ b/packages/engine/tests/osv.test.ts @@ -0,0 +1,124 @@ +import { describe, expect, test } from "bun:test"; +import { osvToThreatProfile, type OsvPackage } from "../src/ingestion/osv"; + +describe("osvToThreatProfile", () => { + const baseOsv: OsvPackage = { + id: "GHSA-xxxx-yyyy-zzzz", + modified: "2023-01-01T00:00:00Z", + published: "2023-01-01T00:00:00Z", + summary: "A vulnerability summary", + affected: [ + { + package: { + name: "test-package", + ecosystem: "npm", + }, + }, + ], + }; + + test("converts basic OSV record correctly", () => { + const result = osvToThreatProfile(baseOsv) as any; + expect(result.id).toBe(baseOsv.id); + expect(result.name).toBe("test-package"); + expect(result.ecosystem).toBe("npm"); + expect(result.severity).toBe("LOW"); // Default score 0 -> LOW + expect(result.status).toBe("UNDER_REVIEW"); + }); + + test("maps CVSS_V3 scores to severity correctly", () => { + const testCases = [ + { score: "9.5", expected: "CRITICAL" }, + { score: "9.0", expected: "CRITICAL" }, + { score: "8.9", expected: "HIGH" }, + { score: "7.0", expected: "HIGH" }, + { score: "6.9", expected: "MEDIUM" }, + { score: "4.0", expected: "MEDIUM" }, + { score: "3.9", expected: "LOW" }, + { score: "0.0", expected: "LOW" }, + ]; + + for (const { score, expected } of testCases) { + const osv = { + ...baseOsv, + severity: [{ type: "CVSS_V3", score }], + }; + const result = osvToThreatProfile(osv) as any; + expect(result.severity).toBe(expected); + } + }); + + test("handles non-CVSS_V3 severity types by defaulting to score 0", () => { + const osv = { + ...baseOsv, + severity: [{ type: "CVSS_V2", score: "10.0" }], + }; + const result = osvToThreatProfile(osv) as any; + expect(result.severity).toBe("LOW"); + }); + + test("handles missing severity array", () => { + const osv = { + ...baseOsv, + severity: undefined, + }; + const result = osvToThreatProfile(osv) as any; + expect(result.severity).toBe("LOW"); + }); + + test("uses name and ecosystem from first affected package", () => { + const osv: OsvPackage = { + ...baseOsv, + affected: [ + { package: { name: "pkg1", ecosystem: "pypi" } }, + { package: { name: "pkg2", ecosystem: "npm" } }, + ], + }; + const result = osvToThreatProfile(osv) as any; + expect(result.name).toBe("pkg1"); + expect(result.ecosystem).toBe("pypi"); + }); + + test("handles missing package information by using ID and default ecosystem", () => { + const osv: OsvPackage = { + ...baseOsv, + affected: [], + }; + const result = osvToThreatProfile(osv) as any; + expect(result.name).toBe(osv.id); + expect(result.ecosystem).toBe("npm"); + }); + + test("handles missing summary", () => { + const osv: OsvPackage = { + ...baseOsv, + summary: undefined, + }; + const result = osvToThreatProfile(osv) as any; + expect(result.description).toBe(""); + }); + + test("maps references correctly", () => { + const osv: OsvPackage = { + ...baseOsv, + references: [ + { type: "ADVISORY", url: "https://example.com/advisory" }, + { type: "WEB", url: "https://example.com/web" }, + ], + }; + const result = osvToThreatProfile(osv) as any; + expect(result.references).toEqual([ + { type: "ADVISORY", url: "https://example.com/advisory" }, + { type: "WEB", url: "https://example.com/web" }, + ]); + }); + + test("handles missing references", () => { + const osv: OsvPackage = { + ...baseOsv, + references: undefined, + }; + const result = osvToThreatProfile(osv) as any; + expect(result.references).toEqual([]); + }); +});