#!/usr/bin/env node 'use strict'; const assert = require('assert/strict'); const fs = require('fs'); const os = require('os'); const path = require('path'); function envValue(filePath, key) { const content = fs.readFileSync(filePath, 'utf8'); const match = content.match(new RegExp(`^${key}=(.*)$`, 'm')); return match ? match[1].trim() : undefined; } function json(data) { return new Response(JSON.stringify({ code: 200, data }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); } async function main() { const packageRoot = path.resolve(__dirname, '..'); const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'qiwei-token-switch-')); const previousCwd = process.cwd(); const previousEnv = { ...process.env }; const originalFetch = global.fetch; let closeAgentWorkbenches = () => {}; let stopMonitor = () => {}; const requests = []; try { process.env.HOME = fixtureRoot; process.env.USERPROFILE = fixtureRoot; process.env.QIWEI_PACKAGE_ROOT = fixtureRoot; process.env.QIWEI_WORKSPACE_ROOT = fixtureRoot; process.env.QIWEI_OUTPUTS_DIR = path.join(fixtureRoot, 'outputs'); process.env.QIWEI_AUTH_TOKEN = 'sk-old-account'; process.env.QIWEI_UID = 'uid-old-account'; process.env.QIWEI_GUID = 'guid-old-account'; process.env.QIWEI_API_BASE = 'https://fixture.example/api/qiwei'; process.chdir(fixtureRoot); fs.writeFileSync(path.join(fixtureRoot, '.env.local'), [ 'QIWEI_AUTH_TOKEN=sk-old-account', 'QIWEI_UID=uid-old-account', 'QIWEI_GUID=guid-old-account', 'QIWEI_API_BASE=https://fixture.example/api/qiwei', '', ].join('\n'), 'utf8'); global.fetch = async (rawUrl, options = {}) => { const url = new URL(String(rawUrl)); const authorization = String(options.headers?.Authorization || options.headers?.authorization || ''); requests.push({ path: url.pathname, authorization }); if (url.pathname.endsWith('/trial/status')) { return json({ active: true, state: 'active', seats: 1, credentialReady: true, expireAt: '2099-01-01T00:00:00.000Z' }); } if (url.pathname.endsWith('/subscribe/status')) { return json({ subscribed: false, seats: null, usedSeats: 0 }); } if (url.pathname.endsWith('/login/status')) { const sameAccount = authorization.includes('sk-old-account') || authorization.includes('r:same-account'); return json({ configured: sameAccount, online: sameAccount, statusCode: sameAccount ? 2 : null, detail: sameAccount ? { userId: 'user-old', nickname: 'Old Account' } : {}, }); } throw new Error(`Unexpected fixture request: ${url.pathname}`); }; const dashboardServer = require(path.join(packageRoot, 'mcp', 'src', 'dashboard', 'server')); const agentService = require(path.join(packageRoot, 'mcp', 'src', 'dashboard', 'agent-service')); const credentials = require(path.join(packageRoot, 'mcp', 'src', 'core', 'credentials')); closeAgentWorkbenches = agentService.closeAgentWorkbenches; stopMonitor = () => dashboardServer.__testing.accountConnectionMonitor.stop(); const sameAccount = await dashboardServer.__testing.saveAuthToken('r:same-account'); assert.equal(sameAccount.status, 'ok'); assert.equal(sameAccount.summary.accountReset, false); assert.equal(envValue(path.join(fixtureRoot, '.env.local'), 'QIWEI_UID'), 'uid-old-account'); assert.equal(credentials.readQiweiUid(), 'uid-old-account'); const differentAccount = await dashboardServer.__testing.saveAuthToken('r:different-account'); assert.equal(differentAccount.status, 'ok'); assert.equal(differentAccount.summary.accountReset, true); assert.equal(differentAccount.summary.trialActive, true); assert.equal(envValue(path.join(fixtureRoot, '.env.local'), 'QIWEI_AUTH_TOKEN'), 'r:different-account'); assert.equal(envValue(path.join(fixtureRoot, '.env.local'), 'QIWEI_UID'), ''); assert.equal(envValue(path.join(fixtureRoot, '.env.local'), 'QIWEI_GUID'), ''); assert.equal(credentials.readQiweiUid(), ''); assert.equal(credentials.readQiweiGuid(), ''); assert.equal(agentService.__testing.activeAccountMetadata().uid, ''); assert.equal(agentService.__testing.activeAccountMetadata().guid, ''); assert.equal(dashboardServer.__testing.accountConnectionMonitor.state.lastOutput, null); assert.equal(requests.some(item => item.path.endsWith('/login/start')), false); process.stdout.write(`${JSON.stringify({ status: 'ok', checks: 16, coverage: [ 'same_account_session_refresh_keeps_device_binding', 'different_account_token_clears_uid_and_guid', 'different_account_switch_resets_workbench_context', 'credential_switch_does_not_start_login', ], }, null, 2)}\n`); } finally { stopMonitor(); closeAgentWorkbenches(); global.fetch = originalFetch; process.chdir(previousCwd); for (const key of Object.keys(process.env)) { if (!(key in previousEnv)) delete process.env[key]; } for (const [key, value] of Object.entries(previousEnv)) process.env[key] = value; fs.rmSync(fixtureRoot, { recursive: true, force: true }); } } main().catch(error => { process.stderr.write(`${error.stack || error.message}\n`); process.exitCode = 1; });