test/adduser.test.js
Rama main · réplica de lectura del repositorio original.
import { describe, it, expect, afterEach } from 'vitest';
import { execFileSync } from 'child_process';
import { writeFileSync, readFileSync, rmSync } from 'fs';
// USERS points at the hermetic per-file path from test/setup.js.
const USERS = process.env.AGENT007_USERS_PATH;
function run(args, expectOk = true, env = {}) {
try {
const out = execFileSync('node', ['bin/adduser.js', ...args], {
env: { ...process.env, AGENT007_USERS_PATH: USERS, ...env }, encoding: 'utf8',
});
return { code: 0, out };
} catch (e) {
if (expectOk) throw e;
return { code: e.status, out: (e.stdout || '') + (e.stderr || '') };
}
}
const users = () => JSON.parse(readFileSync(USERS, 'utf8'));
describe('adduser CLI', () => {
afterEach(() => { try { rmSync(USERS, { force: true }); } catch {} });
it('rejects an empty name', () => {
const r = run([''], false);
expect(r.code).not.toBe(0);
expect(r.out).toMatch(/Usage/);
});
it('creates the first user and warns login is now required', () => {
const r = run(['Alice'], true, { PUBLIC_URL: '', PORT: '7123' });
expect(r.out).toMatch(/first user/i);
expect(r.out).toMatch(/http:\/\/localhost:7123\/\?token=/);
const u = users();
expect(u).toHaveLength(1);
expect(u[0].displayName).toBe('Alice');
expect(u[0].color).toBe('#d4a847'); // USER_COLORS[0]
expect(u[0].tokenHash).toHaveLength(64);
});
it("links to PUBLIC_URL when the app is behind a proxy", () => {
expect(run(['Ada'], true, { PUBLIC_URL: 'https://agent.example.com/' }).out).toMatch(/ https:\/\/agent\.example\.com\/\?token=/);
});
it('appends a second user with the next color and no first-user notice', () => {
run(['Alice']);
const r = run(['Bob']);
expect(r.out).not.toMatch(/first user/i);
const u = users();
expect(u).toHaveLength(2);
expect(u[1].color).toBe('#58a6ff'); // USER_COLORS[1]
});
it('rejects a duplicate display name without appending', () => {
run(['Alice']);
const r = run(['Alice'], false);
expect(r.code).not.toBe(0);
expect(r.out).toMatch(/already exists/);
expect(users()).toHaveLength(1);
});
it('exits with an error when users.json is corrupt', () => {
writeFileSync(USERS, '{ not json');
const r = run(['Alice'], false);
expect(r.code).not.toBe(0);
expect(r.out).toMatch(/Cannot read/);
});
});