File size: 2,794 Bytes
4e23b01 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | import { describe, expect, it, vi } from 'vitest';
import { Session } from '#/session';
import type { SDKRpcClientBase } from '#/rpc';
function makeSession() {
const rpc = {
createGoal: vi.fn(async () => ({ goalId: 'g1' })),
getGoal: vi.fn(async () => ({ goal: null })),
pauseGoal: vi.fn(async () => ({ goalId: 'g1' })),
resumeGoal: vi.fn(async () => ({ goalId: 'g1' })),
cancelGoal: vi.fn(async () => ({ goalId: 'g1' })),
getCronTasks: vi.fn(async () => ({ tasks: [] })),
clearSessionHandlers: vi.fn(),
} as unknown as SDKRpcClientBase;
const session = new Session({ id: 'ses_goal', workDir: '/tmp/work', rpc });
return { session, rpc };
}
describe('Session goal methods', () => {
it('createGoal forwards the supported payload with sessionId', async () => {
const { session, rpc } = makeSession();
await session.createGoal({
objective: 'Ship feature X',
replace: true,
});
expect(rpc.createGoal).toHaveBeenCalledWith({
sessionId: 'ses_goal',
objective: 'Ship feature X',
replace: true,
});
});
it('getGoal forwards sessionId', async () => {
const { session, rpc } = makeSession();
await session.getGoal();
expect(rpc.getGoal).toHaveBeenCalledWith({ sessionId: 'ses_goal' });
});
it('pauseGoal forwards sessionId', async () => {
const { session, rpc } = makeSession();
await session.pauseGoal();
expect(rpc.pauseGoal).toHaveBeenCalledWith({ sessionId: 'ses_goal' });
});
it('resumeGoal forwards sessionId', async () => {
const { session, rpc } = makeSession();
await session.resumeGoal();
expect(rpc.resumeGoal).toHaveBeenCalledWith({ sessionId: 'ses_goal' });
});
it('cancelGoal forwards sessionId', async () => {
const { session, rpc } = makeSession();
await session.cancelGoal();
expect(rpc.cancelGoal).toHaveBeenCalledWith({ sessionId: 'ses_goal' });
});
it('getCronTasks forwards sessionId and returns the task list', async () => {
const { session, rpc } = makeSession();
const result = await session.getCronTasks();
expect(rpc.getCronTasks).toHaveBeenCalledWith({ sessionId: 'ses_goal' });
expect(result).toEqual({ tasks: [] });
});
it('does not expose a public clearGoal or updateGoal method', () => {
const { session } = makeSession();
expect((session as unknown as { clearGoal?: unknown }).clearGoal).toBeUndefined();
expect((session as unknown as { updateGoal?: unknown }).updateGoal).toBeUndefined();
});
it('keeps the goal metadata key reserved for lifecycle methods', async () => {
const { session } = makeSession();
await expect(
session.updateMetadata({ goal: { status: 'complete' } }),
).rejects.toMatchObject({ code: 'goal.metadata_reserved' });
});
});
|