mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 13:22:11 +03:00
* feat(providers): live monthly credit quota for Firecrawl Wire Firecrawl team credits into Provider Limits / preflight via GET /v2/team/credit-usage (Bearer API key) - firecrawlQuotaFetcher + usage/firecrawl leaf - USAGE_FETCHER_PROVIDERS + USAGE_SUPPORTED_PROVIDERS + apikey allowlist - register via quotaTrackersBatch - unit tests for fetcher + usage dispatch * chore(changelog) - add changelog on live monthly credit quota for Firecrawl * fix(providers): satisfy provider limits file-size gate --------- Co-authored-by: allanvb <allanvb@users.noreply.github.com>
163 lines
5.4 KiB
TypeScript
163 lines
5.4 KiB
TypeScript
/**
|
|
* tests/unit/firecrawl-usage.test.ts
|
|
*
|
|
* Firecrawl usage.ts dispatch + Provider Limits allowlists for team credits.
|
|
*/
|
|
|
|
import { describe, it, afterEach } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
const { __testing, USAGE_FETCHER_PROVIDERS, getUsageForProvider } =
|
|
await import("../../open-sse/services/usage.ts");
|
|
const { invalidateFirecrawlQuotaCache } =
|
|
await import("../../open-sse/services/firecrawlQuotaFetcher.ts");
|
|
const { USAGE_SUPPORTED_PROVIDERS } = await import("../../src/shared/constants/providers.ts");
|
|
const { isSupportedUsageConnection } = await import("../../src/lib/usage/providerLimits.ts");
|
|
const { getFirecrawlUsage } = __testing;
|
|
|
|
const originalFetch = globalThis.fetch;
|
|
|
|
function creditUsageResponse(remaining: number, plan: number, endIso?: string) {
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: true,
|
|
data: {
|
|
remainingCredits: remaining,
|
|
planCredits: plan,
|
|
billingPeriodEnd: endIso || "2026-07-31T23:59:59Z",
|
|
},
|
|
}),
|
|
{ status: 200, headers: { "content-type": "application/json" } }
|
|
);
|
|
}
|
|
|
|
describe("Firecrawl usage dispatch", () => {
|
|
afterEach(() => {
|
|
globalThis.fetch = originalFetch;
|
|
invalidateFirecrawlQuotaCache("conn-fc");
|
|
invalidateFirecrawlQuotaCache("conn-live");
|
|
});
|
|
|
|
it("registers firecrawl in USAGE_FETCHER_PROVIDERS and USAGE_SUPPORTED_PROVIDERS", () => {
|
|
assert.ok((USAGE_FETCHER_PROVIDERS as readonly string[]).includes("firecrawl"));
|
|
assert.ok((USAGE_SUPPORTED_PROVIDERS as readonly string[]).includes("firecrawl"));
|
|
});
|
|
|
|
it("isSupportedUsageConnection accepts firecrawl apikey connections", () => {
|
|
assert.equal(
|
|
isSupportedUsageConnection({
|
|
id: "c1",
|
|
provider: "firecrawl",
|
|
authType: "apikey",
|
|
}),
|
|
true
|
|
);
|
|
});
|
|
|
|
it("getFirecrawlUsage maps live credit-usage into monthly quota", async () => {
|
|
globalThis.fetch = async () => creditUsageResponse(250, 1000);
|
|
|
|
const r = (await getFirecrawlUsage("conn-live", "fc-key")) as {
|
|
plan?: string;
|
|
message?: string;
|
|
quotas?: {
|
|
monthly?: {
|
|
used: number;
|
|
total: number;
|
|
remaining?: number;
|
|
resetAt: string | null;
|
|
};
|
|
};
|
|
remainingCredits?: number;
|
|
};
|
|
|
|
assert.ok(r.quotas?.monthly, `expected quotas, got: ${JSON.stringify(r)}`);
|
|
assert.match(r.plan || "", /Firecrawl/i);
|
|
assert.equal(r.quotas!.monthly!.used, 750);
|
|
assert.equal(r.quotas!.monthly!.total, 1000);
|
|
assert.equal(r.quotas!.monthly!.remaining, 250);
|
|
assert.equal(r.remainingCredits, 250);
|
|
assert.ok(r.quotas!.monthly!.resetAt?.includes("2026-07-31"));
|
|
});
|
|
|
|
it("getFirecrawlUsage reports over-plan remaining credits as more than 100% left", async () => {
|
|
globalThis.fetch = async () => creditUsageResponse(1500, 1000);
|
|
|
|
const r = (await getFirecrawlUsage("conn-live", "fc-key")) as {
|
|
quotas?: {
|
|
monthly?: {
|
|
used: number;
|
|
total: number;
|
|
remaining?: number;
|
|
remainingPercentage?: number;
|
|
extraCreditsInferred?: number;
|
|
overPlan?: boolean;
|
|
};
|
|
};
|
|
remainingCredits?: number;
|
|
planCredits?: number;
|
|
extraCreditsInferred?: number;
|
|
};
|
|
|
|
assert.equal(r.quotas?.monthly?.used, 0);
|
|
assert.equal(r.quotas?.monthly?.total, 1000);
|
|
assert.equal(r.quotas?.monthly?.remaining, 1500);
|
|
assert.equal(r.quotas?.monthly?.remainingPercentage, 150);
|
|
assert.equal(r.quotas?.monthly?.overPlan, true);
|
|
assert.equal(r.quotas?.monthly?.extraCreditsInferred, 500);
|
|
assert.equal(r.extraCreditsInferred, 500);
|
|
});
|
|
|
|
it("getFirecrawlUsage keeps the plan baseline stable as over-plan credits are spent", async () => {
|
|
globalThis.fetch = async () => creditUsageResponse(1450, 1000);
|
|
|
|
const r = (await getFirecrawlUsage("conn-live", "fc-key")) as {
|
|
quotas?: {
|
|
monthly?: {
|
|
used: number;
|
|
total: number;
|
|
remaining?: number;
|
|
remainingPercentage?: number;
|
|
extraCreditsInferred?: number;
|
|
};
|
|
};
|
|
};
|
|
|
|
assert.equal(r.quotas?.monthly?.used, 0);
|
|
assert.equal(r.quotas?.monthly?.total, 1000);
|
|
assert.equal(r.quotas?.monthly?.remaining, 1450);
|
|
assert.equal(r.quotas?.monthly?.remainingPercentage, 145);
|
|
assert.equal(r.quotas?.monthly?.extraCreditsInferred, 450);
|
|
});
|
|
|
|
it("getFirecrawlUsage returns message when live quota unavailable", async () => {
|
|
globalThis.fetch = async () => new Response("Unauthorized", { status: 401 });
|
|
const r = (await getFirecrawlUsage("conn-fc", "dead")) as {
|
|
message?: string;
|
|
quotas?: unknown;
|
|
};
|
|
assert.ok(r.message && !r.quotas);
|
|
});
|
|
|
|
it("getFirecrawlUsage returns message when connection id missing", async () => {
|
|
const r = (await getFirecrawlUsage("", "key")) as { message?: string; quotas?: unknown };
|
|
assert.ok(r.message && !r.quotas);
|
|
});
|
|
|
|
it("getUsageForProvider('firecrawl', ...) delegates to getFirecrawlUsage", async () => {
|
|
globalThis.fetch = async () => creditUsageResponse(100, 500);
|
|
|
|
const r = (await getUsageForProvider({
|
|
id: "conn-live",
|
|
provider: "firecrawl",
|
|
apiKey: "dispatch-key",
|
|
} as Parameters<typeof getUsageForProvider>[0])) as {
|
|
quotas?: { monthly?: { used: number; total: number; remaining?: number } };
|
|
};
|
|
|
|
assert.equal(r.quotas?.monthly?.used, 400);
|
|
assert.equal(r.quotas?.monthly?.total, 500);
|
|
assert.equal(r.quotas?.monthly?.remaining, 100);
|
|
});
|
|
});
|