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/, ); });