mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 12:10:49 +00:00
Add tests for malware db retry
This commit is contained in:
parent
d83a381231
commit
8d2655a4bf
1 changed files with 125 additions and 0 deletions
125
packages/safe-chain/src/api/aikido.spec.js
Normal file
125
packages/safe-chain/src/api/aikido.spec.js
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
import { describe, it, mock, beforeEach } from "node:test";
|
||||
import assert from "node:assert";
|
||||
|
||||
describe("aikido API", async () => {
|
||||
const mockFetch = mock.fn();
|
||||
|
||||
mock.module("make-fetch-happen", {
|
||||
defaultExport: mockFetch,
|
||||
});
|
||||
|
||||
mock.module("../config/settings.js", {
|
||||
namedExports: {
|
||||
getEcoSystem: () => "js",
|
||||
ECOSYSTEM_JS: "js",
|
||||
ECOSYSTEM_PY: "py",
|
||||
},
|
||||
});
|
||||
|
||||
const { fetchMalwareDatabase, fetchMalwareDatabaseVersion } =
|
||||
await import("./aikido.js");
|
||||
|
||||
beforeEach(() => {
|
||||
mockFetch.mock.resetCalls();
|
||||
});
|
||||
|
||||
describe("fetchMalwareDatabase", () => {
|
||||
it("should succeed immediately when fetch succeeds on first try", async () => {
|
||||
const malwareData = [
|
||||
{ package_name: "malicious-pkg", version: "1.0.0", reason: "test" },
|
||||
];
|
||||
mockFetch.mock.mockImplementationOnce(() => ({
|
||||
ok: true,
|
||||
json: async () => malwareData,
|
||||
headers: { get: () => '"etag-123"' },
|
||||
}));
|
||||
|
||||
const result = await fetchMalwareDatabase();
|
||||
|
||||
assert.strictEqual(mockFetch.mock.calls.length, 1);
|
||||
assert.deepStrictEqual(result.malwareDatabase, malwareData);
|
||||
assert.strictEqual(result.version, '"etag-123"');
|
||||
});
|
||||
|
||||
it("should throw error after exhausting all retries", async () => {
|
||||
mockFetch.mock.mockImplementation(() => {
|
||||
throw new Error("Network error");
|
||||
});
|
||||
|
||||
await assert.rejects(() => fetchMalwareDatabase(), {
|
||||
message: "Network error",
|
||||
});
|
||||
|
||||
assert.strictEqual(mockFetch.mock.calls.length, 4);
|
||||
});
|
||||
|
||||
it("should succeed after failing 3 times and succeeding on 4th attempt", async () => {
|
||||
const malwareData = [
|
||||
{ package_name: "bad-pkg", version: "2.0.0", reason: "malware" },
|
||||
];
|
||||
let callCount = 0;
|
||||
mockFetch.mock.mockImplementation(() => {
|
||||
callCount++;
|
||||
if (callCount < 4) {
|
||||
throw new Error("Network error");
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => malwareData,
|
||||
headers: { get: () => '"etag-456"' },
|
||||
};
|
||||
});
|
||||
|
||||
const result = await fetchMalwareDatabase();
|
||||
|
||||
assert.strictEqual(mockFetch.mock.calls.length, 4);
|
||||
assert.deepStrictEqual(result.malwareDatabase, malwareData);
|
||||
assert.strictEqual(result.version, '"etag-456"');
|
||||
});
|
||||
});
|
||||
|
||||
describe("fetchMalwareDatabaseVersion", () => {
|
||||
it("should succeed immediately when fetch succeeds on first try", async () => {
|
||||
mockFetch.mock.mockImplementationOnce(() => ({
|
||||
ok: true,
|
||||
headers: { get: () => '"version-etag"' },
|
||||
}));
|
||||
|
||||
const result = await fetchMalwareDatabaseVersion();
|
||||
|
||||
assert.strictEqual(mockFetch.mock.calls.length, 1);
|
||||
assert.strictEqual(result, '"version-etag"');
|
||||
});
|
||||
|
||||
it("should throw error after exhausting all retries", async () => {
|
||||
mockFetch.mock.mockImplementation(() => {
|
||||
throw new Error("Connection refused");
|
||||
});
|
||||
|
||||
await assert.rejects(() => fetchMalwareDatabaseVersion(), {
|
||||
message: "Connection refused",
|
||||
});
|
||||
|
||||
assert.strictEqual(mockFetch.mock.calls.length, 4);
|
||||
});
|
||||
|
||||
it("should succeed after failing 3 times and succeeding on 4th attempt", async () => {
|
||||
let callCount = 0;
|
||||
mockFetch.mock.mockImplementation(() => {
|
||||
callCount++;
|
||||
if (callCount < 4) {
|
||||
throw new Error("Timeout");
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
headers: { get: () => '"final-etag"' },
|
||||
};
|
||||
});
|
||||
|
||||
const result = await fetchMalwareDatabaseVersion();
|
||||
|
||||
assert.strictEqual(mockFetch.mock.calls.length, 4);
|
||||
assert.strictEqual(result, '"final-etag"');
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue