40 lines
1.6 KiB
JavaScript
40 lines
1.6 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
import { join } from 'node:path';
|
|
import { tmpdir } from 'node:os';
|
|
import test from 'node:test';
|
|
import { UploadStore } from '../src/upload-store.mjs';
|
|
|
|
test('stores uploads only in the bind directory and persists replay state', async (t) => {
|
|
const root = await mkdtemp(join(tmpdir(), 'image-upload-store-'));
|
|
t.after(() => rm(root, { recursive: true, force: true }));
|
|
const config = { uploadRoot: join(root, 'uploads'), uploadStatePath: join(root, 'upload-state.json') };
|
|
const body = Buffer.from('immutable image bytes');
|
|
const filename = `${'a'.repeat(32)}.png`;
|
|
const store = new UploadStore(config);
|
|
await store.initialize();
|
|
const first = await store.store({ requestKey: 'core2026:request-1', client: 'core2026', filename, body });
|
|
assert.deepEqual(first, { duplicate: false, path: `icons/users/core2026/${filename}` });
|
|
assert.equal(await readFile(join(root, 'uploads', 'core2026', filename), 'utf8'), 'immutable image bytes');
|
|
|
|
const restarted = new UploadStore(config);
|
|
await restarted.initialize();
|
|
assert.deepEqual(
|
|
await restarted.store({ requestKey: 'core2026:request-1', client: 'core2026', filename, body }),
|
|
{ duplicate: true, path: `icons/users/core2026/${filename}` },
|
|
);
|
|
await assert.rejects(
|
|
restarted.store({
|
|
requestKey: 'core2026:request-1',
|
|
client: 'core2026',
|
|
filename: `${'b'.repeat(32)}.png`,
|
|
body,
|
|
}),
|
|
/already used/,
|
|
);
|
|
await assert.rejects(
|
|
restarted.store({ requestKey: 'core2026:request-2', client: '../escape', filename, body }),
|
|
/Invalid upload path/,
|
|
);
|
|
});
|