import { describe, expect, it, vi } from "vitest" ;
import type { RuntimeEnv } from "../../runtime.js" ;
import {
addAllowlistUserEntriesFromConfigEntry,
buildAllowlistResolutionSummary,
canonicalizeAllowlistWithResolvedIds,
patchAllowlistUsersInConfigEntries,
summarizeMapping,
} from "./resolve-utils.js" ;
describe("buildAllowlistResolutionSummary" , () => {
it("returns mapping, additions, and unresolved (including missing ids)" , () => {
const resolvedUsers = [
{ input: "a" , resolved: true , id: "1" },
{ input: "b" , resolved: false },
{ input: "c" , resolved: true },
];
const result = buildAllowlistResolutionSummary(resolvedUsers);
expect(result.mapping).toEqual(["a→1" ]);
expect(result.additions).toEqual(["1" ]);
expect(result.unresolved).toEqual(["b" , "c" ]);
});
it("supports custom resolved formatting" , () => {
const resolvedUsers = [{ input: "a" , resolved: true , id: "1" , note: "x" }];
const result = buildAllowlistResolutionSummary(resolvedUsers, {
formatResolved: (entry) =>
`${entry.input}→${entry.id}${(entry as { note?: string }).note ? " (note)" : "" }`,
});
expect(result.mapping).toEqual(["a→1 (note)" ]);
});
it("supports custom unresolved formatting" , () => {
const resolvedUsers = [{ input: "a" , resolved: false , note: "missing" }];
const result = buildAllowlistResolutionSummary(resolvedUsers, {
formatUnresolved: (entry) =>
`${entry.input}${(entry as { note?: string }).note ? " (missing)" : "" }`,
});
expect(result.unresolved).toEqual(["a (missing)" ]);
});
});
describe("addAllowlistUserEntriesFromConfigEntry" , () => {
it("adds trimmed users and skips '*' and blanks" , () => {
const target = new Set<string>();
addAllowlistUserEntriesFromConfigEntry(target, { users: [" a " , "*" , "" , "b" ] });
expect(Array.from(target).toSorted()).toEqual(["a" , "b" ]);
});
it("ignores non-objects" , () => {
const target = new Set<string>(["a" ]);
addAllowlistUserEntriesFromConfigEntry(target, null );
expect(Array.from(target)).toEqual(["a" ]);
});
});
describe("canonicalizeAllowlistWithResolvedIds" , () => {
it("replaces resolved names with ids and keeps unresolved entries" , () => {
const resolvedMap = new Map([
["Alice#1234" , { input: "Alice#1234" , resolved: true , id: "111" }],
["bob" , { input: "bob" , resolved: false }],
]);
const result = canonicalizeAllowlistWithResolvedIds({
existing: ["Alice#1234" , "bob" , "222" , "*" ],
resolvedMap,
});
expect(result).toEqual(["111" , "bob" , "222" , "*" ]);
});
it("deduplicates ids after canonicalization" , () => {
const resolvedMap = new Map([["alice" , { input: "alice" , resolved: true , id: "111" }]]);
const result = canonicalizeAllowlistWithResolvedIds({
existing: ["alice" , "111" , "alice" ],
resolvedMap,
});
expect(result).toEqual(["111" ]);
});
});
describe("patchAllowlistUsersInConfigEntries" , () => {
it("supports canonicalization strategy for nested users" , () => {
const entries = {
alpha: { users: ["Alice" , "111" , "Bob" ] },
beta: { users: ["*" ] },
};
const resolvedMap = new Map([
["Alice" , { input: "Alice" , resolved: true , id: "111" }],
["Bob" , { input: "Bob" , resolved: false }],
]);
const patched = patchAllowlistUsersInConfigEntries({
entries,
resolvedMap,
strategy: "canonicalize" ,
});
expect((patched.alpha as { users: string[] }).users).toEqual(["111" , "Bob" ]);
expect((patched.beta as { users: string[] }).users).toEqual(["*" ]);
});
});
describe("summarizeMapping" , () => {
it("logs sampled resolved and unresolved entries" , () => {
const runtime: RuntimeEnv = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
summarizeMapping("demo allowlist" , ["a" , "b" , "c" , "d" , "e" , "f" , "g" ], ["x" , "y" ], runtime);
expect(runtime.log).toHaveBeenCalledWith(
"demo allowlist resolved: a, b, c, d, e, f (+1)\ndemo allowlist unresolved: x, y" ,
);
});
it("skips logging when both lists are empty" , () => {
const runtime: RuntimeEnv = {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
summarizeMapping("demo allowlist" , [], [], runtime);
expect(runtime.log).not.toHaveBeenCalled();
});
});
Messung V0.5 in Prozent C=99 H=95 G=96
¤ Dauer der Verarbeitung: 0.2 Sekunden
¤
*© Formatika GbR, Deutschland