import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import { createLocalMindSpaceStorageAdapter, normalizeMindSpaceStorageKey, resolveStoragePath, } from './mindspace-storage-adapter.mjs'; test('normalizeMindSpaceStorageKey rejects absolute paths and traversal', () => { assert.equal(normalizeMindSpaceStorageKey('users/u1/file.txt'), 'users/u1/file.txt'); assert.equal(normalizeMindSpaceStorageKey('users/u1/./file.txt'), 'users/u1/file.txt'); for (const key of ['/tmp/file.txt', '../file.txt', 'users/../file.txt', 'C:/tmp/file.txt', 'a\\b']) { assert.throws( () => normalizeMindSpaceStorageKey(key), (error) => error.code === 'invalid_storage_key', ); } }); test('resolveStoragePath keeps object keys inside storage root', async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-storage-root-')); const target = resolveStoragePath(root, 'users/u1/file.txt'); assert.equal(target, path.join(root, 'users', 'u1', 'file.txt')); assert.throws( () => resolveStoragePath(root, '../outside.txt'), (error) => error.code === 'invalid_storage_key', ); }); test('local storage adapter writes, reads, stats, lists, copies, and deletes objects', async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-storage-adapter-')); const adapter = createLocalMindSpaceStorageAdapter(root); const writeResult = await adapter.putObject('users/u1/conversations/s1/public/report.html', '

Hi

'); assert.equal(writeResult.key, 'users/u1/conversations/s1/public/report.html'); assert.equal(writeResult.sizeBytes, Buffer.byteLength('

Hi

')); const body = await adapter.getObject('users/u1/conversations/s1/public/report.html'); assert.equal(body.toString('utf8'), '

Hi

'); const stat = await adapter.statObject('users/u1/conversations/s1/public/report.html'); assert.equal(stat.exists, true); assert.equal(stat.isDirectory, false); await adapter.copyObject( 'users/u1/conversations/s1/public/report.html', 'users/u1/conversations/s1/generated/report-copy.html', ); assert.deepEqual( (await adapter.listObjects('users/u1/conversations/s1')).map((item) => item.key), [ 'users/u1/conversations/s1/generated/report-copy.html', 'users/u1/conversations/s1/public/report.html', ], ); await adapter.deleteObject('users/u1/conversations/s1/public/report.html'); assert.equal((await adapter.statObject('users/u1/conversations/s1/public/report.html')).exists, false); }); test('local storage adapter rejects signed URLs explicitly', async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-storage-adapter-')); const adapter = createLocalMindSpaceStorageAdapter(root); await assert.rejects( () => adapter.getSignedUrl('users/u1/file.txt'), (error) => error.code === 'signed_url_not_supported', ); });