39948-vm/backend/tests/file-service.test.ts
2026-07-02 14:22:33 +02:00

58 lines
1.8 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
createErrorResponse,
generatePresignedUrls,
isValidPath,
} from '../src/services/file.ts';
void test('isValidPath allows relative storage keys and rejects traversal or protocol inputs', () => {
assert.equal(isValidPath('projects/demo/image.jpg'), true);
assert.equal(isValidPath('nested/folder/video.mp4'), true);
assert.equal(isValidPath('../secret.txt'), false);
assert.equal(isValidPath('folder/../../secret.txt'), false);
assert.equal(isValidPath('https://example.test/file.jpg'), false);
assert.equal(isValidPath('s3://bucket/file.jpg'), false);
assert.equal(isValidPath('folder//file.jpg'), false);
assert.equal(isValidPath('folder/\0/file.jpg'), false);
assert.equal(isValidPath(' '), false);
assert.equal(isValidPath(null), false);
});
void test('createErrorResponse returns a stable structured error payload', () => {
assert.deepEqual(
createErrorResponse('Invalid file paths detected', 'INVALID_PATH', {
invalidPaths: ['../secret.txt'],
}),
{
message: 'Invalid file paths detected',
code: 'INVALID_PATH',
details: {
invalidPaths: ['../secret.txt'],
},
},
);
});
void test('generatePresignedUrls returns backend download URLs for local storage provider', async () => {
const previousProvider = process.env.FILE_STORAGE_PROVIDER;
process.env.FILE_STORAGE_PROVIDER = 'local';
try {
assert.deepEqual(
await generatePresignedUrls(['projects/demo/image 1.jpg']),
{
'projects/demo/image 1.jpg':
'/api/file/download?privateUrl=projects%2Fdemo%2Fimage%201.jpg',
},
);
} finally {
if (previousProvider === undefined) {
delete process.env.FILE_STORAGE_PROVIDER;
} else {
process.env.FILE_STORAGE_PROVIDER = previousProvider;
}
}
});