mindspace: close authority boundaries
This commit is contained in:
@@ -101,6 +101,462 @@ test('createMindSpaceRemoteServerAdapter exposes conversation package read metho
|
||||
assert.equal(calls[1].init.headers.Authorization, 'Bearer secret-token');
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes the chat save write authority', 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({
|
||||
html: '<html>ready</html>',
|
||||
relativePath: 'public/report.html',
|
||||
changed: true,
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
const input = {
|
||||
userId: 'user-1',
|
||||
sourceContent: 'source',
|
||||
html: '<html>draft</html>',
|
||||
relativePath: 'public/report.html',
|
||||
};
|
||||
|
||||
const result =
|
||||
await adapter.chatSaveService.materializeWorkspaceHtml(input);
|
||||
|
||||
assert.equal(result.changed, true);
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/chatSaveService\/materializeWorkspaceHtml$/,
|
||||
);
|
||||
assert.deepEqual(JSON.parse(calls[0].init.body), {
|
||||
args: [input],
|
||||
});
|
||||
assert.equal(
|
||||
calls[0].init.headers.Authorization,
|
||||
'Bearer secret-token',
|
||||
);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter creates shared HTML through MindSpace', 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({
|
||||
publicUrl:
|
||||
'https://example.com/MindSpace/user-1/public/shared/page.html',
|
||||
filename: 'page.html',
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
const input = {
|
||||
userId: 'user-1',
|
||||
html: '<html>page</html>',
|
||||
sourceFilename: 'page.html',
|
||||
};
|
||||
|
||||
const result =
|
||||
await adapter.chatSaveService.createSharedHtml(input);
|
||||
|
||||
assert.equal(result.filename, 'page.html');
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/chatSaveService\/createSharedHtml$/,
|
||||
);
|
||||
assert.deepEqual(JSON.parse(calls[0].init.body), {
|
||||
args: [input],
|
||||
});
|
||||
|
||||
const workspaceInput = {
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
relativePath: 'oa/notes.txt',
|
||||
body: 'generated notes',
|
||||
};
|
||||
await adapter.conversationArtifactService
|
||||
.registerWorkspaceFileArtifact(
|
||||
workspaceInput,
|
||||
);
|
||||
assert.match(
|
||||
calls[1].url,
|
||||
/conversationArtifactService\/registerWorkspaceFileArtifact$/,
|
||||
);
|
||||
assert.deepEqual(JSON.parse(calls[1].init.body), {
|
||||
args: [workspaceInput],
|
||||
});
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes conversation artifact write authority', 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([
|
||||
{ artifactId: 'artifact-1' },
|
||||
]);
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
const input = {
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
artifactRefs: [
|
||||
{
|
||||
relativePath: 'public/report.html',
|
||||
messageId: 'message-1',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const result =
|
||||
await adapter.conversationArtifactService
|
||||
.registerPublicHtmlArtifacts(input);
|
||||
|
||||
assert.deepEqual(result, [
|
||||
{ artifactId: 'artifact-1' },
|
||||
]);
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/conversationArtifactService\/registerPublicHtmlArtifacts$/,
|
||||
);
|
||||
assert.deepEqual(JSON.parse(calls[0].init.body), {
|
||||
args: [input],
|
||||
});
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes public Finish write authority', 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({
|
||||
materialized: ['public/report.html'],
|
||||
publicHtmlRelativePaths: [
|
||||
'public/report.html',
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
const input = {
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
messages: [],
|
||||
};
|
||||
|
||||
const result =
|
||||
await adapter.publicFinishService
|
||||
.syncAfterFinish(input);
|
||||
|
||||
assert.deepEqual(result.publicHtmlRelativePaths, [
|
||||
'public/report.html',
|
||||
]);
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/publicFinishService\/syncAfterFinish$/,
|
||||
);
|
||||
assert.deepEqual(JSON.parse(calls[0].init.body), {
|
||||
args: [input],
|
||||
});
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes WeChat Page Data delivery authority', 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({
|
||||
outcome: { action: 'send' },
|
||||
deliveryArtifacts: [
|
||||
{
|
||||
relativePath:
|
||||
'public/report.html',
|
||||
url: 'https://example.com/MindSpace/user-1/public/report.html',
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: { log() {}, warn() {}, error() {} },
|
||||
});
|
||||
const input = {
|
||||
userId: 'user-1',
|
||||
reply: {
|
||||
text: 'published',
|
||||
messages: [],
|
||||
},
|
||||
intent: {
|
||||
agentText: 'build a survey',
|
||||
},
|
||||
publicBaseUrl: 'https://example.com',
|
||||
};
|
||||
|
||||
const result =
|
||||
await adapter.publicFinishService
|
||||
.prepareWechatPageDataDelivery(input);
|
||||
|
||||
assert.equal(result.outcome.action, 'send');
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/publicFinishService\/prepareWechatPageDataDelivery$/,
|
||||
);
|
||||
assert.deepEqual(JSON.parse(calls[0].init.body), {
|
||||
args: [input],
|
||||
});
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes WeChat HTML and thumbnail authority', async () => {
|
||||
const calls = [];
|
||||
const adapter =
|
||||
createMindSpaceRemoteServerAdapter({
|
||||
endpoint:
|
||||
'https://mindspace.example.com/',
|
||||
authToken: 'secret-token',
|
||||
fetchFn: async (url, init) => {
|
||||
calls.push({ url, init });
|
||||
const thumbnail =
|
||||
String(url).endsWith(
|
||||
'/ensureWechatFreshPageThumbnails',
|
||||
);
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
async text() {
|
||||
return JSON.stringify(
|
||||
thumbnail
|
||||
? { ok: true }
|
||||
: {
|
||||
confirmedArtifacts: [
|
||||
{
|
||||
relativePath:
|
||||
'public/page.html',
|
||||
url:
|
||||
'https://example.com/MindSpace/user-1/public/page.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: {
|
||||
log() {},
|
||||
warn() {},
|
||||
error() {},
|
||||
},
|
||||
});
|
||||
const prepareInput = {
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
reply: {
|
||||
text: 'done',
|
||||
messages: [],
|
||||
},
|
||||
};
|
||||
const thumbnailInput = {
|
||||
userId: 'user-1',
|
||||
sessionId: 'session-1',
|
||||
artifacts: [
|
||||
{
|
||||
relativePath:
|
||||
'public/page.html',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const prepared =
|
||||
await adapter.publicFinishService
|
||||
.prepareWechatHtmlDelivery(
|
||||
prepareInput,
|
||||
);
|
||||
const thumbnail =
|
||||
await adapter.publicFinishService
|
||||
.ensureWechatFreshPageThumbnails(
|
||||
thumbnailInput,
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
prepared.confirmedArtifacts[0]
|
||||
.relativePath,
|
||||
'public/page.html',
|
||||
);
|
||||
assert.equal(thumbnail.ok, true);
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/publicFinishService\/prepareWechatHtmlDelivery$/,
|
||||
);
|
||||
assert.match(
|
||||
calls[1].url,
|
||||
/publicFinishService\/ensureWechatFreshPageThumbnails$/,
|
||||
);
|
||||
assert.deepEqual(
|
||||
JSON.parse(calls[0].init.body),
|
||||
{ args: [prepareInput] },
|
||||
);
|
||||
assert.deepEqual(
|
||||
JSON.parse(calls[1].init.body),
|
||||
{ args: [thumbnailInput] },
|
||||
);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes logical workspace delivery authority', 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({
|
||||
action: 'deliver',
|
||||
kind: 'html',
|
||||
ownerId: 'user-1',
|
||||
relativePath:
|
||||
'public/report.html',
|
||||
html: '<html></html>',
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: {
|
||||
log() {},
|
||||
warn() {},
|
||||
error() {},
|
||||
},
|
||||
});
|
||||
const input = {
|
||||
requestPath:
|
||||
'/user-1/public/report.html',
|
||||
};
|
||||
|
||||
const result =
|
||||
await adapter
|
||||
.workspacePublicationDeliveryService
|
||||
.resolveWorkspaceRequest(input);
|
||||
|
||||
assert.equal(result.kind, 'html');
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/workspacePublicationDeliveryService\/resolveWorkspaceRequest$/,
|
||||
);
|
||||
assert.deepEqual(
|
||||
JSON.parse(calls[0].init.body),
|
||||
{ args: [input] },
|
||||
);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter exposes binary and long-image workspace tools', 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({
|
||||
relativePath:
|
||||
'public/output.bin',
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
logger: {
|
||||
log() {},
|
||||
warn() {},
|
||||
error() {},
|
||||
},
|
||||
});
|
||||
const binaryInput = {
|
||||
workspaceRef:
|
||||
'mindspace://users/user-1/workspace',
|
||||
sessionId: 'session-1',
|
||||
packageId: 'cp_session-1',
|
||||
path: 'public/report.docx',
|
||||
bodyBase64:
|
||||
Buffer.from('PK').toString('base64'),
|
||||
};
|
||||
const imageInput = {
|
||||
workspaceRef:
|
||||
'mindspace://users/user-1/workspace',
|
||||
sessionId: 'session-1',
|
||||
packageId: 'cp_session-1',
|
||||
htmlPath: 'public/report.html',
|
||||
};
|
||||
|
||||
await adapter.workspaceToolService
|
||||
.writeBinaryFile(binaryInput);
|
||||
await adapter.workspaceToolService
|
||||
.generateLongImage(imageInput);
|
||||
|
||||
assert.match(
|
||||
calls[0].url,
|
||||
/workspaceToolService\/writeBinaryFile$/,
|
||||
);
|
||||
assert.match(
|
||||
calls[1].url,
|
||||
/workspaceToolService\/generateLongImage$/,
|
||||
);
|
||||
assert.deepEqual(
|
||||
JSON.parse(calls[0].init.body),
|
||||
{ args: [binaryInput] },
|
||||
);
|
||||
assert.deepEqual(
|
||||
JSON.parse(calls[1].init.body),
|
||||
{ args: [imageInput] },
|
||||
);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter rejects unknown binding methods', () => {
|
||||
const adapter = createMindSpaceRemoteServerAdapter({
|
||||
endpoint: 'https://mindspace.example.com',
|
||||
@@ -109,6 +565,10 @@ test('createMindSpaceRemoteServerAdapter rejects unknown binding methods', () =>
|
||||
});
|
||||
|
||||
assert.throws(() => adapter.assetService.notARealMethod, /does not expose/);
|
||||
assert.throws(
|
||||
() => adapter.conversationPackageRegistry.recordArtifact,
|
||||
/does not expose/,
|
||||
);
|
||||
});
|
||||
|
||||
test('createMindSpaceRemoteServerAdapter surfaces remote conversation package errors with binding context', async () => {
|
||||
|
||||
Reference in New Issue
Block a user