Files
wehub-resource-sync 7088f49b01
Build dist / build (push) Has been cancelled
CI / test (18.x) (push) Has been cancelled
CI / test (20.x) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:33 +08:00

144 lines
5.1 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
import path from 'node:path';
import { tmpdir } from 'node:os';
import { deriveAuthInfo, readAuthInfo, truncateUser, formatAuthSegment } from '../dist/auth.js';
const MAX_ACCOUNT = {
oauthAccount: {
emailAddress: 'someone.long@example.com',
displayName: 'Some One',
organizationType: 'claude_max',
organizationRateLimitTier: 'default_claude_max_20x',
},
};
function restoreEnvVar(name, value) {
if (value === undefined) {
delete process.env[name];
} else {
process.env[name] = value;
}
}
test('deriveAuthInfo formats claude_max with rate-limit tier', () => {
const info = deriveAuthInfo(MAX_ACCOUNT, {});
assert.equal(info.method, 'Claude Max 20x');
assert.equal(info.user, 'someone.long');
});
test('deriveAuthInfo formats claude_pro without tier', () => {
const info = deriveAuthInfo({
oauthAccount: {
emailAddress: 'a@b.com',
organizationType: 'claude_pro',
organizationRateLimitTier: 'default_claude_pro',
},
}, {});
assert.equal(info.method, 'Claude Pro');
assert.equal(info.user, 'a');
});
test('deriveAuthInfo falls back to displayName without email', () => {
const info = deriveAuthInfo({
oauthAccount: {
displayName: 'Some One',
organizationType: 'claude_enterprise',
},
}, {});
assert.equal(info.method, 'Claude Enterprise');
assert.equal(info.user, 'Some One');
});
test('deriveAuthInfo reports API Key when no oauth account but key exported', () => {
const info = deriveAuthInfo({}, { ANTHROPIC_API_KEY: 'sk-test' });
assert.equal(info.method, 'API Key');
assert.equal(info.user, null);
});
test('deriveAuthInfo gives API Key precedence over a stale oauth account', () => {
const info = deriveAuthInfo(MAX_ACCOUNT, { ANTHROPIC_API_KEY: 'sk-test' });
assert.deepEqual(info, { method: 'API Key', user: null });
});
test('deriveAuthInfo returns nulls for missing/invalid input', () => {
assert.deepEqual(deriveAuthInfo(null, {}), { method: null, user: null });
assert.deepEqual(deriveAuthInfo('junk', {}), { method: null, user: null });
assert.deepEqual(deriveAuthInfo({ oauthAccount: 42 }, {}), { method: null, user: null });
});
test('deriveAuthInfo strips ANSI sequences and control characters from values', () => {
const info = deriveAuthInfo({
oauthAccount: {
emailAddress: 'evil\x1b[31m@example.com',
organizationType: 'claude_max',
},
}, {});
assert.equal(info.user, 'evil');
});
test('readAuthInfo honors CLAUDE_CONFIG_DIR and handles unreadable profiles', async () => {
const tempDir = await mkdtemp(path.join(tmpdir(), 'claude-hud-auth-test-'));
const configDir = path.join(tempDir, 'profile');
const originalConfigDir = process.env.CLAUDE_CONFIG_DIR;
const originalApiKey = process.env.ANTHROPIC_API_KEY;
try {
delete process.env.ANTHROPIC_API_KEY;
process.env.CLAUDE_CONFIG_DIR = configDir;
assert.deepEqual(readAuthInfo(), { method: null, user: null });
await writeFile(`${configDir}.json`, JSON.stringify(MAX_ACCOUNT), 'utf8');
assert.deepEqual(readAuthInfo(), { method: 'Claude Max 20x', user: 'someone.long' });
await writeFile(`${configDir}.json`, '{invalid', 'utf8');
assert.deepEqual(readAuthInfo(), { method: null, user: null });
} finally {
restoreEnvVar('CLAUDE_CONFIG_DIR', originalConfigDir);
restoreEnvVar('ANTHROPIC_API_KEY', originalApiKey);
await rm(tempDir, { recursive: true, force: true });
}
});
test('readAuthInfo reports an API key without requiring an oauth profile', async () => {
const tempDir = await mkdtemp(path.join(tmpdir(), 'claude-hud-auth-key-test-'));
const originalConfigDir = process.env.CLAUDE_CONFIG_DIR;
const originalApiKey = process.env.ANTHROPIC_API_KEY;
try {
process.env.CLAUDE_CONFIG_DIR = path.join(tempDir, 'missing');
process.env.ANTHROPIC_API_KEY = 'sk-test';
assert.deepEqual(readAuthInfo(), { method: 'API Key', user: null });
} finally {
restoreEnvVar('CLAUDE_CONFIG_DIR', originalConfigDir);
restoreEnvVar('ANTHROPIC_API_KEY', originalApiKey);
await rm(tempDir, { recursive: true, force: true });
}
});
test('truncateUser truncates with ellipsis and honors 0 = full', () => {
assert.equal(truncateUser('yukinoshita.reimu', 8), 'yukinosh…');
assert.equal(truncateUser('short', 8), 'short');
assert.equal(truncateUser('yukinoshita.reimu', 0), 'yukinoshita.reimu');
});
test('formatAuthSegment joins method and truncated user', () => {
const info = deriveAuthInfo(MAX_ACCOUNT, {});
assert.equal(
formatAuthSegment(info, { showAuth: true, showAuthUser: true, authUserLength: 8 }),
'Claude Max 20x · someone.…',
);
assert.equal(
formatAuthSegment(info, { showAuth: true, showAuthUser: false }),
'Claude Max 20x',
);
assert.equal(
formatAuthSegment(info, { showAuth: false, showAuthUser: true, authUserLength: 0 }),
'someone.long',
);
assert.equal(formatAuthSegment(info, { showAuth: false, showAuthUser: false }), null);
assert.equal(formatAuthSegment(null, { showAuth: true, showAuthUser: true }), null);
});