Files
2026-07-13 13:39:12 +08:00

90 lines
3.0 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
parseBulkApiKeys,
BULK_API_KEY_MAX_LINES,
} from "../../src/shared/utils/bulkApiKeyParser.ts";
test("parses name|apiKey lines", () => {
const { entries, warnings } = parseBulkApiKeys("prod|sk-1\nstaging|sk-2");
assert.equal(warnings.length, 0);
assert.deepEqual(entries, [
{ name: "prod", apiKey: "sk-1", lineNumber: 1 },
{ name: "staging", apiKey: "sk-2", lineNumber: 2 },
]);
});
test("auto-names lines without pipe (Key 1, Key 2, ...)", () => {
const { entries } = parseBulkApiKeys("sk-a\nsk-b\nsk-c");
assert.deepEqual(
entries.map((e) => e.name),
["Key 1", "Key 2", "Key 3"]
);
});
test("auto-name index only advances on unnamed lines", () => {
const { entries } = parseBulkApiKeys("named|sk-1\nsk-2\nnamed2|sk-3\nsk-4");
assert.deepEqual(
entries.map((e) => e.name),
["named", "Key 1", "named2", "Key 2"]
);
});
test("apiKey may contain | — only first separator counts", () => {
const { entries } = parseBulkApiKeys("key1|sk-with|pipe|inside");
assert.equal(entries.length, 1);
assert.equal(entries[0].name, "key1");
assert.equal(entries[0].apiKey, "sk-with|pipe|inside");
});
test("skips blank lines and # comments", () => {
const { entries } = parseBulkApiKeys("# header\nsk-1\n\n# inline comment\nsk-2");
assert.equal(entries.length, 2);
assert.equal(entries[0].lineNumber, 2);
assert.equal(entries[1].lineNumber, 5);
});
test("handles CRLF line endings", () => {
const { entries } = parseBulkApiKeys("prod|sk-1\r\nstaging|sk-2\r\n");
assert.equal(entries.length, 2);
});
test("warns on empty apiKey after pipe", () => {
const { entries, warnings } = parseBulkApiKeys("prod|\nstaging|sk-2");
assert.equal(entries.length, 1);
assert.equal(entries[0].name, "staging");
assert.equal(warnings.length, 1);
assert.match(warnings[0], /Line 1.*empty apiKey/);
});
test("empty name falls back to auto-name", () => {
const { entries } = parseBulkApiKeys("|sk-1");
assert.equal(entries[0].name, "Key 1");
assert.equal(entries[0].apiKey, "sk-1");
});
test("trims whitespace around name and apiKey", () => {
const { entries } = parseBulkApiKeys(" prod | sk-1 ");
assert.equal(entries[0].name, "prod");
assert.equal(entries[0].apiKey, "sk-1");
});
test("empty input returns empty entries", () => {
const { entries, warnings } = parseBulkApiKeys("");
assert.equal(entries.length, 0);
assert.equal(warnings.length, 0);
});
test("only whitespace returns empty entries", () => {
const { entries } = parseBulkApiKeys(" \n\t\n \n");
assert.equal(entries.length, 0);
});
test("input exceeding cap is truncated with warning", () => {
const lines = Array.from({ length: BULK_API_KEY_MAX_LINES + 5 }, (_, i) => `sk-${i}`);
const { entries, warnings } = parseBulkApiKeys(lines.join("\n"));
assert.equal(entries.length, BULK_API_KEY_MAX_LINES);
assert.equal(warnings.length, 1);
assert.match(warnings[0], /only the first/);
});