Ctrl K
ComunidadGuías…

server/boat-errors.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { describe, expect, it } from "vitest";

import { boatErrorMessage, boatRefusal } from "./boat.ts";

const billing = {
  ok: false,
  status: 402,
  code: "billing_required",
  message: "Start the $20/month Boat plan to create sandboxes.",
  error: {
    code: "billing_required",
    details: { billingUrl: "https://boat.dev/dashboard?tab=billing", accessTier: "trial" },
  },
};

describe("boatErrorMessage", () => {
  it("passes the provider's billing message through, with its link", () => {
    const msg = boatErrorMessage(402, "boat create", billing);
    expect(msg).toContain("$20/month Boat plan");
    expect(msg).toContain("https://boat.dev/dashboard?tab=billing");
    expect(msg).not.toMatch(/\(402\)/);
  });

  it("still says something useful when the provider says nothing", () => {
    expect(boatErrorMessage(402, "boat create", {})).toMatch(/paid Boat plan/i);
  });

  it("tells you to re-paste your own key on an auth failure", () => {
    expect(boatErrorMessage(401, "boat create", { message: "unauthorized" }))
      .toBe("boat.dev rejected your Boat API key — paste a current one in Settings → API keys");
  });

  it("never asks for a token the person never pasted when Cloud Pro's included one is refused", () => {
    for (const status of [401, 403]) {
      const msg = boatErrorMessage(status, "boat create", { message: "This cloud computer key is not valid." }, true);
      expect(msg).toBe("The cloud computers included with your Cloud plan aren't available right now. Try again later.");
      expect(msg).not.toMatch(/key|paste/);
    }
    expect(boatErrorMessage(402, "boat create", { message: "Cloud computers are included with an active Cloud Pro subscription." }, true))
      .toBe("Cloud computers are included with an active Cloud Pro subscription.");
  });

  it("names the rate limit rather than a bare status", () => {
    expect(boatErrorMessage(429, "boat create", { message: "Too many sandboxes created today." })).toBe(
      "Too many sandboxes created today.",
    );
  });

  it("falls back to the status when nothing is known", () => {
    expect(boatErrorMessage(500, "boat create")).toBe("boat create failed (500)");
  });
});

describe("boatRefusal", () => {
  it("keeps the provider's status and the Admin's own code for reading the failed place", () => {
    const inactive = { ok: false, code: "subscription_inactive", message: "Cloud computers are included with an active Cloud subscription.",
      error: { code: "subscription_inactive", message: "Cloud computers are included with an active Cloud subscription.", status: 402 } };
    expect(boatRefusal(402, "boat create", inactive, true)).toMatchObject({
      message: "Cloud computers are included with an active Cloud subscription.", boatStatus: 402, boatCode: "subscription_inactive",
    });
  });

  it("never sets the status a route would answer with", () => {
    expect(boatRefusal(200, "boat create", { ok: false, message: "no sandbox" })).not.toHaveProperty("status");
    expect(boatRefusal(500, "boat create", { code: "Not A Code!" })).not.toHaveProperty("boatCode");
  });
});