import { describe, expect, it } from "vitest";
import { ApiError, ApiHttpError, ApiTimeoutError, ApiNetworkError } from "./errors.js";

describe("ApiError", () => {
  it("extends Error with a message", () => {
    const err = new ApiError("something broke");
    expect(err).toBeInstanceOf(Error);
    expect(err).toBeInstanceOf(ApiError);
    expect(err.message).toBe("something broke");
    expect(err.name).toBe("ApiError");
  });
});

describe("ApiHttpError", () => {
  it("has status and optional body", () => {
    const err = new ApiHttpError("Not Found", 404, { detail: "missing" });
    expect(err).toBeInstanceOf(ApiError);
    expect(err).toBeInstanceOf(ApiHttpError);
    expect(err.status).toBe(404);
    expect(err.body).toEqual({ detail: "missing" });
    expect(err.name).toBe("ApiHttpError");
  });

  it("body defaults to undefined", () => {
    const err = new ApiHttpError("Server Error", 500);
    expect(err.status).toBe(500);
    expect(err.body).toBeUndefined();
  });
});

describe("ApiTimeoutError", () => {
  it("has timeoutMs", () => {
    const err = new ApiTimeoutError(5000);
    expect(err).toBeInstanceOf(ApiError);
    expect(err.timeoutMs).toBe(5000);
    expect(err.message).toContain("5000");
    expect(err.name).toBe("ApiTimeoutError");
  });
});

describe("ApiNetworkError", () => {
  it("wraps a cause", () => {
    const cause = new Error("ECONNREFUSED");
    const err = new ApiNetworkError(cause);
    expect(err).toBeInstanceOf(ApiError);
    expect(err.cause).toBe(cause);
    expect(err.name).toBe("ApiNetworkError");
  });

  it("works without a cause", () => {
    const err = new ApiNetworkError();
    expect(err.cause).toBeUndefined();
  });
});
