test/dashboard-billing-health.test.js
Rama master · réplica de lectura del repositorio original.
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { buildBillingHealth, deriveBillingState } from '../src/dashboard/billing-health.js';
const OK_SOURCES = {
status: { ok: true, stale: false, fetchedAt: 1 },
quota: { ok: true, stale: false, fetchedAt: 1 },
suspended: { ok: true, stale: false, fetchedAt: 1 },
unpaid: { ok: true, stale: false, fetchedAt: 1 },
autorecharge: { ok: true, stale: false, fetchedAt: 1 },
spending: { ok: true, stale: false, fetchedAt: 1 },
};
function base(over = {}) {
return {
status: {
plan_slug: 'pro',
is_subscription_valid: true,
uses_quota: true,
has_subscription_or_credits: true,
has_failed_auto_recharge: false,
billing_error: null,
billing_method: 'stripe',
is_enterprise: false,
plan_uses_credits: true,
show_consumption_dashboard: false,
billing_waived_agent_versions: [],
},
quota: {
is_quota_plan: true,
has_quota_allocation: true,
daily_percentage: 3,
weekly_percentage: 1,
},
suspended: { sessions: [], can_restart_now: false },
unpaid: { has_unpaid_invoices: false },
autorecharge: { account_migrated_to_auto_recharge: true, auto_recharge_enabled: false },
spending: { state: 'active' },
sources: OK_SOURCES,
...over,
};
}
describe('deriveBillingState', () => {
it('maps each state exactly', () => {
const cases = [
['ok', base()],
['quota_exhausted', base({ quota: { is_quota_plan: true, has_quota_allocation: true, daily_percentage: 100, weekly_percentage: 0 } })],
['paused', base({ suspended: { sessions: [{ id: 's1' }], can_restart_now: false } })],
['unpaid', base({ unpaid: { has_unpaid_invoices: true } })],
['recharge_failed', base({ status: { ...base().status, has_failed_auto_recharge: true } })],
['no_subscription', base({ status: { ...base().status, has_subscription_or_credits: false } })],
];
for (const [expected, input] of cases) {
assert.equal(deriveBillingState(input), expected, `state ${expected}`);
}
});
it('applies the documented precedence', () => {
const all = base({
suspended: { sessions: [{ id: 's1' }], can_restart_now: false },
unpaid: { has_unpaid_invoices: true },
status: { ...base().status, has_failed_auto_recharge: true },
quota: { is_quota_plan: true, has_quota_allocation: true, daily_percentage: 100, weekly_percentage: 100 },
});
assert.equal(deriveBillingState(all), 'paused');
const unpaidPlusRecharge = base({
unpaid: { has_unpaid_invoices: true },
status: { ...base().status, has_failed_auto_recharge: true },
});
assert.equal(deriveBillingState(unpaidPlusRecharge), 'unpaid');
const rechargePlusQuota = base({
status: { ...base().status, has_failed_auto_recharge: true },
quota: { is_quota_plan: true, has_quota_allocation: true, daily_percentage: 100, weekly_percentage: 0 },
});
assert.equal(deriveBillingState(rechargePlusQuota), 'recharge_failed');
const quotaPlusNoSub = base({
quota: { is_quota_plan: true, has_quota_allocation: true, daily_percentage: 100, weekly_percentage: 0 },
status: { ...base().status, has_subscription_or_credits: false },
});
assert.equal(deriveBillingState(quotaPlusNoSub), 'quota_exhausted');
});
it('never reports quota_exhausted for a non-quota plan', () => {
const creditsPlan = base({
quota: { is_quota_plan: false, has_quota_allocation: true, daily_percentage: 100, weekly_percentage: 100 },
});
assert.equal(deriveBillingState(creditsPlan), 'ok');
});
it('reports unknown when a blocking source is unavailable and nothing blocks', () => {
assert.equal(deriveBillingState(base({ sources: { ...OK_SOURCES, unpaid: { ok: false, error: 'forbidden' } } })), 'unknown');
assert.equal(deriveBillingState(base({ sources: { ...OK_SOURCES, status: { ok: false, error: 'timeout' } } })), 'unknown');
});
it('does not require the quota source for a credits-only plan', () => {
const creditsOnly = base({
status: { ...base().status, uses_quota: false },
sources: { ...OK_SOURCES, quota: { ok: false, error: 'forbidden' } },
});
assert.equal(deriveBillingState(creditsOnly), 'ok');
});
});
describe('buildBillingHealth', () => {
it('returns the ok banner with details and an informational auto-recharge warning', () => {
const out = buildBillingHealth({ ...base(), accountId: 'acct-test', accountRef: 'acct-1a2b3c4d', now: 42 });
assert.equal(out.ok, true);
assert.equal(out.state, 'ok');
assert.equal(out.severity, 'ok');
assert.equal(out.bannerKey, 'billing.banner.ok');
assert.deepEqual(out.warnings, ['auto_recharge_disabled']);
assert.equal(out.details.plan, 'pro');
assert.equal(out.details.availableCredits, undefined, 'credits are not part of the health card');
assert.equal(out.details.suspendedSessionCount, 0);
assert.equal(out.details.spendingState, 'active');
assert.deepEqual(out.details.autoRecharge, {
migrated: true, enabled: false, threshold: null, amount: null, maxMonthlyTotalSpend: null,
});
assert.equal(out.details.waivedAgentVersionsCount, 0);
assert.equal(out.fetchedAt, 42);
});
it('maps each state to its severity and banner key', () => {
const expected = {
ok: ['ok', 'billing.banner.ok'],
quota_exhausted: ['warn', 'billing.banner.quotaExhausted'],
paused: ['error', 'billing.banner.paused'],
unpaid: ['error', 'billing.banner.unpaid'],
recharge_failed: ['error', 'billing.banner.rechargeFailed'],
no_subscription: ['muted', 'billing.banner.noSubscription'],
unknown: ['muted', 'billing.banner.unknown'],
};
const inputs = {
ok: base(),
quota_exhausted: base({ quota: { is_quota_plan: true, has_quota_allocation: true, daily_percentage: 100, weekly_percentage: 0 } }),
paused: base({ suspended: { sessions: [{ id: 's1' }], can_restart_now: false } }),
unpaid: base({ unpaid: { has_unpaid_invoices: true } }),
recharge_failed: base({ status: { ...base().status, has_failed_auto_recharge: true } }),
no_subscription: base({ status: { ...base().status, has_subscription_or_credits: false } }),
unknown: base({ sources: { ...OK_SOURCES, unpaid: { ok: false, error: 'forbidden' } } }),
};
for (const [state, input] of Object.entries(inputs)) {
const out = buildBillingHealth(input);
assert.equal(out.state, state);
assert.equal(out.severity, expected[state][0], `severity ${state}`);
assert.equal(out.bannerKey, expected[state][1], `banner ${state}`);
}
});
it('keeps billing_error out of the state and redacts its text', () => {
const out = buildBillingHealth(base({
status: {
...base().status,
billing_error: 'contact org-test123 / user-test456 / user@example.test auth1_abcdefgh',
},
}));
assert.equal(out.state, 'ok');
assert.ok(out.warnings.includes('billing_error'));
const text = out.details.billingError;
for (const secret of ['org-test123', 'user-test456', 'user@example.test', 'auth1_abcdefgh']) {
assert.equal(text.includes(secret), false, `must redact ${secret}`);
}
assert.ok(text.length <= 200);
});
it('marks restartable suspended sessions as a warning, not a pause', () => {
const out = buildBillingHealth(base({ suspended: { sessions: [{ id: 's1' }, { id: 's2' }], can_restart_now: true } }));
assert.equal(out.state, 'ok');
assert.ok(out.warnings.includes('sessions_restartable'));
});
it('never serializes session ids or titles', () => {
const out = buildBillingHealth(base({
suspended: { sessions: [{ id: 'session-secret-id', title: 'private title' }], can_restart_now: false },
}));
const serialized = JSON.stringify(out);
assert.equal(serialized.includes('session-secret-id'), false);
assert.equal(serialized.includes('private title'), false);
assert.equal(out.details.suspendedSessionCount, 1);
});
it('reports partial and stale overlays without inventing a blocking state', () => {
const out = buildBillingHealth(base({
sources: {
...OK_SOURCES,
status: { ok: true, stale: true, fetchedAt: 1 },
unpaid: { ok: false, error: 'timeout' },
},
}));
assert.equal(out.partial, true);
assert.equal(out.stale, true);
assert.equal(out.state, 'unknown');
});
});