You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.8 KiB
62 lines
1.8 KiB
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
import { noteImportContention, emitResilience } from "@/lib/resilience-metrics";
|
|
import { extractMailMeta } from "@/services/imap/snapshot";
|
|
import { computeRawHash, sha256 } from "@/utils/hash";
|
|
|
|
vi.mock("@/lib/logger", () => ({
|
|
logger: {
|
|
info: vi.fn(),
|
|
warn: vi.fn(),
|
|
error: vi.fn(),
|
|
debug: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
import { logger } from "@/lib/logger";
|
|
|
|
describe("resilience metrics helpers", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("emitResilience writes stable metric name", () => {
|
|
emitResilience("idempotency.hash_collision", "error", { a: 1 });
|
|
expect(logger.error).toHaveBeenCalledWith(
|
|
expect.objectContaining({ metric: "idempotency.hash_collision", a: 1 }),
|
|
"idempotency.hash_collision",
|
|
);
|
|
});
|
|
|
|
it("noteImportContention fires on 4th hit", () => {
|
|
const id = `mail-${Date.now()}`;
|
|
for (let i = 0; i < 3; i++) noteImportContention(id);
|
|
expect(logger.warn).not.toHaveBeenCalled();
|
|
noteImportContention(id);
|
|
expect(logger.warn).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
metric: "import.contention",
|
|
mailId: id,
|
|
count: 4,
|
|
}),
|
|
"import.contention",
|
|
);
|
|
});
|
|
|
|
it("subject missing marked when empty subject", () => {
|
|
const meta = extractMailMeta({ subject: " " } as never);
|
|
expect(meta.subject).toBe("(无主题)");
|
|
expect(meta.subjectMissing).toBe(true);
|
|
});
|
|
|
|
it("hash collision salt differs from base raw_hash", () => {
|
|
const base = computeRawHash({
|
|
date: "2026-01-01T00:00:00.000Z",
|
|
from: "a@b.com",
|
|
subject: "x",
|
|
filenames: ["a.xlsx"],
|
|
});
|
|
const forked = sha256(`${base}|acc|INBOX|99`);
|
|
expect(forked).not.toEqual(base);
|
|
});
|
|
});
|