session-manager-helpers.test.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import { describe, expect, test, vi } from "vitest";
  2. const loggerWarnMock = vi.fn();
  3. const PARSE_HEADER_RECORD_WARN_MESSAGE = "SessionManager: Failed to parse header record JSON";
  4. function getParseHeaderRecordWarnCalls(): unknown[][] {
  5. return loggerWarnMock.mock.calls.filter((call) => call[0] === PARSE_HEADER_RECORD_WARN_MESSAGE);
  6. }
  7. vi.mock("server-only", () => ({}));
  8. vi.mock("@/lib/logger", () => ({
  9. logger: {
  10. warn: loggerWarnMock,
  11. trace: vi.fn(),
  12. info: vi.fn(),
  13. error: vi.fn(),
  14. },
  15. }));
  16. const sanitizeHeadersMock = vi.fn();
  17. vi.mock("@/app/v1/_lib/proxy/errors", () => ({
  18. sanitizeHeaders: sanitizeHeadersMock,
  19. }));
  20. async function loadHelpers() {
  21. const mod = await import("@/lib/session-manager");
  22. return {
  23. headersToSanitizedObject: mod.headersToSanitizedObject,
  24. parseHeaderRecord: mod.parseHeaderRecord,
  25. };
  26. }
  27. describe("SessionManager 辅助函数", () => {
  28. test("parseHeaderRecord:有效 JSON 对象应解析为记录", async () => {
  29. vi.clearAllMocks();
  30. const { parseHeaderRecord } = await loadHelpers();
  31. expect(parseHeaderRecord('{"a":"1","b":"2"}')).toEqual({ a: "1", b: "2" });
  32. expect(getParseHeaderRecordWarnCalls()).toHaveLength(0);
  33. });
  34. test("parseHeaderRecord:空对象应返回空记录", async () => {
  35. vi.clearAllMocks();
  36. const { parseHeaderRecord } = await loadHelpers();
  37. expect(parseHeaderRecord("{}")).toEqual({});
  38. expect(getParseHeaderRecordWarnCalls()).toHaveLength(0);
  39. });
  40. test("parseHeaderRecord:只保留字符串值", async () => {
  41. vi.clearAllMocks();
  42. const { parseHeaderRecord } = await loadHelpers();
  43. expect(parseHeaderRecord('{"a":"1","b":2,"c":true,"d":null,"e":{},"f":[]}')).toEqual({
  44. a: "1",
  45. });
  46. expect(getParseHeaderRecordWarnCalls()).toHaveLength(0);
  47. });
  48. test("parseHeaderRecord:无效 JSON 应返回 null 并记录 warn", async () => {
  49. vi.clearAllMocks();
  50. const { parseHeaderRecord } = await loadHelpers();
  51. expect(parseHeaderRecord("{bad json")).toBe(null);
  52. const calls = getParseHeaderRecordWarnCalls();
  53. expect(calls).toHaveLength(1);
  54. const [message, meta] = calls[0] ?? [];
  55. expect(message).toBe("SessionManager: Failed to parse header record JSON");
  56. expect(meta).toEqual(expect.objectContaining({ error: expect.anything() }));
  57. });
  58. test("parseHeaderRecord:JSON 数组/null/原始值应返回 null", async () => {
  59. vi.clearAllMocks();
  60. const { parseHeaderRecord } = await loadHelpers();
  61. expect(parseHeaderRecord('["a"]')).toBe(null);
  62. expect(parseHeaderRecord("null")).toBe(null);
  63. expect(parseHeaderRecord("1")).toBe(null);
  64. expect(getParseHeaderRecordWarnCalls()).toHaveLength(0);
  65. });
  66. test("headersToSanitizedObject:单个 header 应正确转换", async () => {
  67. vi.clearAllMocks();
  68. const { headersToSanitizedObject } = await loadHelpers();
  69. const headers = new Headers({ "x-test": "1" });
  70. sanitizeHeadersMock.mockReturnValueOnce("x-test: 1");
  71. expect(headersToSanitizedObject(headers)).toEqual({ "x-test": "1" });
  72. expect(sanitizeHeadersMock).toHaveBeenCalledWith(headers);
  73. });
  74. test("headersToSanitizedObject:多个 header 应正确转换", async () => {
  75. vi.clearAllMocks();
  76. const { headersToSanitizedObject } = await loadHelpers();
  77. const headers = new Headers({ a: "1", b: "2" });
  78. sanitizeHeadersMock.mockReturnValueOnce("a: 1\nb: 2");
  79. expect(headersToSanitizedObject(headers)).toEqual({ a: "1", b: "2" });
  80. expect(sanitizeHeadersMock).toHaveBeenCalledWith(headers);
  81. });
  82. test("headersToSanitizedObject:空 Headers 应返回空对象", async () => {
  83. vi.clearAllMocks();
  84. const { headersToSanitizedObject } = await loadHelpers();
  85. const headers = new Headers();
  86. sanitizeHeadersMock.mockReturnValueOnce("(empty)");
  87. expect(headersToSanitizedObject(headers)).toEqual({});
  88. expect(sanitizeHeadersMock).toHaveBeenCalledWith(headers);
  89. });
  90. test("headersToSanitizedObject:值包含冒号时应保留完整值", async () => {
  91. vi.clearAllMocks();
  92. const { headersToSanitizedObject } = await loadHelpers();
  93. const headers = new Headers({ "x-test": "a:b:c" });
  94. sanitizeHeadersMock.mockReturnValueOnce("x-test: a:b:c");
  95. expect(headersToSanitizedObject(headers)).toEqual({ "x-test": "a:b:c" });
  96. expect(sanitizeHeadersMock).toHaveBeenCalledWith(headers);
  97. });
  98. });