/**
 * GraphQL 类型定义与工具函数测试
 *
 * 测试 types.ts 中的常量、错误码映射和工具函数。
 */

import { describe, it, expect } from "vitest";
import {
  ERROR_CODE_PREFIX,
  ERROR_CODES,
  ERROR_I18N_PREFIX,
  getErrorI18nPrefix,
} from "./types";

describe("ERROR_CODE_PREFIX", () => {
  it("应包含所有错误码前缀", () => {
    expect(ERROR_CODE_PREFIX.IAM).toBe("IAM_");
    expect(ERROR_CODE_PREFIX.CORE_EDU).toBe("CORE_EDU_");
    expect(ERROR_CODE_PREFIX.BFF_STUDENT).toBe("BFF_STUDENT_");
    expect(ERROR_CODE_PREFIX.GW).toBe("GW_");
    expect(ERROR_CODE_PREFIX.NETWORK).toBe("NETWORK_");
  });

  it("应为只读常量对象", () => {
    expect(typeof ERROR_CODE_PREFIX).toBe("object");
    expect(Object.keys(ERROR_CODE_PREFIX)).toHaveLength(5);
  });
});

describe("ERROR_CODES", () => {
  it("应包含 BFF_STUDENT 错误码", () => {
    expect(ERROR_CODES.BFF_STUDENT_UPSTREAM_UNAVAILABLE).toBe(
      "BFF_STUDENT_UPSTREAM_UNAVAILABLE",
    );
    expect(ERROR_CODES.BFF_STUDENT_FORBIDDEN).toBe("BFF_STUDENT_FORBIDDEN");
    expect(ERROR_CODES.BFF_STUDENT_NOT_FOUND).toBe("BFF_STUDENT_NOT_FOUND");
  });

  it("应包含 CORE_EDU 错误码", () => {
    expect(ERROR_CODES.CORE_EDU_EXAM_NOT_FOUND).toBe("CORE_EDU_EXAM_NOT_FOUND");
    expect(ERROR_CODES.CORE_EDU_HOMEWORK_ALREADY_SUBMITTED).toBe(
      "CORE_EDU_HOMEWORK_ALREADY_SUBMITTED",
    );
    expect(ERROR_CODES.CORE_EDU_EXAM_ALREADY_SUBMITTED).toBe(
      "CORE_EDU_EXAM_ALREADY_SUBMITTED",
    );
  });

  it("应包含 IAM 错误码", () => {
    expect(ERROR_CODES.IAM_UNAUTHORIZED).toBe("IAM_UNAUTHORIZED");
    expect(ERROR_CODES.IAM_FORBIDDEN).toBe("IAM_FORBIDDEN");
  });

  it("应包含 GW 错误码", () => {
    expect(ERROR_CODES.GW_RATE_LIMITED).toBe("GW_RATE_LIMITED");
    expect(ERROR_CODES.GW_CIRCUIT_OPEN).toBe("GW_CIRCUIT_OPEN");
  });

  it("应包含 NETWORK 错误码", () => {
    expect(ERROR_CODES.NETWORK_TIMEOUT).toBe("NETWORK_TIMEOUT");
    expect(ERROR_CODES.NETWORK_OFFLINE).toBe("NETWORK_OFFLINE");
  });

  it("所有错误码应与其前缀匹配", () => {
    const bffCodes = [
      ERROR_CODES.BFF_STUDENT_UPSTREAM_UNAVAILABLE,
      ERROR_CODES.BFF_STUDENT_AGGREGATION_FAILED,
      ERROR_CODES.BFF_STUDENT_FORBIDDEN,
      ERROR_CODES.BFF_STUDENT_NOT_FOUND,
      ERROR_CODES.BFF_STUDENT_VALIDATION_FAILED,
    ];
    bffCodes.forEach((code) => {
      expect(code.startsWith(ERROR_CODE_PREFIX.BFF_STUDENT)).toBe(true);
    });

    const coreEduCodes = [
      ERROR_CODES.CORE_EDU_EXAM_NOT_FOUND,
      ERROR_CODES.CORE_EDU_EXAM_NOT_AVAILABLE,
      ERROR_CODES.CORE_EDU_HOMEWORK_NOT_FOUND,
    ];
    coreEduCodes.forEach((code) => {
      expect(code.startsWith(ERROR_CODE_PREFIX.CORE_EDU)).toBe(true);
    });
  });
});

describe("ERROR_I18N_PREFIX", () => {
  it("应将 IAM 前缀映射到 iam.error", () => {
    expect(ERROR_I18N_PREFIX[ERROR_CODE_PREFIX.IAM]).toBe("iam.error");
  });

  it("应将 CORE_EDU 前缀映射到 coreEdu.error", () => {
    expect(ERROR_I18N_PREFIX[ERROR_CODE_PREFIX.CORE_EDU]).toBe("coreEdu.error");
  });

  it("应将 BFF_STUDENT 前缀映射到 bffStudent.error", () => {
    expect(ERROR_I18N_PREFIX[ERROR_CODE_PREFIX.BFF_STUDENT]).toBe(
      "bffStudent.error",
    );
  });

  it("应将 GW 前缀映射到 gateway.error", () => {
    expect(ERROR_I18N_PREFIX[ERROR_CODE_PREFIX.GW]).toBe("gateway.error");
  });

  it("应将 NETWORK 前缀映射到 network.error", () => {
    expect(ERROR_I18N_PREFIX[ERROR_CODE_PREFIX.NETWORK]).toBe("network.error");
  });
});

describe("getErrorI18nPrefix", () => {
  it("应为 IAM_ 前缀错误码返回 iam.error", () => {
    expect(getErrorI18nPrefix("IAM_UNAUTHORIZED")).toBe("iam.error");
    expect(getErrorI18nPrefix("IAM_FORBIDDEN")).toBe("iam.error");
  });

  it("应为 CORE_EDU_ 前缀错误码返回 coreEdu.error", () => {
    expect(getErrorI18nPrefix("CORE_EDU_EXAM_NOT_FOUND")).toBe("coreEdu.error");
    expect(getErrorI18nPrefix("CORE_EDU_HOMEWORK_NOT_FOUND")).toBe(
      "coreEdu.error",
    );
  });

  it("应为 BFF_STUDENT_ 前缀错误码返回 bffStudent.error", () => {
    expect(getErrorI18nPrefix("BFF_STUDENT_UPSTREAM_UNAVAILABLE")).toBe(
      "bffStudent.error",
    );
    expect(getErrorI18nPrefix("BFF_STUDENT_FORBIDDEN")).toBe("bffStudent.error");
  });

  it("应为 GW_ 前缀错误码返回 gateway.error", () => {
    expect(getErrorI18nPrefix("GW_RATE_LIMITED")).toBe("gateway.error");
    expect(getErrorI18nPrefix("GW_CIRCUIT_OPEN")).toBe("gateway.error");
  });

  it("应为 NETWORK_ 前缀错误码返回 network.error", () => {
    expect(getErrorI18nPrefix("NETWORK_TIMEOUT")).toBe("network.error");
    expect(getErrorI18nPrefix("NETWORK_OFFLINE")).toBe("network.error");
  });

  it("应为未知前缀错误码返回 common.error", () => {
    expect(getErrorI18nPrefix("UNKNOWN_ERROR")).toBe("common.error");
    expect(getErrorI18nPrefix("")).toBe("common.error");
  });

  it("应为空字符串返回 common.error", () => {
    expect(getErrorI18nPrefix("")).toBe("common.error");
  });
});
