Files
ccs/tests/unit/auth-resources-command.test.ts
T

181 lines
5.4 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, spyOn } from 'bun:test';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import ProfileRegistry from '../../src/auth/profile-registry';
import InstanceManager from '../../src/management/instance-manager';
import { handleResources } from '../../src/auth/commands/resources-command';
import { handleCreate } from '../../src/auth/commands/create-command';
describe('auth resources command', () => {
let tempRoot = '';
let originalCcsHome: string | undefined;
let originalUnifiedMode: string | undefined;
beforeEach(() => {
tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-auth-resources-'));
originalCcsHome = process.env.CCS_HOME;
originalUnifiedMode = process.env.CCS_UNIFIED_CONFIG;
process.env.CCS_HOME = tempRoot;
process.env.CCS_UNIFIED_CONFIG = '1';
});
afterEach(() => {
if (originalCcsHome !== undefined) process.env.CCS_HOME = originalCcsHome;
else delete process.env.CCS_HOME;
if (originalUnifiedMode !== undefined) process.env.CCS_UNIFIED_CONFIG = originalUnifiedMode;
else delete process.env.CCS_UNIFIED_CONFIG;
if (tempRoot && fs.existsSync(tempRoot)) {
fs.rmSync(tempRoot, { recursive: true, force: true });
}
});
it('updates an existing account shared resource mode without changing context metadata', async () => {
const ccsDir = path.join(tempRoot, '.ccs');
fs.mkdirSync(ccsDir, { recursive: true });
fs.writeFileSync(
path.join(ccsDir, 'config.yaml'),
[
'version: 8',
'accounts:',
' work:',
' created: "2026-02-01T00:00:00.000Z"',
' last_used: null',
' context_mode: shared',
' context_group: sprint-a',
'profiles: {}',
'cliproxy:',
' oauth_accounts: {}',
' providers: {}',
' variants: {}',
].join('\n'),
'utf8'
);
const registry = new ProfileRegistry();
const instanceMgr = new InstanceManager();
const ensureSpy = spyOn(InstanceManager.prototype, 'ensureInstance').mockResolvedValue(
path.join(ccsDir, 'instances', 'work')
);
const lines: string[] = [];
const originalLog = console.log;
console.log = (...args: unknown[]) => {
lines.push(args.map(String).join(' '));
};
try {
await handleResources(
{
registry,
instanceMgr,
version: 'test',
},
['work', '--mode', 'profile-local', '--json']
);
} finally {
console.log = originalLog;
ensureSpy.mockRestore();
}
const output = JSON.parse(lines.join('\n')) as {
shared_resource_mode: string;
bare?: boolean;
};
expect(output.shared_resource_mode).toBe('profile-local');
expect(output.bare).toBe(true);
const account = registry.getAllAccountsUnified().work;
expect(account.shared_resource_mode).toBe('profile-local');
expect(account.bare).toBe(true);
expect(account.context_mode).toBe('shared');
expect(account.context_group).toBe('sprint-a');
});
it('rolls back inferred shared metadata when instance reconciliation fails', async () => {
const ccsDir = path.join(tempRoot, '.ccs');
fs.mkdirSync(ccsDir, { recursive: true });
fs.writeFileSync(
path.join(ccsDir, 'config.yaml'),
[
'version: 8',
'accounts:',
' work:',
' created: "2026-02-01T00:00:00.000Z"',
' last_used: null',
'profiles: {}',
'cliproxy:',
' oauth_accounts: {}',
' providers: {}',
' variants: {}',
].join('\n'),
'utf8'
);
const registry = new ProfileRegistry();
const instanceMgr = new InstanceManager();
const ensureSpy = spyOn(InstanceManager.prototype, 'ensureInstance').mockRejectedValue(
new Error('reconcile failed')
);
try {
await expect(
handleResources(
{
registry,
instanceMgr,
version: 'test',
},
['work', '--mode', 'profile-local']
)
).rejects.toThrow('reconcile failed');
} finally {
ensureSpy.mockRestore();
}
const account = registry.getAllAccountsUnified().work;
expect(account.shared_resource_mode).toBeUndefined();
expect(account.bare).toBeUndefined();
});
it('rejects --mode on auth create instead of silently ignoring it', async () => {
const registry = new ProfileRegistry();
const instanceMgr = new InstanceManager();
const originalExit = process.exit;
const originalLog = console.log;
const originalError = console.error;
const lines: string[] = [];
process.exit = ((code?: number) => {
throw new Error(`process.exit(${code ?? 0})`);
}) as typeof process.exit;
console.log = (...args: unknown[]) => {
lines.push(args.map(String).join(' '));
};
console.error = (...args: unknown[]) => {
lines.push(args.map(String).join(' '));
};
try {
await expect(
handleCreate(
{
registry,
instanceMgr,
version: 'test',
},
['work', '--mode', 'profile-local']
)
).rejects.toThrow('process.exit(7)');
} finally {
process.exit = originalExit;
console.log = originalLog;
console.error = originalError;
}
expect(lines.join('\n')).toContain('Unknown option(s): "--mode"');
});
});