1
0
Files
DiAL/tests/server/logger.test.ts

118 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, test } from "bun:test";
import type { Logger } from "../../src/server/logger";
import { createConsoleFallback, createMemoryLogger, createNoopLogger, REDACT_PATHS } from "../../src/server/logger";
describe("NoopLogger", () => {
test("所有方法不抛异常", () => {
const logger = createNoopLogger();
logger.trace("trace");
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
logger.fatal("fatal");
logger.flush();
const child = logger.child({ component: "test" });
expect(child).toBeDefined();
});
});
describe("MemoryLogger", () => {
test("记录所有等级日志", () => {
const logger = createMemoryLogger();
logger.trace("trace-msg");
logger.debug("debug-msg");
logger.info("info-msg");
logger.warn("warn-msg");
logger.error("error-msg");
logger.fatal("fatal-msg");
expect(logger.entries).toHaveLength(6);
expect(logger.entries[0]).toEqual({ level: "trace", msg: "trace-msg" });
expect(logger.entries[5]).toEqual({ level: "fatal", msg: "fatal-msg" });
});
test("记录结构化日志", () => {
const logger = createMemoryLogger();
logger.info({ matched: true, targetId: "abc" }, "check complete");
expect(logger.entries).toHaveLength(1);
expect(logger.entries[0]!.level).toBe("info");
expect(logger.entries[0]!.msg).toBe("check complete");
expect(logger.entries[0]!.obj).toEqual({ matched: true, targetId: "abc" });
});
test("child 返回自身", () => {
const logger = createMemoryLogger();
const child = logger.child({ component: "engine" });
child.info("child-msg");
expect(logger.entries).toHaveLength(1);
});
test("flush 不抛异常", () => {
const logger = createMemoryLogger();
logger.flush();
});
});
describe("ConsoleFallbackLogger", () => {
test("不抛异常", () => {
const logger = createConsoleFallback();
logger.trace("trace");
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
logger.fatal("fatal");
logger.flush();
const child = logger.child({ component: "test" });
expect(child).toBeDefined();
});
});
describe("Logger 接口契约", () => {
function assertLogger(logger: Logger): void {
logger.trace("trace");
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
logger.fatal("fatal");
logger.info({ key: "value" }, "structured");
logger.child({ component: "test" }).info("child");
logger.flush();
}
test("NoopLogger 满足 Logger 接口", () => {
expect(() => assertLogger(createNoopLogger())).not.toThrow();
});
test("MemoryLogger 满足 Logger 接口", () => {
expect(() => assertLogger(createMemoryLogger())).not.toThrow();
});
test("ConsoleFallbackLogger 满足 Logger 接口", () => {
expect(() => assertLogger(createConsoleFallback())).not.toThrow();
});
});
describe("redaction 敏感信息保护", () => {
test("MemoryLogger 不做 redaction测试用途仅 Pino 运行时 redact", () => {
const logger = createMemoryLogger();
logger.info({ authorization: "Bearer secret", password: "hunter2" }, "test");
const entry = logger.entries[0]!;
expect(entry.obj!["authorization"]).toBe("Bearer secret");
expect(entry.obj!["password"]).toBe("hunter2");
});
test("REDACT_PATHS 覆盖所有敏感字段键名", () => {
const sensitiveKeys = ["authorization", "cookie", "set-cookie", "authToken", "key", "password", "token", "apiKey"];
for (const key of sensitiveKeys) {
expect(REDACT_PATHS).toContain(key);
expect(REDACT_PATHS).toContain(`*.${key}`);
}
});
});