39948-vm/backend/tests/file-service.test.ts
2026-07-03 15:59:42 +02:00

55 lines
1.7 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import config from '../src/config.ts';
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 = config.fileStorage.provider;
config.fileStorage.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 {
config.fileStorage.provider = previousProvider;
}
});