// apps/kimi-web/test/daemon-client.test.ts // DaemonKimiWebApi.getSessionGoal — wire → app mapping of GET /sessions/{id}/goal: // a present snapshot, explicit null (no active goal), and the request URL. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { DaemonKimiWebApi } from '../src/api/daemon/client'; function envelope(data: unknown): Response { return new Response(JSON.stringify({ code: 0, msg: '', data }), { status: 200, headers: { 'content-type': 'application/json' }, }); } const WIRE_GOAL = { goalId: 'goal_1', objective: 'fix all lint warnings', status: 'active', turnsUsed: 1, tokensUsed: 0, wallClockMs: 0, budget: { tokenBudget: null, turnBudget: null, wallClockBudgetMs: null, remainingTokens: null, remainingTurns: null, remainingWallClockMs: null, tokenBudgetReached: false, turnBudgetReached: false, wallClockBudgetReached: false, overBudget: false, }, }; function createApi(): DaemonKimiWebApi { return new DaemonKimiWebApi({ serverHttpUrl: 'http://daemon.test', clientId: 'web_test', clientName: 'test', clientVersion: '0.0.0', clientUiMode: 'test', }); } describe('DaemonKimiWebApi.getSessionGoal', () => { beforeEach(() => { vi.stubGlobal('fetch', vi.fn()); }); afterEach(() => { vi.unstubAllGlobals(); }); it('maps a present goal snapshot', async () => { vi.mocked(fetch).mockResolvedValue(envelope(WIRE_GOAL)); const goal = await createApi().getSessionGoal('sess_1'); expect(goal?.objective).toBe('fix all lint warnings'); expect(goal?.status).toBe('active'); expect(goal?.turnsUsed).toBe(1); }); it('maps null to null (no active goal)', async () => { vi.mocked(fetch).mockResolvedValue(envelope(null)); const goal = await createApi().getSessionGoal('sess_1'); expect(goal).toBeNull(); }); it('requests the session goal endpoint', async () => { vi.mocked(fetch).mockResolvedValue(envelope(null)); await createApi().getSessionGoal('sess_42'); expect(vi.mocked(fetch).mock.calls[0]?.[0]).toBe( 'http://daemon.test/api/v1/sessions/sess_42/goal', ); }); });