import assert from "node:assert/strict"; import { test } from "bun:test"; import { createUserBillingClient } from "./user-billing-client.ts"; test("user-billing login retries transient dependency failures only", async () => { const calls = []; const client = createUserBillingClient({ env: { HWLAB_USER_BILLING_URL: "http://user-billing.test", HWLAB_USER_BILLING_LOGIN_RETRY_ATTEMPTS: "2", HWLAB_USER_BILLING_LOGIN_RETRY_DELAY_MS: "1" }, fetchImpl: async (url, init) => { calls.push({ url: String(url), method: init?.method }); if (calls.length === 1) throw new Error("The operation timed out."); return new Response(JSON.stringify({ token: "hws_retry_ok", tokenType: "Bearer" }), { status: 200, headers: { "content-type": "application/json" } }); } }); const result = await client.login({ username: "admin", password: "redacted" }); assert.equal(result.ok, true); assert.equal(result.retryCount, 1); assert.equal(result.transientObserved, true); assert.equal(calls.length, 2); const authFailures = []; const invalidClient = createUserBillingClient({ env: { HWLAB_USER_BILLING_URL: "http://user-billing.test", HWLAB_USER_BILLING_LOGIN_RETRY_ATTEMPTS: "2", HWLAB_USER_BILLING_LOGIN_RETRY_DELAY_MS: "1" }, fetchImpl: async (url, init) => { authFailures.push({ url: String(url), method: init?.method }); return new Response(JSON.stringify({ error: { code: "invalid_credentials", message: "invalid email, username or password" } }), { status: 401, headers: { "content-type": "application/json" } }); } }); const invalid = await invalidClient.login({ username: "admin", password: "wrong" }); assert.equal(invalid.ok, false); assert.equal(invalid.status, 401); assert.equal(invalid.error.code, "invalid_credentials"); assert.equal(authFailures.length, 1); const unexpectedCalls = []; const unconfiguredClient = createUserBillingClient({ env: { HWLAB_USER_BILLING_LOGIN_RETRY_ATTEMPTS: "2", HWLAB_USER_BILLING_LOGIN_RETRY_DELAY_MS: "1" }, fetchImpl: async (url, init) => { unexpectedCalls.push({ url: String(url), method: init?.method }); throw new Error("fetch should not run without a user-billing URL"); } }); const unconfigured = await unconfiguredClient.login({ username: "admin", password: "redacted" }); assert.equal(unconfigured.ok, false); assert.equal(unconfigured.status, 503); assert.equal(unconfigured.error.code, "user_billing_not_configured"); assert.equal(unconfigured.retryable, undefined); assert.equal(unexpectedCalls.length, 0); }); test("user-billing login propagates traceparent to dependency requests", async () => { const traceparent = "00-11111111111111111111111111111111-2222222222222222-01"; const calls = []; const client = createUserBillingClient({ env: { HWLAB_USER_BILLING_URL: "http://user-billing.test" }, fetchImpl: async (url, init) => { calls.push({ url: String(url), traceparent: init?.headers?.traceparent }); return new Response(JSON.stringify({ token: "hws_trace_ok", tokenType: "Bearer" }), { status: 200, headers: { "content-type": "application/json" } }); } }); const result = await client.login({ username: "admin", password: "redacted" }, { traceparent }); assert.equal(result.ok, true); assert.equal(calls.length, 1); assert.equal(calls[0].traceparent, traceparent); });