/** * token-monitor test suite * Run: node test.js * Red first, then implement until green. */ import { readFileSync, existsSync } from 'fs'; import { homedir } from 'os'; import { join } from 'path'; import { execSync } from 'child_process'; import { parseGeminiBody } from './providers/gemini.js'; import { parseXaiHeaders } from './providers/xai.js'; let passed = 0; let failed = 0; const failures = []; function assert(label, condition, detail = '') { if (condition) { console.log(` ✓ ${label}`); passed++; } else { console.log(` ✗ ${label}${detail ? ': ' + detail : ''}`); failed++; failures.push({ label, detail }); } } function run(cmd) { return execSync(cmd, { cwd: '/home/exedev/projects/token-monitor', encoding: 'utf-8' }); } function runSafe(cmd) { try { return { stdout: run(cmd), code: 0 }; } catch (e) { return { stdout: e.stdout || '', stderr: e.stderr || '', code: e.status }; } } // ── 1. Package structure ───────────────────────────────────────────────────── console.log('\n── 1. File structure ───────────────────────────────────────────'); const root = '/home/exedev/projects/token-monitor'; const files = [ 'package.json', 'monitor.js', 'logger.js', 'report.js', 'providers/index.js', 'providers/anthropic-teams.js', 'providers/anthropic-api.js', 'providers/shelley-proxy.js', 'README.md', ]; for (const f of files) { assert(`${f} exists`, existsSync(join(root, f))); } // ── 2. package.json shape ──────────────────────────────────────────────────── console.log('\n── 2. package.json ─────────────────────────────────────────────'); const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8')); assert('name = token-monitor', pkg.name === 'token-monitor'); assert('type = module (ESM)', pkg.type === 'module'); assert('no external dependencies', !pkg.dependencies || Object.keys(pkg.dependencies).length === 0); assert('engines.node >= 18', pkg.engines?.node?.includes('18') || pkg.engines?.node?.includes('>=18')); // ── 3. Severity logic (unit test, importable) ──────────────────────────────── console.log('\n── 3. Severity logic ───────────────────────────────────────────'); const { getSeverity } = await import('./report.js'); assert('teams: rejected → critical', getSeverity({ type: 'teams-direct', status: 'rejected', utilization_5h: 0, utilization_7d: 1.0 }) === 'critical'); assert('teams: 7d > 0.85 → warning', getSeverity({ type: 'teams-direct', status: 'allowed', utilization_5h: 0.2, utilization_7d: 0.9 }) === 'warning'); assert('teams: 5h > 0.7 → warning', getSeverity({ type: 'teams-direct', status: 'allowed', utilization_5h: 0.75, utilization_7d: 0.4 }) === 'warning'); assert('teams: healthy → ok', getSeverity({ type: 'teams-direct', status: 'allowed', utilization_5h: 0.3, utilization_7d: 0.4 }) === 'ok'); assert('shelley: high token use → warning', getSeverity({ type: 'shelley-proxy', tokens_remaining: 5000, tokens_limit: 50000 }) === 'warning'); assert('shelley: healthy → ok', getSeverity({ type: 'shelley-proxy', tokens_remaining: 45000, tokens_limit: 50000 }) === 'ok'); assert('api-direct → unknown', getSeverity({ type: 'api-direct' }) === 'unknown'); // ── 4. Provider registry ───────────────────────────────────────────────────── console.log('\n── 4. Provider registry ────────────────────────────────────────'); const { getProviders } = await import('./providers/index.js'); const providers = getProviders(); const names = Object.keys(providers); assert('team-vigilio in registry', names.includes('team-vigilio')); assert('team-molto in registry', names.includes('team-molto')); assert('team-nadja in registry', names.includes('team-nadja')); assert('team-ludo in registry', names.includes('team-ludo')); assert('team-buio in registry', names.includes('team-buio')); assert('shelley-proxy in registry', names.includes('shelley-proxy')); assert('api-ateam in registry', names.includes('api-ateam')); assert('zai NOT in registry (not anthropic-messages)', !names.includes('zai')); for (const [name, p] of Object.entries(providers)) { assert(`${name} has baseUrl`, typeof p.baseUrl === 'string' && p.baseUrl.length > 0); assert(`${name} has type`, ['teams-direct', 'shelley-proxy', 'api-direct'].includes(p.type)); } // ── 5. Teams header parser ─────────────────────────────────────────────────── console.log('\n── 5. Teams header parser ──────────────────────────────────────'); const { parseTeamsHeaders } = await import('./providers/anthropic-teams.js'); // Simulate a 200 OK response with unified headers const ok200headers = new Map([ ['anthropic-ratelimit-unified-status', 'allowed'], ['anthropic-ratelimit-unified-5h-status', 'allowed'], ['anthropic-ratelimit-unified-5h-utilization', '0.32'], ['anthropic-ratelimit-unified-5h-reset', '1775336400'], ['anthropic-ratelimit-unified-7d-status', 'allowed'], ['anthropic-ratelimit-unified-7d-utilization', '0.45'], ['anthropic-ratelimit-unified-7d-reset', '1775869200'], ['anthropic-ratelimit-unified-representative-claim', 'five_hour'], ['anthropic-ratelimit-unified-fallback-percentage', '0.5'], ['anthropic-ratelimit-unified-reset', '1775336400'], ['anthropic-ratelimit-unified-overage-status', 'rejected'], ['anthropic-ratelimit-unified-overage-disabled-reason', 'org_level_disabled'], ['anthropic-organization-id', '1d7653ad-11d9-4029-ba1a-a2dd4cd0b2f3'], ]); const fakeHeaders200 = { get: (k) => ok200headers.get(k.toLowerCase()) || null }; const parsed200 = parseTeamsHeaders(fakeHeaders200, 200, 'team-test'); assert('200: type = teams-direct', parsed200.type === 'teams-direct'); assert('200: status = allowed', parsed200.status === 'allowed'); assert('200: utilization_5h is number', typeof parsed200.utilization_5h === 'number'); assert('200: utilization_5h = 0.32', parsed200.utilization_5h === 0.32); assert('200: utilization_7d = 0.45', parsed200.utilization_7d === 0.45); assert('200: representative_claim present', parsed200.representative_claim === 'five_hour'); assert('200: reset_timestamp is number', typeof parsed200.reset_timestamp === 'number'); assert('200: reset_in_seconds is number', typeof parsed200.reset_in_seconds === 'number'); assert('200: organization_id present', parsed200.organization_id === '1d7653ad-11d9-4029-ba1a-a2dd4cd0b2f3'); assert('200: severity = ok', parsed200.severity === 'ok'); // Simulate 429 with rejected status const rejected429headers = new Map([ ['anthropic-ratelimit-unified-status', 'rejected'], ['anthropic-ratelimit-unified-5h-status', 'allowed'], ['anthropic-ratelimit-unified-5h-utilization', '0.0'], ['anthropic-ratelimit-unified-5h-reset', '1775322000'], ['anthropic-ratelimit-unified-7d-status', 'rejected'], ['anthropic-ratelimit-unified-7d-utilization', '1.0'], ['anthropic-ratelimit-unified-7d-surpassed-threshold', '1.0'], ['anthropic-ratelimit-unified-7d-reset', '1775404800'], ['anthropic-ratelimit-unified-representative-claim', 'seven_day'], ['anthropic-ratelimit-unified-fallback-percentage', '0.5'], ['anthropic-ratelimit-unified-reset', '1775404800'], ['anthropic-ratelimit-unified-overage-status', 'rejected'], ['anthropic-ratelimit-unified-overage-disabled-reason', 'org_level_disabled'], ['anthropic-organization-id', '1d7653ad-11d9-4029-ba1a-a2dd4cd0b2f3'], ['retry-after', '83690'], ]); const fakeHeaders429 = { get: (k) => rejected429headers.get(k.toLowerCase()) || null }; const parsed429 = parseTeamsHeaders(fakeHeaders429, 429, 'team-vigilio'); assert('429: status = rejected', parsed429.status === 'rejected'); assert('429: utilization_7d = 1.0', parsed429.utilization_7d === 1.0); assert('429: severity = critical', parsed429.severity === 'critical'); assert('429: retry_after_seconds = 83690', parsed429.retry_after_seconds === 83690); // 401 invalid key const { parseTeamsHeaders: ph } = await import('./providers/anthropic-teams.js'); const parsed401 = ph({ get: () => null }, 401, 'team-ludo'); assert('401: status = invalid_key', parsed401.status === 'invalid_key'); assert('401: utilization_5h = null', parsed401.utilization_5h === null); assert('401: utilization_7d = null', parsed401.utilization_7d === null); assert('401: severity = unknown', parsed401.severity === 'unknown'); // ── 6. Shelley header parser ───────────────────────────────────────────────── console.log('\n── 6. Shelley header parser ────────────────────────────────────'); const { parseShelleyHeaders } = await import('./providers/shelley-proxy.js'); const shelleyHeaderMap = new Map([ ['anthropic-ratelimit-tokens-limit', '4800000'], ['anthropic-ratelimit-tokens-remaining', '4750000'], ['anthropic-ratelimit-tokens-reset', '2026-04-04T13:00:00Z'], ['anthropic-ratelimit-requests-limit', '20000'], ['anthropic-ratelimit-requests-remaining', '19999'], ['anthropic-ratelimit-requests-reset', '2026-04-04T16:45:09Z'], ['exedev-gateway-cost', '0.000013'], ]); const fakeShelleyHeaders = { get: (k) => shelleyHeaderMap.get(k.toLowerCase()) || null }; const parsedShelley = parseShelleyHeaders(fakeShelleyHeaders, 200); assert('shelley: type = shelley-proxy', parsedShelley.type === 'shelley-proxy'); assert('shelley: status = ok', parsedShelley.status === 'ok'); assert('shelley: tokens_limit = 4800000', parsedShelley.tokens_limit === 4800000); assert('shelley: tokens_remaining = 4750000', parsedShelley.tokens_remaining === 4750000); assert('shelley: tokens_reset present', typeof parsedShelley.tokens_reset === 'string'); assert('shelley: requests_limit = 20000', parsedShelley.requests_limit === 20000); assert('shelley: requests_remaining = 19999', parsedShelley.requests_remaining === 19999); assert('shelley: cost_per_call_usd = 0.000013', parsedShelley.cost_per_call_usd === 0.000013); assert('shelley: severity = ok', parsedShelley.severity === 'ok'); // ── 7. api-ateam provider ──────────────────────────────────────────────────── console.log('\n── 7. api-ateam (no billing data) ──────────────────────────────'); const { getApiAteamStatus } = await import('./providers/anthropic-api.js'); const apiStatus = getApiAteamStatus(); assert('api-ateam: type = api-direct', apiStatus.type === 'api-direct'); assert('api-ateam: status = no_billing_data', apiStatus.status === 'no_billing_data'); assert('api-ateam: message is string', typeof apiStatus.message === 'string' && apiStatus.message.length > 0); assert('api-ateam: severity = unknown', apiStatus.severity === 'unknown'); // ── 8. Logger ──────────────────────────────────────────────────────────────── console.log('\n── 8. Logger ───────────────────────────────────────────────────'); const { logRun } = await import('./logger.js'); const testData = { test: true, value: 42, providers: {} }; logRun(testData); const today = new Date().toISOString().slice(0, 10); const logFile = join(homedir(), '.logs', 'token-monitor', `${today}.jsonl`); assert('log file created', existsSync(logFile)); const lastLine = readFileSync(logFile, 'utf-8').trim().split('\n').pop(); const logEntry = JSON.parse(lastLine); assert('log entry has ts', typeof logEntry.ts === 'string'); assert('log entry has test data', logEntry.test === true && logEntry.value === 42); // ── 9. Report generator ────────────────────────────────────────────────────── console.log('\n── 9. Report generator ─────────────────────────────────────────'); const { generateReport } = await import('./report.js'); const sampleResult = { timestamp: '2026-04-04T12:00:00Z', providers: { 'team-vigilio': { type: 'teams-direct', status: 'rejected', utilization_5h: 0.0, utilization_7d: 1.0, representative_claim: 'seven_day', reset_timestamp: Math.floor(Date.now() / 1000) + 82800, reset_in_seconds: 82800, severity: 'critical', }, 'team-molto': { type: 'teams-direct', status: 'allowed', utilization_5h: 0.32, utilization_7d: 0.45, representative_claim: 'five_hour', reset_timestamp: Math.floor(Date.now() / 1000) + 3600, reset_in_seconds: 3600, severity: 'ok', }, 'team-ludo': { type: 'teams-direct', status: 'invalid_key', utilization_5h: null, utilization_7d: null, severity: 'unknown', }, 'shelley-proxy': { type: 'shelley-proxy', status: 'ok', tokens_remaining: 45000, tokens_limit: 50000, requests_remaining: 48, requests_limit: 50, tokens_reset: '2026-04-04T13:00:00Z', cost_per_call_usd: 0.000013, severity: 'ok', }, 'api-ateam': { type: 'api-direct', status: 'no_billing_data', message: 'Anthropic API does not expose billing/quota via REST', severity: 'unknown', }, }, }; const report = generateReport(sampleResult); assert('report is string', typeof report === 'string'); assert('report contains Token Monitor header', report.includes('Token Monitor')); assert('report contains team-vigilio', report.includes('team-vigilio')); assert('report contains CRITICAL', report.includes('CRITICAL')); assert('report contains team-molto', report.includes('team-molto')); assert('report contains shelley-proxy', report.includes('shelley-proxy')); assert('report contains api-ateam', report.includes('api-ateam')); assert('report contains Overall summary', report.toLowerCase().includes('overall')); // ── 10. CLI: --summary flag ────────────────────────────────────────────────── console.log('\n── 10. CLI flags (--summary, --json) ───────────────────────────'); // --summary: exit 0, stdout contains provider names const summaryResult = runSafe('node monitor.js --summary'); assert('--summary exits 0', summaryResult.code === 0, `exit code: ${summaryResult.code}\n${summaryResult.stderr || ''}`); assert('--summary output contains Token Monitor', summaryResult.stdout.includes('Token Monitor')); assert('--summary output contains provider names', summaryResult.stdout.includes('team-') || summaryResult.stdout.includes('shelley')); // --json: exit 0, valid JSON, correct schema const jsonResult = runSafe('node monitor.js --json'); assert('--json exits 0', jsonResult.code === 0, `exit code: ${jsonResult.code}\n${jsonResult.stderr || ''}`); let jsonData; try { jsonData = JSON.parse(jsonResult.stdout); assert('--json outputs valid JSON', true); } catch (e) { assert('--json outputs valid JSON', false, e.message); } if (jsonData) { assert('JSON has timestamp', typeof jsonData.timestamp === 'string'); assert('JSON has providers object', typeof jsonData.providers === 'object'); const pnames = Object.keys(jsonData.providers); assert('JSON providers includes team-vigilio', pnames.includes('team-vigilio')); assert('JSON providers includes shelley-proxy', pnames.includes('shelley-proxy')); assert('JSON providers includes api-ateam', pnames.includes('api-ateam')); // Teams-direct entries must have required fields for (const [name, p] of Object.entries(jsonData.providers)) { if (p.type === 'teams-direct' && p.status !== 'invalid_key') { assert(`${name}: has utilization_5h`, typeof p.utilization_5h === 'number'); assert(`${name}: has utilization_7d`, typeof p.utilization_7d === 'number'); assert(`${name}: has severity`, typeof p.severity === 'string'); assert(`${name}: has reset_in_seconds`, typeof p.reset_in_seconds === 'number'); } if (p.type === 'shelley-proxy') { assert('shelley-proxy: has cost_per_call_usd', typeof p.cost_per_call_usd === 'number'); assert('shelley-proxy: has tokens_remaining', typeof p.tokens_remaining === 'number'); assert('shelley-proxy: has tokens_limit', typeof p.tokens_limit === 'number'); } if (p.type === 'api-direct') { assert('api-ateam: status = no_billing_data', p.status === 'no_billing_data'); } } } // Default run: exit 0, log file updated const defaultResult = runSafe('node monitor.js'); assert('default run exits 0', defaultResult.code === 0, `exit code: ${defaultResult.code}\n${defaultResult.stderr || ''}`); // Log file should exist and have content const logFileAfter = join(homedir(), '.logs', 'token-monitor', `${today}.jsonl`); assert('log file exists after default run', existsSync(logFileAfter)); const logLines = readFileSync(logFileAfter, 'utf-8').trim().split('\n'); assert('log file has at least 2 entries', logLines.length >= 2); // ── 11. Gemini provider parser ──────────────────────────────────────────────── console.log('\n── 11. Gemini provider parser ──────────────────────────────────'); const gemini429Body = { error: { code: 429, status: 'RESOURCE_EXHAUSTED', details: [ { '@type': 'type.googleapis.com/google.rpc.QuotaFailure', violations: [ { quotaMetric: 'generativelanguage.googleapis.com/generate_content_free_tier_requests', quotaId: 'GenerateRequestsPerMinutePerProjectPerModel-FreeTier', quotaDimensions: { location: 'global', model: 'gemini-2.0-flash' }, }, { quotaMetric: 'generativelanguage.googleapis.com/generate_content_free_tier_requests', quotaId: 'GenerateRequestsPerDayPerProjectPerModel-FreeTier', quotaDimensions: { location: 'global', model: 'gemini-2.0-flash' }, }, ], }, { '@type': 'type.googleapis.com/google.rpc.RetryInfo', retryDelay: '43s' }, ], }, }; assert('providers/gemini.js exists', existsSync(join(root, 'providers/gemini.js'))); const g429 = parseGeminiBody(gemini429Body, 429); assert('gemini 429: status = exhausted', g429.status === 'exhausted'); assert('gemini 429: type = gemini-api', g429.type === 'gemini-api'); assert('gemini 429: quota_violations is array', Array.isArray(g429.quota_violations)); assert('gemini 429: quota_violations has 2 entries', g429.quota_violations.length === 2); assert('gemini 429: retry_delay_seconds = 43', g429.retry_delay_seconds === 43); assert('gemini 429: severity = critical', g429.severity === 'critical'); const g200 = parseGeminiBody(null, 200); assert('gemini 200: status = ok', g200.status === 'ok'); assert('gemini 200: severity = ok', g200.severity === 'ok'); assert('gemini 200: quota_violations is empty array', Array.isArray(g200.quota_violations) && g200.quota_violations.length === 0); const g401 = parseGeminiBody(null, 401); assert('gemini 401: status = invalid_key', g401.status === 'invalid_key'); assert('gemini 401: severity = unknown', g401.severity === 'unknown'); // ── 12. x.ai provider parser ───────────────────────────────────────────────── console.log('\n── 12. x.ai provider parser ────────────────────────────────────'); class MockHeaders { constructor(map) { this._map = map; } get(name) { return this._map[name.toLowerCase()] ?? null; } } const xai200Headers = new MockHeaders({ 'x-ratelimit-limit-requests': '1000', 'x-ratelimit-remaining-requests': '998', 'x-ratelimit-limit-tokens': '500000', 'x-ratelimit-remaining-tokens': '499981', }); const xai200HeadersNearFull = new MockHeaders({ 'x-ratelimit-limit-requests': '1000', 'x-ratelimit-remaining-requests': '5', 'x-ratelimit-limit-tokens': '500000', 'x-ratelimit-remaining-tokens': '499981', }); const xai429Headers = new MockHeaders({ 'x-ratelimit-remaining-requests': '0', }); assert('providers/xai.js exists', existsSync(join(root, 'providers/xai.js'))); const xNoKey = parseXaiHeaders(null, 200, null); assert('xai no key: status = no_key', xNoKey.status === 'no_key'); assert('xai no key: severity = unknown', xNoKey.severity === 'unknown'); const x200 = parseXaiHeaders(xai200Headers, 200, 'xai-key'); assert('xai 200: status = ok', x200.status === 'ok'); assert('xai 200: requests_remaining = 998', x200.requests_remaining === 998); assert('xai 200: tokens_remaining = 499981', x200.tokens_remaining === 499981); assert('xai 200: severity = ok', x200.severity === 'ok'); const x200Near = parseXaiHeaders(xai200HeadersNearFull, 200, 'xai-key'); assert('xai 200 near-full: severity = warning', x200Near.severity === 'warning'); const x429 = parseXaiHeaders(xai429Headers, 429, 'xai-key'); assert('xai 429: status = rate_limited', x429.status === 'rate_limited'); assert('xai 429: severity = critical', x429.severity === 'critical'); const x401 = parseXaiHeaders(null, 401, 'xai-key'); assert('xai 401: status = invalid_key', x401.status === 'invalid_key'); // ── Results ────────────────────────────────────────────────────────────────── console.log('\n' + '═'.repeat(50)); console.log(`Tests: ${passed + failed} | Passed: ${passed} | Failed: ${failed}`); if (failures.length > 0) { console.log('\nFailed:'); for (const f of failures) { console.log(` ✗ ${f.label}${f.detail ? ' — ' + f.detail : ''}`); } process.exit(1); } else { console.log('\nAll tests pass. ✓'); process.exit(0); }