Files
memind/mindspace-conversation-package.test.mjs
T
2026-07-03 00:34:03 +08:00

230 lines
6.6 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
assertConversationArtifactKind,
buildConversationDisplayFolderName,
buildConversationPackageManifest,
buildConversationPackageUri,
buildConversationStoragePrefix,
createConversationArtifact,
createConversationPackageRecord,
} from './mindspace-conversation-package.mjs';
test('buildConversationStoragePrefix produces backend-neutral object prefixes', () => {
assert.equal(
buildConversationStoragePrefix({ userId: 'user-1', sessionId: 'session-1' }),
'users/user-1/conversations/session-1',
);
assert.equal(
buildConversationPackageUri({ userId: 'user 1', sessionId: 'session:1' }),
'mindspace://users/user%201/conversations/session%3A1',
);
});
test('buildConversationStoragePrefix rejects path separators', () => {
assert.throws(
() => buildConversationStoragePrefix({ userId: '../user', sessionId: 'session-1' }),
(error) => error.code === 'invalid_storage_segment',
);
assert.throws(
() => buildConversationStoragePrefix({ userId: 'user-1', sessionId: 'a/b' }),
(error) => error.code === 'invalid_storage_segment',
);
});
test('createConversationPackageRecord defaults storage prefix and timestamps', () => {
assert.deepEqual(
createConversationPackageRecord({
id: 'cp_custom',
userId: 'user-1',
sessionId: 'session-1',
title: '旅行页面',
now: 1000,
}),
{
id: 'cp_custom',
userId: 'user-1',
sessionId: 'session-1',
title: '旅行页面',
status: 'active',
storagePrefix: 'users/user-1/conversations/session-1',
manifestAssetId: null,
createdAt: 1000,
updatedAt: 1000,
},
);
});
test('buildConversationDisplayFolderName prefers title and hides internal ids', () => {
assert.equal(buildConversationDisplayFolderName('旅行计划'), '旅行计划');
assert.equal(buildConversationDisplayFolderName(' '), '本次对话文件夹');
});
test('createConversationArtifact validates artifact kind and preserves provenance', () => {
assert.equal(assertConversationArtifactKind('public_html'), 'public_html');
assert.throws(
() => assertConversationArtifactKind('random_blob'),
(error) => error.code === 'unsupported_conversation_artifact_kind',
);
const artifact = createConversationArtifact({
id: 'ca_1',
packageId: 'cp_1',
artifactKind: 'public_html',
assetId: 'asset-1',
pageId: 'page-1',
publicationId: 'pub-1',
agentRunId: 'run-1',
messageId: 'msg-1',
displayName: 'report.html',
mimeType: 'text/html',
sizeBytes: 120,
storageKey: 'users/user-1/conversations/session-1/public/report.html',
canonicalUrl: 'https://m.tkmind.cn/MindSpace/user-1/public/report.html',
sortOrder: 2,
now: 2000,
});
assert.equal(artifact.packageId, 'cp_1');
assert.equal(artifact.artifactKind, 'public_html');
assert.equal(artifact.assetId, 'asset-1');
assert.equal(artifact.pageId, 'page-1');
assert.equal(artifact.publicationId, 'pub-1');
assert.equal(artifact.messageId, 'msg-1');
});
test('createConversationArtifact preserves unknown size as null', () => {
const artifact = createConversationArtifact({
packageId: 'cp_1',
artifactKind: 'generated_file',
sizeBytes: null,
now: 1000,
});
assert.equal(artifact.sizeBytes, null);
});
test('createConversationArtifact keeps sort order inside MySQL INT range', () => {
const artifact = createConversationArtifact({
packageId: 'cp_1',
artifactKind: 'public_html',
sortOrder: 1783003000123,
now: 1000,
});
assert.equal(artifact.sortOrder, 1783003000);
const clamped = createConversationArtifact({
packageId: 'cp_1',
artifactKind: 'public_html',
sortOrder: Number.MAX_SAFE_INTEGER,
now: 1000,
});
assert.equal(clamped.sortOrder, 2147483647);
});
test('buildConversationPackageManifest sorts artifacts and emits stable public shape', () => {
const manifest = buildConversationPackageManifest({
packageRecord: {
id: 'cp_1',
userId: 'user-1',
sessionId: 'session-1',
title: '项目周报',
now: 1000,
},
artifacts: [
{
id: 'ca_late',
artifactKind: 'page',
displayName: '项目周报',
pageId: 'page-1',
messageId: 'msg-2',
agentRunId: 'run-1',
sortOrder: 2,
createdAt: 3000,
},
{
id: 'ca_first',
artifactKind: 'input_image',
displayName: 'cover.png',
messageId: 'msg-1',
sortOrder: 1,
createdAt: 2000,
},
{
id: 'ca_public',
artifactKind: 'public_html',
displayName: 'report.html',
pageId: 'page-1',
publicationId: 'pub-1',
messageId: 'msg-2',
agentRunId: 'run-1',
canonicalUrl: 'https://m.tkmind.cn/MindSpace/user-1/public/report.html',
sortOrder: 3,
createdAt: 4000,
},
],
});
assert.equal(manifest.schemaVersion, 1);
assert.equal(manifest.uri, 'mindspace://users/user-1/conversations/session-1');
assert.equal(manifest.displayFolderName, '项目周报');
assert.equal(manifest.storagePrefix, 'users/user-1/conversations/session-1');
assert.deepEqual(
manifest.artifacts.map((artifact) => artifact.artifactId),
['ca_first', 'ca_late', 'ca_public'],
);
assert.deepEqual(manifest.artifacts[0], {
artifactId: 'ca_first',
kind: 'input_image',
messageId: 'msg-1',
displayName: 'cover.png',
sortOrder: 1,
createdAt: 2000,
});
assert.deepEqual(manifest.pages, [
{
pageId: 'page-1',
artifactIds: ['ca_late', 'ca_public'],
displayName: '项目周报',
canonicalUrl: 'https://m.tkmind.cn/MindSpace/user-1/public/report.html',
createdAt: 3000,
updatedAt: 4000,
},
]);
assert.deepEqual(manifest.publications, [
{
publicationId: 'pub-1',
artifactIds: ['ca_public'],
displayName: 'report.html',
canonicalUrl: 'https://m.tkmind.cn/MindSpace/user-1/public/report.html',
createdAt: 4000,
updatedAt: 4000,
},
]);
assert.deepEqual(manifest.messages, [
{
messageId: 'msg-1',
artifactIds: ['ca_first'],
kinds: ['input_image'],
createdAt: 2000,
updatedAt: 2000,
},
{
messageId: 'msg-2',
artifactIds: ['ca_late', 'ca_public'],
kinds: ['page', 'public_html'],
createdAt: 3000,
updatedAt: 4000,
},
]);
assert.deepEqual(manifest.agentRuns, [
{
agentRunId: 'run-1',
artifactIds: ['ca_late', 'ca_public'],
kinds: ['page', 'public_html'],
createdAt: 3000,
updatedAt: 4000,
},
]);
});