feat: finalize mindspace service extraction phase a
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
createMindSpaceRemoteServerAdapter,
|
||||
mindspaceRemoteServerAdapterInternals,
|
||||
} from './mindspace-remote-server-adapter.mjs';
|
||||
|
||||
test('buildRemoteOperationUrl normalizes endpoint and encodes operation path', () => {
|
||||
assert.equal(
|
||||
mindspaceRemoteServerAdapterInternals.buildRemoteOperationUrl(
|
||||
'https://mindspace.example.com/',
|
||||
'assetService',
|
||||
'renderAssetPreview',
|
||||
'/internal/mindspace-adapter',
|
||||
),
|
||||
'https://mindspace.example.com/internal/mindspace-adapter/assetService/renderAssetPreview',
|
||||
);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter validates endpoint at startup', () => {
|
||||
const adapter = createMindSpaceRemoteServerAdapter({
|
||||
fetchFn: async () => {
|
||||
throw new Error('should not fetch');
|
||||
},
|
||||
});
|
||||
assert.throws(() => adapter.assertReady(), /MINDSPACE_REMOTE_BASE_URL/);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter proxies server binding methods through fetch transport', async () => {
|
||||
const calls = [];
|
||||
const adapter = createMindSpaceRemoteServerAdapter({
|
||||
endpoint: 'https://mindspace.example.com/',
|
||||
authToken: 'secret-token',
|
||||
operationBasePath: '/internal/mindspace-adapter/',
|
||||
timeoutMs: 3000,
|
||||
fetchFn: async (url, init) => {
|
||||
calls.push({ url, init });
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
async text() {
|
||||
return JSON.stringify({ ok: true, source: 'remote' });
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
|
||||
const result = await adapter.assetService.renderAssetPreview({ userId: 'u1', assetId: 'a1' });
|
||||
|
||||
assert.deepEqual(result, { ok: true, source: 'remote' });
|
||||
assert.equal(calls.length, 1);
|
||||
assert.equal(
|
||||
calls[0].url,
|
||||
'https://mindspace.example.com/internal/mindspace-adapter/assetService/renderAssetPreview',
|
||||
);
|
||||
assert.equal(calls[0].init.method, 'POST');
|
||||
assert.equal(calls[0].init.headers.Authorization, 'Bearer secret-token');
|
||||
assert.deepEqual(JSON.parse(calls[0].init.body), {
|
||||
args: [{ userId: 'u1', assetId: 'a1' }],
|
||||
});
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes conversation package read methods', async () => {
|
||||
const calls = [];
|
||||
const adapter = createMindSpaceRemoteServerAdapter({
|
||||
endpoint: 'https://mindspace.example.com/',
|
||||
authToken: 'secret-token',
|
||||
fetchFn: async (url, init) => {
|
||||
calls.push({ url, init });
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
async text() {
|
||||
return JSON.stringify({ packageId: 'cp-session-1' });
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
|
||||
await adapter.conversationPackageRegistry.readManifestForSession({
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
});
|
||||
await adapter.conversationPackageRegistry.readArtifactObject({
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
artifactId: 'artifact-1',
|
||||
});
|
||||
|
||||
assert.match(calls[0].url, /conversationPackageRegistry\/readManifestForSession$/);
|
||||
assert.match(calls[1].url, /conversationPackageRegistry\/readArtifactObject$/);
|
||||
assert.deepEqual(JSON.parse(calls[0].init.body), {
|
||||
args: [{ userId: 'user-1', sessionId: 'session-1' }],
|
||||
});
|
||||
assert.deepEqual(JSON.parse(calls[1].init.body), {
|
||||
args: [{ userId: 'user-1', sessionId: 'session-1', artifactId: 'artifact-1' }],
|
||||
});
|
||||
assert.equal(calls[0].init.headers.Authorization, 'Bearer secret-token');
|
||||
assert.equal(calls[1].init.headers.Authorization, 'Bearer secret-token');
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter rejects unknown binding methods', () => {
|
||||
const adapter = createMindSpaceRemoteServerAdapter({
|
||||
endpoint: 'https://mindspace.example.com',
|
||||
fetchFn: async () => ({ ok: true, status: 204, text: async () => '' }),
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
|
||||
assert.throws(() => adapter.assetService.notARealMethod, /does not expose/);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter surfaces remote conversation package errors with binding context', async () => {
|
||||
const adapter = createMindSpaceRemoteServerAdapter({
|
||||
endpoint: 'https://mindspace.example.com/',
|
||||
authToken: 'secret-token',
|
||||
fetchFn: async () => ({
|
||||
ok: false,
|
||||
status: 502,
|
||||
async text() {
|
||||
return 'upstream manifest missing';
|
||||
},
|
||||
}),
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
() => adapter.conversationPackageRegistry.readManifestForSession({
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
}),
|
||||
/conversationPackageRegistry\.readManifestForSession\(\) failed with 502: upstream manifest missing/,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user