Files
EJClaw/setup/verify-state.test.ts
2026-03-31 06:54:49 +09:00

132 lines
3.2 KiB
TypeScript

import fs from 'fs';
import os from 'os';
import path from 'path';
import { afterEach, describe, expect, it } from 'vitest';
import { Database } from 'bun:sqlite';
import type { ServiceDef } from './service-defs.js';
import type { ServiceCheck } from './verify-services.js';
import {
buildVerifySummary,
detectChannelAuth,
detectCredentials,
loadRegisteredGroupsSummary,
} from './verify-state.js';
describe('verify state helpers', () => {
const tempRoots: string[] = [];
afterEach(() => {
for (const root of tempRoots.splice(0)) {
fs.rmSync(root, { recursive: true, force: true });
}
});
it('detects configured credentials from .env', () => {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ejclaw-verify-'));
tempRoots.push(tempRoot);
fs.writeFileSync(
path.join(tempRoot, '.env'),
'CLAUDE_CODE_OAUTH_TOKEN=test-token\n',
);
expect(detectCredentials(tempRoot)).toBe('configured');
});
it('detects channel auth from either env source', () => {
expect(
detectChannelAuth(
{ DISCORD_BOT_TOKEN: '' },
{ DISCORD_BOT_TOKEN: 'discord-token' },
),
).toEqual({
discord: 'configured',
});
});
it('loads registered group counts from the sqlite store', () => {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ejclaw-verify-'));
tempRoots.push(tempRoot);
const dbPath = path.join(tempRoot, 'messages.db');
const db = new Database(dbPath);
db.exec(`
CREATE TABLE registered_groups (
jid TEXT PRIMARY KEY,
agent_type TEXT
);
`);
db.exec(`
INSERT INTO registered_groups (jid, agent_type) VALUES
('group-1', 'claude-code'),
('group-2', 'codex'),
('group-3', 'codex');
`);
db.close();
expect(loadRegisteredGroupsSummary(dbPath)).toEqual({
registeredGroups: 3,
groupsByAgent: {
'claude-code': 1,
codex: 2,
},
});
});
it('builds a successful verification summary when all gates pass', () => {
const services: ServiceCheck[] = [{ name: 'ejclaw', status: 'running' }];
const serviceDefs: ServiceDef[] = [
{
kind: 'primary',
name: 'ejclaw',
description: 'EJClaw',
launchdLabel: 'com.ejclaw',
logName: 'ejclaw',
},
{
kind: 'codex',
name: 'ejclaw-codex',
description: 'Codex',
launchdLabel: 'com.ejclaw.codex',
logName: 'ejclaw-codex',
},
];
expect(
buildVerifySummary(
services,
serviceDefs,
'configured',
{ discord: 'configured' },
2,
{ codex: 1 },
),
).toMatchObject({
status: 'success',
configuredChannels: ['discord'],
codexConfigured: true,
reviewConfigured: false,
servicesSummary: { ejclaw: 'running' },
});
});
it('fails verification when any required gate is missing', () => {
const services: ServiceCheck[] = [{ name: 'ejclaw', status: 'stopped' }];
expect(
buildVerifySummary(
services,
[],
'missing',
{},
0,
{},
),
).toMatchObject({
status: 'failed',
configuredChannels: [],
servicesSummary: { ejclaw: 'stopped' },
});
});
});