Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions packages/engine/tests/osv.test.ts
Original file line number Diff line number Diff line change
@@ -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([]);
});
});
Loading