Ctrl K
ComunidadGuías…

test/dashboard-api.test.js

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

Archivo original ↗Preguntar a KiBot
import { afterEach, describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { config } from '../src/config.js';
import { addAccountByKey, configureBindHost, getAccountInternal, removeAccount, _resetLockoutForTests } from '../src/auth.js';
import { buildBatchProxyBinding, handleDashboardApi } from '../src/dashboard/api.js';
import {
  recordNativeBridgeDecision,
  resetNativeBridgeStats,
} from '../src/native-bridge-stats.js';
import { _resetRuntimeConfigForTests } from '../src/runtime-config.js';
import { detachedRegistry } from '../src/detached-registry.js';
import { __resetReadCache, __setFetchImplForTest, __setNowForTest } from '../src/dashboard/devin-read.js';

const originalDashboardPassword = config.dashboardPassword;
const originalApiKey = config.apiKey;
const originalNativeBridgeApiKeys = process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_API_KEYS;
const originalNativeBridgeAccounts = process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_ACCOUNTS;
const originalAllowNoAuth = process.env.DASHBOARD_ALLOW_NO_AUTH;
const createdAccounts = new Set();

afterEach(() => {
  __setFetchImplForTest(null);
  __setNowForTest(null);
  __resetReadCache();
  for (const id of createdAccounts) removeAccount(id);
  createdAccounts.clear();
  _resetRuntimeConfigForTests();
  _resetLockoutForTests();
  config.dashboardPassword = originalDashboardPassword;
  config.apiKey = originalApiKey;
  if (originalNativeBridgeApiKeys === undefined) delete process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_API_KEYS;
  else process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_API_KEYS = originalNativeBridgeApiKeys;
  if (originalNativeBridgeAccounts === undefined) delete process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_ACCOUNTS;
  else process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_ACCOUNTS = originalNativeBridgeAccounts;
  if (originalAllowNoAuth === undefined) delete process.env.DASHBOARD_ALLOW_NO_AUTH;
  else process.env.DASHBOARD_ALLOW_NO_AUTH = originalAllowNoAuth;
  resetNativeBridgeStats();
  configureBindHost('0.0.0.0');
});

function fakeRes() {
  return {
    statusCode: 0,
    headers: {},
    body: '',
    writeHead(status, headers) { this.statusCode = status; this.headers = headers || {}; },
    end(chunk) { this.body += chunk ? String(chunk) : ''; },
    json() { return this.body ? JSON.parse(this.body) : null; },
  };
}

function localReq(path) {
  return { url: `/dashboard/api${path}`, headers: {}, socket: { remoteAddress: '127.0.0.1' } };
}

function addTestAccount(label) {
  const account = addAccountByKey(`test-key-${label}-${Date.now()}-${Math.random().toString(16).slice(2)}`, label);
  createdAccounts.add(account.id);
  return account;
}

describe('dashboard batch import proxy binding', () => {
  it('uses nested result.account.id from processWindsurfLogin output', () => {
    const binding = buildBatchProxyBinding(
      { success: true, account: { id: 'acct_123' } },
      'socks5://user:pass@proxy.example.com:1080'
    );
    assert.equal(binding.accountId, 'acct_123');
    assert.deepEqual(binding.proxy, {
      type: 'socks5',
      host: 'proxy.example.com',
      port: 1080,
      username: 'user',
      password: 'pass',
    });
  });

  it('fails closed for dashboard write APIs without auth on non-localhost binds', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = '';
    config.apiKey = '';
    configureBindHost('0.0.0.0');

    const res = fakeRes();
    await handleDashboardApi('DELETE', '/cache', {}, { headers: {} }, res);

    assert.equal(res.statusCode, 401);
    assert.match(res.json().error, /Unauthorized/);
  });

  it('fails closed on localhost binds with no secret by default; opens only with DASHBOARD_ALLOW_NO_AUTH=1', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = '';
    config.apiKey = '';
    configureBindHost('127.0.0.1');

    // AUTH-1: localhost + nothing configured is now fail-closed by default.
    delete process.env.DASHBOARD_ALLOW_NO_AUTH;
    const closed = fakeRes();
    await handleDashboardApi('GET', '/cache', {}, { headers: {}, socket: { remoteAddress: '127.0.0.1' } }, closed);
    assert.equal(closed.statusCode, 401);
    assert.match(closed.json().error, /Unauthorized/);

    // Operators who relied on the old open-local convenience must opt in.
    // audit #1: open-local requires a loopback PEER, not just a loopback bind.
    process.env.DASHBOARD_ALLOW_NO_AUTH = '1';
    const open = fakeRes();
    await handleDashboardApi('GET', '/cache', {}, { headers: {}, socket: { remoteAddress: '127.0.0.1' } }, open);
    assert.equal(open.statusCode, 200);
  });

  it('accepts dashboard auth headers with timing-safe configured secrets', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = 'dash-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');

    const res = fakeRes();
    await handleDashboardApi('GET', '/cache', {}, { headers: { 'x-dashboard-password': 'dash-secret' } }, res);

    assert.equal(res.statusCode, 200);
  });

  it('does NOT lock out on empty-password preloads (page-load 401s are not brute-force)', async () => {
    _resetRuntimeConfigForTests();
    _resetLockoutForTests();
    config.dashboardPassword = 'dash-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const ip = '203.0.113.7';
    const req = (hdrs) => ({ url: '/dashboard/api/overview', headers: hdrs, socket: { remoteAddress: ip } });

    // Simulate the dashboard firing many authed calls with NO password on load.
    for (let i = 0; i < 12; i++) {
      const r = fakeRes();
      await handleDashboardApi('GET', '/overview', {}, req({}), r);
      assert.equal(r.statusCode, 401, 'empty-password call should 401');
    }
    // The IP must NOT be banned — the correct password should still work.
    const ok = fakeRes();
    await handleDashboardApi('GET', '/overview', {}, req({ 'x-dashboard-password': 'dash-secret' }), ok);
    assert.equal(ok.statusCode, 200, 'correct password must still work after empty-password preloads');
  });

  it('DOES lock out after repeated WRONG-password guesses', async () => {
    _resetRuntimeConfigForTests();
    _resetLockoutForTests();
    config.dashboardPassword = 'dash-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const ip = '203.0.113.8';
    const req = () => ({ url: '/dashboard/api/overview', headers: { 'x-dashboard-password': 'wrong-guess' }, socket: { remoteAddress: ip } });

    let banned = false;
    for (let i = 0; i < 10; i++) {
      const r = fakeRes();
      await handleDashboardApi('GET', '/overview', {}, req(), r);
      if (r.statusCode === 429) { banned = true; break; }
    }
    assert.equal(banned, true, 'repeated wrong-password guesses must eventually ban the IP');
  });

  it('includes sanitized native bridge telemetry in authenticated overview', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = 'dash-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_API_KEYS = 'secret-api-key';
    process.env.WINDSURFAPI_NATIVE_TOOL_BRIDGE_ACCOUNTS = 'secret-account';
    recordNativeBridgeDecision({
      enabled: false,
      reason: 'native_bridge_model_not_allowed',
      mode: 'all_mapped',
      modelKey: 'gpt-5.5-medium',
      mappedTools: ['Read'],
      unmappedTools: ['update_plan'],
      callerKey: 'api:secret-caller',
    });

    const res = fakeRes();
    await handleDashboardApi('GET', '/overview', {}, { headers: { 'x-dashboard-password': 'dash-secret' } }, res);
    const body = res.json();
    const raw = JSON.stringify(body);

    assert.equal(res.statusCode, 200);
    assert.equal(body.nativeBridge.decisions, 1);
    assert.equal(body.nativeBridge.decisionReasons.native_bridge_model_not_allowed, 1);
    assert.equal(body.nativeBridgeConfig.hasApiKeyGate, true);
    assert.equal(body.nativeBridgeConfig.hasAccountGate, true);
    assert.equal(raw.includes('secret-api-key'), false);
    assert.equal(raw.includes('secret-account'), false);
    assert.equal(raw.includes('secret-caller'), false);
  });

  it('exposes detach admit/serve counters for the gate-1 measurement', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = 'dash-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const previousTurn = process.env.WINDSURFAPI_CASCADE_TURN;
    const previousDetach = process.env.WINDSURFAPI_CASCADE_DETACH;
    process.env.WINDSURFAPI_CASCADE_TURN = '1';
    process.env.WINDSURFAPI_CASCADE_DETACH = '1';
    detachedRegistry.reset();
    try {
      const admitted = detachedRegistry.admit({
        key: 'gate1-key',
        callerKey: 'session:gate1',
        snapshot: { version: 2, chunks: [{ text: 'gate1' }], consumedThrough: 0, stepOffset: 0 },
        pin: { deadline: Date.now() + 60_000 },
      });
      assert.ok(admitted.token, 'precondition: the registry admitted the sample entry');

      const first = fakeRes();
      await handleDashboardApi('GET', '/overview', {}, { headers: { 'x-dashboard-password': 'dash-secret' } }, first);
      const firstBody = first.json();
      assert.equal(first.statusCode, 200);
      assert.equal(firstBody.detach.enabled, true, 'gate 1 must be able to prove the switch is on');
      assert.equal(firstBody.detach.admit, 1);
      assert.equal(firstBody.detach.serve, 0);
      assert.equal(typeof firstBody.detach.refuse.no_scope, 'number', 'refusal reasons are part of the measurement surface');

      const claim = detachedRegistry.claim('gate1-key', 'session:gate1');
      assert.ok(claim.entry, 'precondition: the entry is claimable');
      detachedRegistry.release('gate1-key', claim.token, { state: 'served' });

      const second = fakeRes();
      await handleDashboardApi('GET', '/overview', {}, { headers: { 'x-dashboard-password': 'dash-secret' } }, second);
      const secondBody = second.json();
      assert.equal(secondBody.detach.admit, 1);
      assert.equal(secondBody.detach.serve, 1, 'serve/admit is the gate-1 ratio');
      assert.equal(secondBody.detach.entries, 0);
    } finally {
      detachedRegistry.reset();
      if (previousTurn === undefined) delete process.env.WINDSURFAPI_CASCADE_TURN;
      else process.env.WINDSURFAPI_CASCADE_TURN = previousTurn;
      if (previousDetach === undefined) delete process.env.WINDSURFAPI_CASCADE_DETACH;
      else process.env.WINDSURFAPI_CASCADE_DETACH = previousDetach;
    }
  });

  it('exposes DEVIN_CONNECT recovery counters at /connect-metrics and resets on DELETE', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = '';
    config.apiKey = '';
    configureBindHost('127.0.0.1');
    process.env.DASHBOARD_ALLOW_NO_AUTH = '1'; // convenience: exercise metrics, not auth

    const { bumpConnect, resetConnectMetrics } = await import('../src/devin-connect-metrics.js');
    resetConnectMetrics();
    bumpConnect('failover_hops', 2);
    bumpConnect('dead_tokens');

    const res = fakeRes();
    await handleDashboardApi('GET', '/connect-metrics', {}, localReq('/connect-metrics'), res);
    assert.equal(res.statusCode, 200);
    const body = res.json();
    assert.equal(body.failover_hops, 2);
    assert.equal(body.dead_tokens, 1);
    assert.equal(typeof body.credDecryptFailures, 'number');
    assert.ok(body.uptimeMs >= 0);
    // Sticky affinity counters ride the same endpoint so an operator can see
    // whether STICKY_SESSION_ENABLED is actually binding.
    assert.equal(typeof body.sticky, 'object');
    assert.equal(typeof body.sticky.enabled, 'boolean');
    for (const k of ['hits', 'misses', 'creates', 'fallbacks', 'size']) {
      assert.equal(typeof body.sticky[k], 'number', `sticky.${k} must be a number`);
    }

    const del = fakeRes();
    await handleDashboardApi('DELETE', '/connect-metrics', {}, localReq('/connect-metrics'), del);
    assert.equal(del.statusCode, 200);
    const after = fakeRes();
    await handleDashboardApi('GET', '/connect-metrics', {}, localReq('/connect-metrics'), after);
    assert.equal(after.json().failover_hops, 0);
  });

  it('supports paged lightweight account summaries without breaking the legacy full list', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = '';
    config.apiKey = '';
    configureBindHost('127.0.0.1');
    process.env.DASHBOARD_ALLOW_NO_AUTH = '1'; // convenience: exercise paging, not auth
    const a1 = addTestAccount('dashboard-summary-a');
    const a2 = addTestAccount('dashboard-summary-b');

    const summaryRes = fakeRes();
    await handleDashboardApi('GET', '/accounts', {}, localReq('/accounts?view=summary&page=1&pageSize=1'), summaryRes);
    const summary = summaryRes.json();
    assert.equal(summaryRes.statusCode, 200);
    assert.equal(summary.page, 1);
    assert.equal(summary.pageSize, 1);
    assert.ok(summary.total >= 2);
    assert.equal(summary.accounts.length, 1);
    assert.ok('tierModelCount' in summary.accounts[0]);
    assert.equal('tierModels' in summary.accounts[0], false);
    assert.equal('availableModels' in summary.accounts[0], false);
    assert.equal('capabilities' in summary.accounts[0], false);
    assert.equal('lsAdmission' in summary.accounts[0], false);

    const detailRes = fakeRes();
    await handleDashboardApi('GET', `/accounts/${a2.id}`, {}, localReq(`/accounts/${a2.id}`), detailRes);
    const detail = detailRes.json();
    assert.equal(detailRes.statusCode, 200);
    assert.equal(detail.account.id, a2.id);
    assert.ok(Array.isArray(detail.account.tierModels));
    assert.ok(Array.isArray(detail.account.availableModels));
    assert.ok('capabilities' in detail.account);

    const legacyRes = fakeRes();
    await handleDashboardApi('GET', '/accounts', {}, localReq('/accounts'), legacyRes);
    const legacy = legacyRes.json();
    const legacyA1 = legacy.accounts.find(a => a.id === a1.id);
    assert.equal(legacyRes.statusCode, 200);
    assert.ok(legacyA1);
    assert.ok(Array.isArray(legacyA1.tierModels));
    assert.ok(Array.isArray(legacyA1.availableModels));
  });
});

// B2: /pool-events exposes the cooldown projection the dashboard's transition
// notifier diffs. cooldownReason is a precedence chain (quota > rate_limit >
// capacity > null) and cooldownUntil is max(rateLimitedUntil, quotaResetAt),
// normalized to null (not 0) when neither deadline is set. This route had zero
// test references before this block.
describe('GET /pool-events cooldown projection', () => {
  it('reports the precedence chain and the max deadline per account state', async () => {
    _resetRuntimeConfigForTests();
    config.dashboardPassword = '';
    config.apiKey = '';
    configureBindHost('127.0.0.1');
    process.env.DASHBOARD_ALLOW_NO_AUTH = '1'; // convenience: exercise projection, not auth

    const now = Date.now();
    const healthy = addTestAccount('pool-events-healthy');
    const quota = addTestAccount('pool-events-quota');
    const rate = addTestAccount('pool-events-rate');
    const capacity = addTestAccount('pool-events-capacity');
    const disabled = addTestAccount('pool-events-disabled');

    const h = getAccountInternal(healthy.id);
    h.tier = 'pro';
    h.credits = { balance: 12.5 };
    h.errorCount = 3;

    getAccountInternal(disabled.id).status = 'disabled';

    // quota outranks the transient and capacity dimensions; the deadline is the
    // LATER of the two real deadlines (max, not the reason's own deadline).
    const q = getAccountInternal(quota.id);
    q.rateLimitedUntil = now + 60_000;
    q.quotaResetAt = now + 120_000;
    q._modelRateLimits = { 'claude-sonnet-4.6': now + 30_000 };

    // rate_limit outranks capacity.
    const r = getAccountInternal(rate.id);
    r.rateLimitedUntil = now + 90_000;
    r.quotaResetAt = 0;
    r._modelRateLimits = { 'claude-sonnet-4.6': now + 30_000 };

    // capacity alone has no account-wide deadline: cooldownUntil must stay null.
    const c = getAccountInternal(capacity.id);
    c.rateLimitedUntil = 0;
    c.quotaResetAt = 0;
    c._modelRateLimits = { 'claude-sonnet-4.6': now + 30_000 };

    const res = fakeRes();
    await handleDashboardApi('GET', '/pool-events', {}, localReq('/pool-events'), res);

    assert.equal(res.statusCode, 200);
    const body = res.json();
    assert.equal(typeof body.ts, 'number', 'the payload must carry a snapshot timestamp');
    const byId = new Map(body.accounts.map(a => [a.id, a]));
    assert.match(byId.get(healthy.id).ref, /^acct-[0-9a-f]{8}$/);
    assert.equal('keyPrefix' in byId.get(healthy.id), false);

    assert.deepEqual(
      {
        status: byId.get(healthy.id).status,
        tier: byId.get(healthy.id).tier,
        balance: byId.get(healthy.id).balance,
        errorCount: byId.get(healthy.id).errorCount,
        cooldownReason: byId.get(healthy.id).cooldownReason,
        cooldownUntil: byId.get(healthy.id).cooldownUntil,
      },
      { status: 'active', tier: 'pro', balance: 12.5, errorCount: 3, cooldownReason: null, cooldownUntil: null },
      'a healthy account must project null (not 0) cooldown fields',
    );

    assert.equal(byId.get(quota.id).cooldownReason, 'quota');
    assert.equal(byId.get(quota.id).cooldownUntil, now + 120_000,
      'cooldownUntil must be max(rateLimitedUntil, quotaResetAt)');

    assert.equal(byId.get(rate.id).cooldownReason, 'rate_limit');
    assert.equal(byId.get(rate.id).cooldownUntil, now + 90_000);

    assert.equal(byId.get(capacity.id).cooldownReason, 'capacity');
    assert.equal(byId.get(capacity.id).cooldownUntil, null,
      'a capacity-only account has no account-wide deadline');

    assert.equal(byId.get(healthy.id).state, 'active');
    assert.equal(byId.get(healthy.id).cooldownRemainingMs, 0);
    assert.equal(byId.get(healthy.id).upstream, null, 'no cache primed: the overlay must be null, not an error');

    assert.equal(byId.get(quota.id).state, 'quota');
    assert.ok(byId.get(quota.id).cooldownRemainingMs > 0);
    assert.ok(byId.get(quota.id).cooldownRemainingMs <= 120_000);

    assert.equal(byId.get(rate.id).state, 'rate_limited');
    assert.ok(byId.get(rate.id).cooldownRemainingMs > 0);

    assert.equal(byId.get(capacity.id).state, 'capacity');
    assert.equal(byId.get(capacity.id).cooldownRemainingMs, 0);

    assert.equal(byId.get(disabled.id).state, 'disabled');

    const serialized = res.body;
    for (const secret of ['keyPrefix', 'apiKey', 'refreshToken', 'totalBalance', '@']) {
      assert.equal(serialized.includes(secret), false, `pool payload must not contain ${secret}`);
    }
    assert.equal(res.headers['Cache-Control'], 'no-store',
      'authed pool snapshots must not be browser-cached');
  });
});

// ─── P0 read cards ──────────────────────────────────────────────────────────
// /usage, /billing/health and /models/reconcile are GET-only projections of
// app.devin.ai billing/model reads. The fake fetch below is the only transport:
// these tests assert the exact paths, the shared cache, the redaction allowlist
// and Cache-Control: no-store.

const CARD_TOGGLEABLE = [
  'devin-gpt-6-1-sol',
  'devin-gpt-6-sol',
  'devin-gpt-6-astra',
  'devin-fable-5-1',
  'devin-opus-5-5',
  'devin-swe-2-high',
  'devin-swe-2-max',
  'devin-swe-2-lightning-high',
  'devin-swe-2-lightning-max',
  'devin-2-5',
  'devin-auto',
  'devin-fast-opus',
  'devin_lite',
  'devin-ultra',
  'devin-swe-2-low',
  'devin-swe-2-priority-low',
  'devin-swe-2-priority-high',
  'devin-swe-2-priority-max',
  'devin-swe-2-lightning-low',
];

function cardJson(value, status = 200) {
  return {
    ok: status >= 200 && status < 300,
    status,
    headers: { get: () => null },
    text: async () => JSON.stringify(value),
  };
}

function cardReq(path) {
  return {
    url: `/dashboard/api${path}`,
    headers: { 'x-dashboard-password': 'card-secret' },
    socket: { remoteAddress: '127.0.0.1' },
  };
}

function installCardFetch({ status = 200, quotaStatus = 200 } = {}) {
  const calls = [];
  __setFetchImplForTest(async (url, init) => {
    calls.push({ url, method: init.method, headers: init.headers });
    const path = url.replace('https://app.devin.ai/api', '');
    if (path === '/users/current-membership') {
      return cardJson({ org: { org_id: 'org-test123' }, user: { email: 'operator@example.test' } });
    }
    if (path === '/org-test123/billing/quota/usage') {
      return quotaStatus === 200
        ? cardJson({
          is_quota_plan: true,
          has_quota_allocation: true,
          daily_percentage: 3,
          weekly_percentage: 1,
          daily_reset_at: '2026-10-18T00:00:00-08:00',
          weekly_reset_at: '2026-10-18T00:00:00-08:00',
          overage_balance: 0,
          hide_daily_quota: false,
        })
        : cardJson({ detail: 'Forbidden' }, quotaStatus);
    }
    if (path === '/org-test123/billing/status') {
      return status === 200
        ? cardJson({
          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',
          available_credits: 0,
          overage_credits: 0,
          billing_waived_agent_versions: [],
        })
        : cardJson({ detail: 'Forbidden' }, status);
    }
    if (path === '/org-test123/billing/usage/limits') {
      return status === 200
        ? cardJson({ max_acu_limit: 20, max_total_session_acu_limit: null })
        : cardJson({ detail: 'Forbidden' }, 403);
    }
    if (path === '/org-test123/billing/usage/daily-usage?cycle=current&view=all') {
      return status === 200 ? cardJson({
        cycle_start: '2026-10-16T20:11:50+00:00',
        cycle_end: '2026-11-16T20:11:50+00:00',
        previous_cycle_available: false,
        total: 0,
        days: [{ date: '2026-10-16', amount: 0, cumulative: 0 }],
        products: [{ view: 'sessions', total: 0, days: [] }],
      }) : cardJson({ detail: 'Forbidden' }, 403);
    }
    if (path === '/users/spending-state') return cardJson({ state: 'active' });
    if (path === '/org-test123/limit-suspended-sessions') return cardJson({ sessions: [], can_restart_now: false });
    if (path === '/billing/subscription/unpaid-invoices') return cardJson({ has_unpaid_invoices: false });
    if (path === '/org-test123/billing/auto-recharge/params') {
      return cardJson({
        account_migrated_to_auto_recharge: true,
        auto_recharge_enabled: false,
        threshold: null,
        amount: null,
        max_monthly_total_spend: null,
      });
    }
    if (path === '/internal-model-catalog') return cardJson({ groups: [], sections: [] });
    if (path === '/org-test123/fed-models') {
      return cardJson({ tiers: {}, helpers: [], models: {}, allowlist: null });
    }
    if (path === '/toggleable-agent-versions') {
      return cardJson({ toggleable_versions: CARD_TOGGLEABLE, swe2_promo_eligible: false, swe2_priority_eligible: false });
    }
    if (path === '/windsurf/org-configs') {
      return cardJson({
        enterpriseTeamConfig: { teamId: 'team-secret-value', allowMcpServers: true },
        enterpriseControlConfig: { extensionModelLabels: ['Base Model'] },
      });
    }
    throw new Error(`unexpected ${path}`);
  });
  return calls;
}

function countPath(calls, suffix) {
  return calls.filter((c) => c.url.endsWith(suffix)).length;
}

describe('dashboard P0 read cards', () => {
  it('serves quota burn-down without orgId/keyPrefix and with a no-store header', async () => {
    config.dashboardPassword = 'card-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const account = addTestAccount('card-usage');
    const calls = installCardFetch();

    const res = fakeRes();
    await handleDashboardApi('GET', '/usage', {}, cardReq(`/usage?account=${account.id}`), res);
    assert.equal(res.statusCode, 200);
    const body = res.json();
    assert.equal(body.ok, true);
    assert.equal(body.accountId, account.id);
    assert.match(body.accountRef, /^acct-[0-9a-f]{8}$/);
    assert.equal(body.plan, 'pro');
    assert.equal(body.quota.dailyPercentage, 3);
    assert.equal(body.limits.maxAcuLimit, 20);
    assert.equal(body.limits.maxTotalSessionAcuLimit, null);
    assert.equal(body.products.length, 1);
    assert.equal(body.serverNow > 0, true);
    assert.equal(body.cached, false);
    assert.equal(res.headers['Cache-Control'], 'no-store');

    assert.ok(countPath(calls, '/billing/usage/daily-usage?cycle=current&view=all') === 1);
    assert.equal(countPath(calls, '/users/post-auth'), 0, 'the dashboard read path must never post-auth');
    assert.ok(calls.every((c) => c.method === 'GET'));
    assert.ok(calls.every((c) => c.headers.Authorization === `Bearer ${account.apiKey}`));

    const serialized = res.body;
    assert.equal(serialized.includes('orgId'), false);
    assert.equal(serialized.includes('org_id'), false);
    assert.equal(serialized.includes('account_id'), false);
    assert.equal(serialized.includes('org-test123'), false);
    assert.equal(serialized.includes('keyPrefix'), false);
    assert.equal(serialized.includes('operator@example.test'), false);

    // Second call within the 30 s TTL: cached and zero new source fetches.
    const before = calls.length;
    const second = fakeRes();
    await handleDashboardApi('GET', '/usage', {}, cardReq(`/usage?account=${account.id}`), second);
    assert.equal(second.statusCode, 200);
    assert.equal(second.json().cached, true);
    assert.equal(calls.length, before, 'a cache hit must not refetch');

    // The pool card's upstream overlay is cache-only: after /usage primed
    // `status`, it carries the allowlist keys and triggers no new fetch.
    const pool = fakeRes();
    await handleDashboardApi('GET', '/pool-events', {}, cardReq('/pool-events'), pool);
    const row = pool.json().accounts.find((a) => a.id === account.id);
    assert.deepEqual(
      Object.keys(row.upstream).sort(),
      ['billingValid', 'fetchedAt', 'plan', 'spendingState', 'stale'],
    );
    assert.equal(row.upstream.plan, 'pro');
    assert.equal(calls.length, before, 'the pool overlay must never fetch upstream');
  });

  it('shares the quota/status cache with billing health and serves the ok banner', async () => {
    config.dashboardPassword = 'card-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const account = addTestAccount('card-health');
    const calls = installCardFetch();

    const usage = fakeRes();
    await handleDashboardApi('GET', '/usage', {}, cardReq(`/usage?account=${account.id}`), usage);
    assert.equal(usage.statusCode, 200);

    const res = fakeRes();
    await handleDashboardApi('GET', '/billing/health', {}, cardReq(`/billing/health?account=${account.id}`), res);
    assert.equal(res.statusCode, 200);
    const body = res.json();
    assert.equal(body.ok, true);
    assert.equal(body.state, 'ok');
    assert.equal(body.severity, 'ok');
    assert.equal(body.bannerKey, 'billing.banner.ok');
    assert.equal(body.details.plan, 'pro');
    assert.equal(body.details.spendingState, 'active');
    assert.equal(body.details.suspendedSessionCount, 0);
    assert.equal(res.headers['Cache-Control'], 'no-store');

    assert.equal(countPath(calls, '/billing/status'), 1, 'status is shared with the usage card');
    assert.equal(countPath(calls, '/billing/quota/usage'), 1, 'quota is shared with the usage card');
    assert.equal(countPath(calls, '/users/spending-state'), 1);
    assert.equal(countPath(calls, '/users/post-auth'), 0);
    assert.equal(res.body.includes('org-test123'), false);
    assert.equal(res.body.includes('keyPrefix'), false);
  });

  it('serves model reconciliation with the 233-row snapshot and no teamId', async () => {
    config.dashboardPassword = 'card-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const account = addTestAccount('card-models');
    const calls = installCardFetch();

    const res = fakeRes();
    await handleDashboardApi('GET', '/models/reconcile', {}, cardReq(`/models/reconcile?account=${account.id}`), res);
    assert.equal(res.statusCode, 200);
    const body = res.json();
    assert.equal(body.ok, true);
    assert.equal(body.snapshotCount, 233);
    assert.equal(body.synced, false);
    assert.deepEqual(body.added, []);
    assert.deepEqual(body.missing, []);
    assert.equal(body.toggleable.total, 19);
    assert.equal(body.toggleable.mappedCount, 9);
    assert.equal(body.upstreamCatalog.empty, true);
    assert.equal(body.orgConfig.teamIdPresent, true);
    assert.equal(body.localCount > 0, true);
    assert.equal(res.headers['Cache-Control'], 'no-store');

    assert.ok(countPath(calls, '/internal-model-catalog') === 1);
    assert.ok(countPath(calls, '/org-test123/fed-models') === 1);
    assert.ok(countPath(calls, '/toggleable-agent-versions') === 1);
    assert.ok(countPath(calls, '/windsurf/org-configs') === 1);
    assert.equal(countPath(calls, '/users/post-auth'), 0);
    assert.equal(res.body.includes('team-secret-value'), false);
    assert.equal(res.body.includes('org-test123'), false);
    assert.equal(res.body.includes('keyPrefix'), false);
  });

  it('returns 403 (not zeros) when the billing sources forbid access', async () => {
    config.dashboardPassword = 'card-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const account = addTestAccount('card-forbidden');
    installCardFetch({ status: 403, quotaStatus: 403 });

    const res = fakeRes();
    await handleDashboardApi('GET', '/usage', {}, cardReq(`/usage?account=${account.id}`), res);
    assert.equal(res.statusCode, 403);
    const body = res.json();
    assert.equal(body.ok, false);
    assert.equal(body.error, 'forbidden');
    assert.equal('quota' in body, false, 'a forbidden read must not render zeros');
    assert.equal(res.headers['Cache-Control'], 'no-store');
  });

  it('serves the last good snapshot as stale when the upstream times out', async () => {
    config.dashboardPassword = 'card-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    const account = addTestAccount('card-stale');
    installCardFetch();

    const first = fakeRes();
    await handleDashboardApi('GET', '/usage', {}, cardReq(`/usage?account=${account.id}`), first);
    assert.equal(first.statusCode, 200);
    assert.equal(first.json().stale, false);

    // Age the cache past the 30 s TTL, then make every upstream read time out.
    const realNow = Date.now();
    __setNowForTest(() => realNow + 31_000);
    __setFetchImplForTest(async () => {
      throw Object.assign(new Error('timed out'), { name: 'TimeoutError' });
    });

    const stale = fakeRes();
    await handleDashboardApi('GET', '/usage', {}, cardReq(`/usage?account=${account.id}`), stale);
    assert.equal(stale.statusCode, 200);
    const body = stale.json();
    assert.equal(body.ok, true);
    assert.equal(body.stale, true);
    assert.equal(body.quota.dailyPercentage, 3, 'the last good value is preserved');
    assert.equal(stale.headers['Cache-Control'], 'no-store');
  });

  it('returns 404 for an unknown account id', async () => {
    config.dashboardPassword = 'card-secret';
    config.apiKey = '';
    configureBindHost('0.0.0.0');
    installCardFetch();

    const res = fakeRes();
    await handleDashboardApi('GET', '/usage', {}, cardReq('/usage?account=does-not-exist'), res);
    assert.equal(res.statusCode, 404);
    assert.equal(res.json().error, 'account_not_found');
  });
});