fix(coding): remediate ML-07 plugin authority
This commit is contained in:
@@ -97,6 +97,13 @@ describe('coding plugin bounded product service', () => {
|
||||
operations: [{
|
||||
id: 'get_document',
|
||||
billing: { mode: 'included', availability: 'available', notice: 'Included quota' },
|
||||
tool: {
|
||||
name: 'data_service_get_document',
|
||||
label: 'Data Service get document',
|
||||
description: 'Read a document from the active project.',
|
||||
mutation: 'read',
|
||||
permissions: ['project.data.read'],
|
||||
},
|
||||
}],
|
||||
}],
|
||||
settingsSurface: 'data-service',
|
||||
@@ -105,6 +112,69 @@ describe('coding plugin bounded product service', () => {
|
||||
expect(JSON.stringify(result)).not.toMatch(/secret upstream body|projectPath|entitlement_scope/u);
|
||||
});
|
||||
|
||||
it('projects the exact three capabilities and fourteen mixed-policy operations', async () => {
|
||||
const root = await mkdtemp(path.join(tmpdir(), 'makelore-plugin-policy-join-'));
|
||||
roots.push(root);
|
||||
await createCodingProjectMetadata(root, { now: '2026-08-27T00:00:00.000Z' });
|
||||
const projectPlugins = createProjectPluginService();
|
||||
await projectPlugins.enable(root, DATA_SERVICE_PLUGIN_DEFINITION.id);
|
||||
const capabilities = ['data-service.control', 'data-service.documents', 'data-service.preview'].map((capabilityId) => ({
|
||||
capability_id: capabilityId,
|
||||
operations: DATA_SERVICE_PLUGIN_DEFINITION.operations
|
||||
.filter((operation) => operation.capabilityId === capabilityId)
|
||||
.map(({ operation }, index) => ({
|
||||
operation,
|
||||
billing: capabilityId === 'data-service.documents'
|
||||
? { mode: 'external_account' as const, notice: 'Provider billed' }
|
||||
: index === 0 && capabilityId === 'data-service.control'
|
||||
? {
|
||||
mode: 'platform_metered' as const,
|
||||
status: 'billing_unavailable' as const,
|
||||
entitlement_scope: capabilityId,
|
||||
notice: 'Pricing unavailable',
|
||||
}
|
||||
: { mode: 'included' as const, entitlement_scope: null, notice: 'Included quota' },
|
||||
})),
|
||||
}));
|
||||
const service = createCodingProjectPluginService({
|
||||
projects: { getProject: vi.fn().mockResolvedValue({ id: 'local-a', path: root }) },
|
||||
projectPlugins,
|
||||
policyClient: {
|
||||
refresh: vi.fn(),
|
||||
getState: () => ({
|
||||
status: 'current' as const, revision: 1, lastVerifiedAt: 1,
|
||||
catalog: {
|
||||
schema_version: 1 as const, catalog_version: 'catalog-a', pricing_version: null,
|
||||
plugins: [{
|
||||
plugin_id: DATA_SERVICE_PLUGIN_DEFINITION.id,
|
||||
supported_contract_versions: [1], status: 'active' as const, capabilities,
|
||||
}],
|
||||
},
|
||||
}),
|
||||
},
|
||||
adapters: [{
|
||||
pluginId: DATA_SERVICE_PLUGIN_DEFINITION.id,
|
||||
inspect: vi.fn().mockResolvedValue({ status: 'ready' }), invoke: vi.fn(),
|
||||
}],
|
||||
definitions: [DATA_SERVICE_PLUGIN_DEFINITION],
|
||||
});
|
||||
|
||||
const item = (await service.list('local-a')).items[0];
|
||||
expect(item?.capabilities.map(({ id }) => id)).toEqual([
|
||||
'data-service.control', 'data-service.documents', 'data-service.preview',
|
||||
]);
|
||||
expect(item?.capabilities.flatMap(({ operations }) => operations)).toHaveLength(14);
|
||||
expect(item?.capabilities.find(({ id }) => id === 'data-service.preview')?.operations)
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ id: 'get', tool: null, billing: expect.objectContaining({ mode: 'included' }) }),
|
||||
expect.objectContaining({ id: 'delete', tool: null }),
|
||||
]));
|
||||
expect(item?.capabilities.find(({ id }) => id === 'data-service.documents')?.operations[0]?.billing)
|
||||
.toMatchObject({ mode: 'external_account', availability: 'available' });
|
||||
expect(item?.capabilities.find(({ id }) => id === 'data-service.control')?.operations[0]?.billing)
|
||||
.toMatchObject({ mode: 'platform_metered', availability: 'unavailable' });
|
||||
});
|
||||
|
||||
it('deactivates only the requested adapter and isolates cleanup failures', async () => {
|
||||
const firstDeactivate = vi.fn().mockRejectedValue(new Error('cleanup failed'));
|
||||
const secondDeactivate = vi.fn().mockResolvedValue(undefined);
|
||||
|
||||
Reference in New Issue
Block a user