AikidoSec-safe-chain/packages/safe-chain/src/config/configFile.spec.js
2025-12-18 13:52:49 +01:00

322 lines
8.7 KiB
JavaScript

import { describe, it, beforeEach, afterEach, mock } from "node:test";
import assert from "node:assert";
let configFileContent = undefined;
mock.module("fs", {
namedExports: {
existsSync: () => configFileContent !== undefined,
readFileSync: () => configFileContent,
writeFileSync: (content) => (configFileContent = content),
mkdirSync: () => {},
},
});
describe("getScanTimeout", async () => {
let originalEnv;
const { getScanTimeout } = await import("./configFile.js");
beforeEach(async () => {
// Save original environment
originalEnv = process.env.AIKIDO_SCAN_TIMEOUT_MS;
});
afterEach(() => {
// Restore original environment
if (originalEnv !== undefined) {
process.env.AIKIDO_SCAN_TIMEOUT_MS = originalEnv;
} else {
delete process.env.AIKIDO_SCAN_TIMEOUT_MS;
}
configFileContent = undefined;
});
it("should return default timeout of 10000ms when no config or env var is set", () => {
delete process.env.AIKIDO_SCAN_TIMEOUT_MS;
configFileContent = undefined;
const timeout = getScanTimeout();
assert.strictEqual(timeout, 10000);
});
it("should return timeout from config file when set", () => {
delete process.env.AIKIDO_SCAN_TIMEOUT_MS;
configFileContent = JSON.stringify({ scanTimeout: 5000 });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 5000);
});
it("should prioritize environment variable over config file", () => {
process.env.AIKIDO_SCAN_TIMEOUT_MS = "20000";
configFileContent = JSON.stringify({ scanTimeout: 5000 });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 20000);
});
it("should handle invalid environment variable and fall back to config", () => {
process.env.AIKIDO_SCAN_TIMEOUT_MS = "invalid";
configFileContent = JSON.stringify({ scanTimeout: 7000 });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 7000);
});
it("should ignore zero and negative values and fall back to default", () => {
configFileContent = undefined;
process.env.AIKIDO_SCAN_TIMEOUT_MS = "0";
let timeout = getScanTimeout();
assert.strictEqual(timeout, 10000);
process.env.AIKIDO_SCAN_TIMEOUT_MS = "-5000";
timeout = getScanTimeout();
assert.strictEqual(timeout, 10000);
});
it("should ignore textual non-numeric values in environment variable and fall back to config", () => {
process.env.AIKIDO_SCAN_TIMEOUT_MS = "fast";
configFileContent = JSON.stringify({ scanTimeout: 8000 });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 8000);
});
it("should ignore textual non-numeric values in config file and fall back to default", () => {
delete process.env.AIKIDO_SCAN_TIMEOUT_MS;
configFileContent = JSON.stringify({ scanTimeout: "slow" });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 10000);
});
it("should ignore textual non-numeric values in both env and config, fall back to default", () => {
process.env.AIKIDO_SCAN_TIMEOUT_MS = "quick";
configFileContent = JSON.stringify({ scanTimeout: "medium" });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 10000);
});
it("should ignore mixed alphanumeric strings in environment variable", () => {
process.env.AIKIDO_SCAN_TIMEOUT_MS = "5000ms";
configFileContent = JSON.stringify({ scanTimeout: 6000 });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 6000);
});
it("should ignore mixed alphanumeric strings in config file", () => {
delete process.env.AIKIDO_SCAN_TIMEOUT_MS;
configFileContent = JSON.stringify({ scanTimeout: "3000ms" });
const timeout = getScanTimeout();
assert.strictEqual(timeout, 10000);
});
});
describe("getMinimumPackageAgeHours", async () => {
const { getMinimumPackageAgeHours } = await import("./configFile.js");
afterEach(() => {
configFileContent = undefined;
});
it("should return null when config file doesn't exist", () => {
configFileContent = undefined;
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, undefined);
});
it("should return null when config file exists but minimumPackageAgeHours is not set", () => {
configFileContent = JSON.stringify({ scanTimeout: 5000 });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, undefined);
});
it("should return value from config file when set to valid number", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: 48 });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, 48);
});
it("should handle string numbers in config file", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: "72" });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, 72);
});
it("should handle decimal values", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: 1.5 });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, 1.5);
});
it("should return null for non-numeric strings", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: "invalid" });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, undefined);
});
it("should return undefined for values with units suffix", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: "48h" });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, undefined);
});
it("should handle malformed JSON and return null", () => {
configFileContent = "{ invalid json";
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, undefined);
});
it("should return 0 when minimumPackageAgeHours is set to 0", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: 0 });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, 0);
});
it("should return 0 when minimumPackageAgeHours is set to string '0'", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: "0" });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, 0);
});
it("should handle negative numeric values", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: -24 });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, -24);
});
it("should handle negative string values", () => {
configFileContent = JSON.stringify({ minimumPackageAgeHours: "-48" });
const hours = getMinimumPackageAgeHours();
assert.strictEqual(hours, -48);
});
});
describe("getNpmCustomRegistries", async () => {
const { getNpmCustomRegistries } = await import("./configFile.js");
afterEach(() => {
configFileContent = undefined;
});
it("should return empty array when config file doesn't exist", () => {
configFileContent = undefined;
const registries = getNpmCustomRegistries();
assert.deepStrictEqual(registries, []);
});
it("should return empty array when npm config is not set", () => {
configFileContent = JSON.stringify({ scanTimeout: 5000 });
const registries = getNpmCustomRegistries();
assert.deepStrictEqual(registries, []);
});
it("should return empty array when customRegistries is not an array", () => {
configFileContent = JSON.stringify({
npm: { customRegistries: "not-an-array" },
});
const registries = getNpmCustomRegistries();
assert.deepStrictEqual(registries, []);
});
it("should return array of custom registries when set", () => {
configFileContent = JSON.stringify({
npm: {
customRegistries: ["npm.company.com", "registry.internal.net"],
},
});
const registries = getNpmCustomRegistries();
assert.deepStrictEqual(registries, [
"npm.company.com",
"registry.internal.net",
]);
});
it("should filter out non-string values", () => {
configFileContent = JSON.stringify({
npm: {
customRegistries: [
"npm.company.com",
123,
null,
"registry.internal.net",
undefined,
{},
],
},
});
const registries = getNpmCustomRegistries();
assert.deepStrictEqual(registries, [
"npm.company.com",
"registry.internal.net",
]);
});
it("should return empty array for empty customRegistries array", () => {
configFileContent = JSON.stringify({
npm: { customRegistries: [] },
});
const registries = getNpmCustomRegistries();
assert.deepStrictEqual(registries, []);
});
it("should handle malformed JSON and return empty array", () => {
configFileContent = "{ invalid json";
const registries = getNpmCustomRegistries();
assert.deepStrictEqual(registries, []);
});
});