import { beforeEach, describe, expect, it, vi } from 'vitest'; const hostApiFetchMock = vi.hoisted(() => vi.fn()); vi.mock('../../src/lib/host-api', () => ({ hostApiFetch: (...args: unknown[]) => hostApiFetchMock(...args), })); import { findCodingFiles, getCodingConversationChanges, getCodingConversationCommands, getCodingFileContent, getCodingFileStatus, getCodingSkills, searchCodingText, } from '../../src/lib/coding-product-tools'; describe('PI-105 Renderer coding product facade', () => { beforeEach(() => { hostApiFetchMock.mockReset().mockResolvedValue({}); }); it('uses only the vendor-neutral coding file and catalog routes', async () => { await getCodingFileStatus(); await findCodingFiles('app file', 25); await getCodingFileContent('src/app file.ts'); await searchCodingText('hello world'); await getCodingSkills('builder/one'); await getCodingConversationCommands('conversation/one'); await getCodingConversationChanges('conversation/one'); expect(hostApiFetchMock.mock.calls.map(([route]) => route)).toEqual([ '/api/coding/files/status', '/api/coding/files/find?query=app+file&limit=25', '/api/coding/files/content?path=src%2Fapp+file.ts', '/api/coding/search?pattern=hello+world', '/api/coding/skills?agentId=builder%2Fone', '/api/coding/conversations/conversation%2Fone/commands', '/api/coding/conversations/conversation%2Fone/changes', ]); expect(JSON.stringify(hostApiFetchMock.mock.calls)).not.toContain('/api/opencode'); }); });