import {
  AppError,
  ValidationError,
  AuthenticationError,
  AuthorizationError,
  NotFoundError,
  ConflictError,
  RateLimitError,
  InternalServerError,
} from "@/lib/errors/app-error";

describe("AppError classes", () => {
  describe("AppError", () => {
    it("should create an AppError with default values", () => {
      const error = new AppError("Test error");
      expect(error.message).toBe("Test error");
      expect(error.statusCode).toBe(500);
      expect(error.isOperational).toBe(true);
      expect(error.code).toBeUndefined();
    });

    it("should create an AppError with custom values", () => {
      const error = new AppError("Custom error", 400, "CUSTOM_ERROR", false);
      expect(error.message).toBe("Custom error");
      expect(error.statusCode).toBe(400);
      expect(error.isOperational).toBe(false);
      expect(error.code).toBe("CUSTOM_ERROR");
    });
  });

  describe("ValidationError", () => {
    it("should create a ValidationError with default code", () => {
      const error = new ValidationError("Invalid input");
      expect(error.message).toBe("Invalid input");
      expect(error.statusCode).toBe(400);
      expect(error.code).toBe("VALIDATION_ERROR");
    });

    it("should create a ValidationError with custom code", () => {
      const error = new ValidationError(
        "Invalid input",
        "CUSTOM_VALIDATION_ERROR"
      );
      expect(error.message).toBe("Invalid input");
      expect(error.statusCode).toBe(400);
      expect(error.code).toBe("CUSTOM_VALIDATION_ERROR");
    });
  });

  describe("AuthenticationError", () => {
    it("should create an AuthenticationError with default message", () => {
      const error = new AuthenticationError();
      expect(error.message).toBe("未授权访问");
      expect(error.statusCode).toBe(401);
      expect(error.code).toBe("AUTHENTICATION_ERROR");
    });

    it("should create an AuthenticationError with custom message", () => {
      const error = new AuthenticationError("Custom auth error");
      expect(error.message).toBe("Custom auth error");
      expect(error.statusCode).toBe(401);
      expect(error.code).toBe("AUTHENTICATION_ERROR");
    });
  });

  describe("AuthorizationError", () => {
    it("should create an AuthorizationError with default message", () => {
      const error = new AuthorizationError();
      expect(error.message).toBe("权限不足");
      expect(error.statusCode).toBe(403);
      expect(error.code).toBe("AUTHORIZATION_ERROR");
    });
  });

  describe("NotFoundError", () => {
    it("should create a NotFoundError with default message", () => {
      const error = new NotFoundError();
      expect(error.message).toBe("资源不存在");
      expect(error.statusCode).toBe(404);
      expect(error.code).toBe("NOT_FOUND_ERROR");
    });
  });

  describe("ConflictError", () => {
    it("should create a ConflictError with default code", () => {
      const error = new ConflictError("Resource conflict");
      expect(error.message).toBe("Resource conflict");
      expect(error.statusCode).toBe(409);
      expect(error.code).toBe("CONFLICT_ERROR");
    });
  });

  describe("RateLimitError", () => {
    it("should create a RateLimitError with default message", () => {
      const error = new RateLimitError();
      expect(error.message).toBe("请求过于频繁");
      expect(error.statusCode).toBe(429);
      expect(error.code).toBe("RATE_LIMIT_ERROR");
    });
  });

  describe("InternalServerError", () => {
    it("should create an InternalServerError with default message", () => {
      const error = new InternalServerError();
      expect(error.message).toBe("服务器内部错误");
      expect(error.statusCode).toBe(500);
      expect(error.code).toBe("INTERNAL_SERVER_ERROR");
      expect(error.isOperational).toBe(false);
    });
  });

  describe("Error inheritance", () => {
    it("should be instanceof Error", () => {
      const error = new AppError("Test");
      expect(error).toBeInstanceOf(Error);
    });

    it("should be instanceof AppError", () => {
      const error = new ValidationError("Test");
      expect(error).toBeInstanceOf(AppError);
    });
  });
});
