import { describe, expect, it } from 'vitest'; import type { HarnessActorContext, HarnessSelection } from '@mosaicstack/types'; import { HarnessOperationError } from '../harness.registry.js'; import { FakeHarnessAdapter } from './fake-harness.adapter.js'; import { runHarnessAdapterContract } from './harness-adapter.contract.js'; const CONTEXT: HarnessActorContext = { actorId: 'actor-1', tenantId: 'tenant-1', seatId: 'seat-1', correlationId: 'correlation-1', }; // The reusable conformance suite. Task 13 re-runs it against the native Pi adapter. runHarnessAdapterContract('FakeHarnessAdapter', () => new FakeHarnessAdapter({ id: 'fake' })); describe('FakeHarnessAdapter no-substitution', () => { it('never substitutes the first catalog row when a bogus selection is requested', async () => { const adapter = new FakeHarnessAdapter({ id: 'fake' }); const catalog = await adapter.catalog(CONTEXT); const firstRow = catalog.models[0]; if (!firstRow) { throw new Error('fixture requires a catalog model'); } const available = catalog.models.find( (entry) => entry.availability === 'available' && entry.modelId !== firstRow.modelId, ); expect(available).toBeDefined(); const selected: HarnessSelection = { harnessId: available!.harnessId, providerId: available!.providerId, modelId: available!.modelId, }; const handle = await adapter.create({ context: CONTEXT, conversationId: 'conversation-1', selection: selected, }); const bogus: HarnessSelection = { harnessId: 'fake', providerId: 'ghost-provider', modelId: 'ghost-model', }; let error: unknown; try { await handle.setModel(bogus); } catch (caught) { error = caught; } expect(error).toBeInstanceOf(HarnessOperationError); const dto = (error as HarnessOperationError).dto; expect(dto.code).toBe('selection_invalid'); // The DTO echoes the exact requested tuple, unchanged. expect(dto.selection).toEqual(bogus); // No substitution to the first catalog row. expect(dto.selection).not.toEqual({ harnessId: firstRow.harnessId, providerId: firstRow.providerId, modelId: firstRow.modelId, }); // The active selection is untouched by the rejected request. expect((await handle.snapshot()).selection).toEqual(selected); }); it('reports model_unavailable with the unchanged tuple for a known but unavailable model', async () => { const adapter = new FakeHarnessAdapter({ id: 'fake' }); const catalog = await adapter.catalog(CONTEXT); const unavailable = catalog.models.find((entry) => entry.availability === 'unavailable'); const available = catalog.models.find((entry) => entry.availability === 'available'); expect(unavailable).toBeDefined(); expect(available).toBeDefined(); const startingSelection: HarnessSelection = { harnessId: available!.harnessId, providerId: available!.providerId, modelId: available!.modelId, }; const handle = await adapter.create({ context: CONTEXT, conversationId: 'conversation-2', selection: startingSelection, }); const requested: HarnessSelection = { harnessId: unavailable!.harnessId, providerId: unavailable!.providerId, modelId: unavailable!.modelId, }; let error: unknown; try { await handle.setModel(requested); } catch (caught) { error = caught; } expect(error).toBeInstanceOf(HarnessOperationError); const dto = (error as HarnessOperationError).dto; expect(dto.code).toBe('model_unavailable'); expect(dto.selection).toEqual(requested); expect((await handle.snapshot()).selection).toEqual(startingSelection); }); });