Files
makelore/tests/unit/coding-plugins-client.test.ts

102 lines
3.5 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import {
configureDataService,
getCodingPlugins,
parseCodingPluginProject,
setCodingPluginEnabled,
} from '@/lib/coding-plugins';
const PROJECT_ID = 'local-project';
function projection() {
return {
schemaVersion: 1,
project: { localProjectId: PROJECT_ID, durableProjectId: null },
policyStatus: 'current',
unknownPluginIds: [],
items: [{
id: 'makelore.data-service',
version: '1.0.0',
contractVersion: 1,
requiresBackend: true,
displayName: '开发数据服务',
description: '项目数据',
enabled: false,
state: 'disabled',
backend: { status: 'unconfigured' },
skills: [{ id: 'data-service', assignedAgentIds: [] }],
capabilities: [{
id: 'data-service.control',
operations: [{
id: 'inspect',
billing: { mode: 'included', availability: 'available', notice: 'Fixed quotas apply' },
tool: {
name: 'data_service_inspect', label: 'Inspect', description: 'Inspect data',
mutation: 'read', permissions: ['project.data.read'],
},
}],
}],
settingsSurface: 'data-service',
}],
};
}
describe('coding plugins Renderer client', () => {
it('strictly parses the bounded Main projection', () => {
expect(parseCodingPluginProject(projection())).toEqual(projection());
expect(() => parseCodingPluginProject({ ...projection(), owner: 'secret' })).toThrow();
expect(() => parseCodingPluginProject({ ...projection(), items: [{ ...projection().items[0], state: 'installed' }] })).toThrow();
});
it('uses the local project handle exactly once and enable does not configure', async () => {
const fetcher = vi.fn()
.mockResolvedValueOnce(projection())
.mockResolvedValueOnce({ ...projection(), items: [{ ...projection().items[0], enabled: true, state: 'configuration_required' }] });
await getCodingPlugins(PROJECT_ID, fetcher);
await setCodingPluginEnabled(PROJECT_ID, 'makelore.data-service', true, fetcher);
expect(fetcher).toHaveBeenNthCalledWith(1, '/api/coding/plugins?projectId=local-project');
expect(fetcher).toHaveBeenNthCalledWith(2, '/api/coding/plugins/makelore.data-service', {
method: 'PUT',
body: JSON.stringify({ projectId: PROJECT_ID, enabled: true }),
});
expect(fetcher.mock.calls.flat().join(' ')).not.toContain('/api/works/data-service/project');
});
it('configures Data Service only through its existing typed route', async () => {
const response = {
success: true,
status: 200,
code: null,
error: null,
retryable: false,
data: {
instance_id: 'instance-1',
project_id: '11111111-1111-4111-8111-111111111111',
collections: [],
usage: { document_count: 0, total_bytes: 0 },
limits: {
max_collections: 20,
max_documents: 1000,
max_total_bytes: 20971520,
max_document_bytes: 65536,
list_default_limit: 50,
list_max_limit: 100,
list_max_data_bytes: 1048576,
mutations_per_minute: 120,
},
created_at: '2026-08-27T00:00:00Z',
updated_at: '2026-08-27T00:00:00Z',
},
};
const fetcher = vi.fn().mockResolvedValue(response);
await expect(configureDataService(['todos'], fetcher)).resolves.toEqual(response);
expect(fetcher).toHaveBeenCalledWith('/api/works/data-service/project', {
method: 'PUT',
body: JSON.stringify({ collections: ['todos'] }),
});
});
});