agent-ecosystem/test/features/member-work-sync/main/RuntimeTurnSettledHookSettings.test.ts
2026-04-30 00:05:58 +03:00

88 lines
3 KiB
TypeScript

import fs from 'fs';
import os from 'os';
import path from 'path';
import { afterEach, describe, expect, it } from 'vitest';
import { RuntimeTurnSettledSpoolPaths } from '@features/member-work-sync/main/infrastructure/RuntimeTurnSettledSpoolPaths';
import { ShellRuntimeTurnSettledHookScriptInstaller } from '@features/member-work-sync/main/infrastructure/ShellRuntimeTurnSettledHookScriptInstaller';
import {
MEMBER_WORK_SYNC_TURN_SETTLED_HOOK_MARKER,
buildRuntimeTurnSettledHookCommand,
buildRuntimeTurnSettledHookSettings,
} from '@features/member-work-sync/main/infrastructure/runtimeTurnSettledHookSettings';
const tempRoots: string[] = [];
function makeTempRoot(): string {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'runtime-turn-settled-hook-'));
tempRoots.push(root);
return root;
}
afterEach(() => {
for (const root of tempRoots.splice(0)) {
fs.rmSync(root, { recursive: true, force: true });
}
});
describe('runtime turn-settled hook settings', () => {
it('builds a shell-quoted command without embedding team identity', () => {
const command = buildRuntimeTurnSettledHookCommand({
scriptPath: "/tmp/agent team's hook.sh",
spoolRoot: '/tmp/member work sync',
provider: 'claude',
});
expect(command).toContain('/bin/sh');
expect(command).toContain("'/tmp/agent team'\\''s hook.sh'");
expect(command).toContain("'claude'");
expect(command).toContain(MEMBER_WORK_SYNC_TURN_SETTLED_HOOK_MARKER);
expect(command).not.toContain('--team-name');
expect(command).not.toContain('--agent-name');
});
it('builds Claude Stop hook settings with a stable marker', () => {
const settings = buildRuntimeTurnSettledHookSettings({
scriptPath: '/tmp/hook.sh',
spoolRoot: '/tmp/spool',
provider: 'claude',
});
expect(settings).toEqual({
hooks: {
Stop: [
{
matcher: '',
hooks: [
{
type: 'command',
command: expect.stringContaining(MEMBER_WORK_SYNC_TURN_SETTLED_HOOK_MARKER),
},
],
},
],
},
});
});
it('installs an executable POSIX shell writer and spool directories', async () => {
const root = makeTempRoot();
const paths = new RuntimeTurnSettledSpoolPaths(root);
const installer = new ShellRuntimeTurnSettledHookScriptInstaller(paths);
const result = await installer.install();
expect(result.scriptPath).toBe(paths.getHookScriptPath());
expect(result.spoolRoot).toBe(paths.getRootDir());
expect(fs.existsSync(paths.getIncomingDir())).toBe(true);
expect(fs.existsSync(paths.getProcessingDir())).toBe(true);
expect(fs.existsSync(paths.getProcessedDir())).toBe(true);
expect(fs.existsSync(paths.getInvalidDir())).toBe(true);
if (process.platform !== 'win32') {
const stat = fs.statSync(result.scriptPath);
expect(stat.mode & 0o111).toBeGreaterThan(0);
}
expect(fs.readFileSync(result.scriptPath, 'utf8')).toContain('dd bs="$max_bytes"');
});
});