Record uploaded assets in conversation packages
This commit is contained in:
+100
-1
@@ -4,7 +4,7 @@ import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import test from 'node:test';
|
||||
import sharp from 'sharp';
|
||||
import { createAssetService, validateUploadRequest } from './mindspace-assets.mjs';
|
||||
import { assetInternals, createAssetService, validateUploadRequest } from './mindspace-assets.mjs';
|
||||
import { DEFAULT_MAX_FILE_BYTES } from './mindspace.mjs';
|
||||
|
||||
function createMockPool(state) {
|
||||
@@ -40,6 +40,8 @@ function createMockPool(state) {
|
||||
temporary_storage_key: params[8],
|
||||
status: 'reserved',
|
||||
expires_at: params[9],
|
||||
source_session_id: params[11] ?? null,
|
||||
source_message_id: params[12] ?? null,
|
||||
});
|
||||
return [[]];
|
||||
}
|
||||
@@ -242,6 +244,103 @@ test('completeUpload marks safe files ready and blocks script payloads', async (
|
||||
assert.equal(asset.scanStatus, 'blocked');
|
||||
});
|
||||
|
||||
test('createUpload stores optional source session metadata', async () => {
|
||||
const storageRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-assets-'));
|
||||
const state = {
|
||||
categories: [{ id: 'cat-1', user_id: 'user-1', space_id: 'space-1', category_code: 'oa' }],
|
||||
spaces: [
|
||||
{
|
||||
id: 'space-1',
|
||||
user_id: 'user-1',
|
||||
quota_bytes: 5 * 1024 * 1024,
|
||||
used_bytes: 0,
|
||||
reserved_bytes: 0,
|
||||
status: 'active',
|
||||
},
|
||||
],
|
||||
uploads: [],
|
||||
assets: [],
|
||||
versions: [],
|
||||
};
|
||||
const service = createAssetService(createMockPool(state), {
|
||||
storageRoot,
|
||||
idFactory: () => 'upload-1',
|
||||
});
|
||||
|
||||
await service.createUpload('user-1', {
|
||||
categoryId: 'cat-1',
|
||||
filename: 'note.txt',
|
||||
sizeBytes: 12,
|
||||
sourceSessionId: 'session-1',
|
||||
sourceMessageId: 'message-1',
|
||||
});
|
||||
|
||||
assert.equal(state.uploads[0].source_session_id, 'session-1');
|
||||
assert.equal(state.uploads[0].source_message_id, 'message-1');
|
||||
});
|
||||
|
||||
test('registerUploadArtifactForConversation records uploaded input artifacts', async () => {
|
||||
const calls = [];
|
||||
const registry = {
|
||||
async ensurePackage(input) {
|
||||
calls.push(['ensurePackage', input]);
|
||||
return { id: 'cp_session-1' };
|
||||
},
|
||||
async recordArtifact(input) {
|
||||
calls.push(['recordArtifact', input]);
|
||||
return input;
|
||||
},
|
||||
async writeManifestForSession(input) {
|
||||
calls.push(['writeManifestForSession', input]);
|
||||
return { storageKey: 'users/user-1/conversations/session-1/manifest.json' };
|
||||
},
|
||||
};
|
||||
|
||||
const result = await assetInternals.registerUploadArtifactForConversation({
|
||||
registry,
|
||||
userId: 'user-1',
|
||||
upload: {
|
||||
filename: 'cover.png',
|
||||
source_session_id: 'session-1',
|
||||
source_message_id: 'message-1',
|
||||
},
|
||||
asset: {
|
||||
displayName: 'cover.png',
|
||||
filename: 'cover.png',
|
||||
mimeType: 'image/png',
|
||||
sizeBytes: 123,
|
||||
publicUrl: 'https://m.tkmind.cn/MindSpace/user-1/images/cover.png',
|
||||
},
|
||||
assetId: 'asset-1',
|
||||
storageKey: 'users/user-1/images/2026-07-02/cover.png',
|
||||
canonicalUrl: 'https://m.tkmind.cn/MindSpace/user-1/images/cover.png',
|
||||
now: 1000,
|
||||
});
|
||||
|
||||
assert.equal(result.artifactKind, 'input_image');
|
||||
assert.equal(result.role, 'user');
|
||||
assert.equal(result.messageId, 'message-1');
|
||||
assert.equal(result.canonicalUrl, 'https://m.tkmind.cn/MindSpace/user-1/images/cover.png');
|
||||
assert.deepEqual(calls[2], [
|
||||
'writeManifestForSession',
|
||||
{ userId: 'user-1', sessionId: 'session-1' },
|
||||
]);
|
||||
});
|
||||
|
||||
test('registerUploadArtifactForConversation skips uploads without source session', async () => {
|
||||
assert.equal(
|
||||
await assetInternals.registerUploadArtifactForConversation({
|
||||
registry: { ensurePackage: async () => assert.fail('should not be called') },
|
||||
userId: 'user-1',
|
||||
upload: { filename: 'note.txt' },
|
||||
asset: { mimeType: 'text/plain' },
|
||||
assetId: 'asset-1',
|
||||
now: 1000,
|
||||
}),
|
||||
null,
|
||||
);
|
||||
});
|
||||
|
||||
test('completeUpload publishes public images to the public temp image library', async () => {
|
||||
const storageRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-assets-'));
|
||||
const h5Root = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-h5-'));
|
||||
|
||||
Reference in New Issue
Block a user