// @vitest-environment node import { describe, expect, it, vi } from 'vitest'; import { DATA_SERVICE_TOOL_DEFINITIONS } from '../../shared/coding-plugins'; import type { DataServiceOperations } from '../../electron/services/data-service-client'; import { createDataServicePluginAdapter, } from '../../electron/coding-plugins/adapters/data-service'; const context = { conversationId: 'conversation-a', runId: 'run-a', resourceId: 'resource-a', requestId: 'pi:run-a:resource-a', localProjectId: 'local-project-a', projectPath: 'C:\\projects\\demo', durableProjectId: 'durable-project-a', workerRole: 'parent' as const, effectiveSkillIds: ['data-service'], }; function success(data: T) { return { success: true as const, status: 200, code: null, error: null, retryable: false as const, data, }; } function operations(): DataServiceOperations { return { configure: vi.fn().mockResolvedValue(success({ configured: true })), inspect: vi.fn().mockResolvedValue(success({ instance_id: 'instance-a' })), listProjects: vi.fn().mockResolvedValue(success({ items: [], total: 0, instance_limit: 20 })), getDocument: vi.fn().mockResolvedValue(success({ id: 'one', data: {}, revision: 1 })), listDocuments: vi.fn().mockResolvedValue(success({ items: [], next_cursor: null, limit: 50 })), putDocument: vi.fn().mockResolvedValue(success({ id: 'one', data: {}, revision: 1 })), deleteDocument: vi.fn().mockResolvedValue(success(null)), removeCollection: vi.fn().mockResolvedValue(success({ removed: true, usage: { document_count: 0, total_bytes: 0 } })), reset: vi.fn().mockResolvedValue(success({ instance_id: 'instance-a' })), removeProject: vi.fn().mockResolvedValue(success({ removed: true })), }; } describe('Data Service plugin adapter', () => { it('validates the parsed tool supplied by the capability registry', async () => { const dataService = operations(); const adapter = createDataServicePluginAdapter(dataService); const inspect = DATA_SERVICE_TOOL_DEFINITIONS.find(({ name }) => name === 'data_service_inspect'); if (!inspect) throw new Error('inspect definition missing'); const result = await adapter.invoke(context, { ...inspect, inputSchema: { type: 'object', additionalProperties: false, required: ['registry_token'], properties: { registry_token: { type: 'string', minLength: 1 } }, }, }, {}); expect(result).toMatchObject({ success: false, status: 422, code: 'plugin_input_invalid', data: null, }); expect(dataService.inspect).not.toHaveBeenCalled(); }); it('maps all ten package operations through DataServiceOperations', async () => { const dataService = operations(); const adapter = createDataServicePluginAdapter(dataService); const inputs: Record = { data_service_configure: { collections: ['todos'] }, data_service_inspect: {}, data_service_list_projects: {}, data_service_get_document: { collection: 'todos', document_id: 'one' }, data_service_list_documents: { collection: 'todos', limit: 50, cursor: 'cursor-a' }, data_service_put_document: { collection: 'todos', document_id: 'one', data: { done: false }, if_revision: 1 }, data_service_delete_document: { collection: 'todos', document_id: 'one', if_revision: 1, confirmed: true }, data_service_remove_collection: { collection: 'todos', confirmed: true }, data_service_reset: { confirmed: true }, data_service_remove_project: { confirmed: true }, }; for (const tool of DATA_SERVICE_TOOL_DEFINITIONS) { const result = await adapter.invoke(context, tool, inputs[tool.name]); expect(result).toMatchObject({ success: true, payload_schema: 'data-service.v1' }); expect(result).not.toHaveProperty('plugin_id'); expect(result).not.toHaveProperty('request_id'); } expect(dataService.configure).toHaveBeenCalledWith({ collections: ['todos'] }, context.projectPath); expect(dataService.inspect).toHaveBeenCalledWith(context.projectPath); expect(dataService.listProjects).toHaveBeenCalledWith(); expect(dataService.getDocument).toHaveBeenCalledWith({ collection: 'todos', document_id: 'one' }, context.projectPath); expect(dataService.listDocuments).toHaveBeenCalledWith({ collection: 'todos', limit: 50, cursor: 'cursor-a' }, context.projectPath); expect(dataService.putDocument).toHaveBeenCalledWith({ collection: 'todos', document_id: 'one', data: { done: false }, if_revision: 1, }, context.projectPath); expect(dataService.deleteDocument).toHaveBeenCalledWith({ collection: 'todos', document_id: 'one', if_revision: 1, confirmed: true, }, context.projectPath); }); it('returns bounded domain context and rejects forbidden or malformed input', async () => { const dataService = operations(); const adapter = createDataServicePluginAdapter(dataService); const put = DATA_SERVICE_TOOL_DEFINITIONS.find(({ name }) => name === 'data_service_put_document'); if (!put) throw new Error('put definition missing'); const invalid = await adapter.invoke(context, put, { collection: 'todos', document_id: 'one', data: {}, projectPath: context.projectPath, }); expect(invalid).toMatchObject({ success: false, status: 422, code: 'plugin_input_invalid', data: null, }); const result = await adapter.invoke(context, put, { collection: 'todos', document_id: 'one', data: {} }); expect(result).toMatchObject({ success: true, payload_schema: 'data-service.v1' }); expect(dataService.putDocument).toHaveBeenCalledTimes(1); }); });