mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
test(uploads): pin the uploads subdir list across Dockerfile and boot
The set of uploads subdirectories is hand-mirrored between the image build and the boot-time mkdir in server/src/index.ts, and drift is invisible until a user whose bind-mounted uploads dir is not writable by node hits an EACCES on the first upload to the missing dir (#1762). Parse both lists and assert they match, with a guard case so the regexes cannot silently match nothing and pass vacuously.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
// The set of uploads subdirectories is hand-mirrored between the image build and
|
||||
// the boot-time mkdir in server/src/index.ts. Drift is invisible until a user on
|
||||
// a host whose bind-mounted uploads dir isn't writable by node hits an EACCES on
|
||||
// first upload to the missing dir (#1762), so pin the two copies together.
|
||||
const repoRoot = path.resolve(__dirname, '../../..');
|
||||
|
||||
const readSubdirs = (file: string, pattern: RegExp): Set<string> => {
|
||||
const source = fs.readFileSync(path.join(repoRoot, file), 'utf8');
|
||||
const found = new Set<string>();
|
||||
for (const m of source.matchAll(pattern)) found.add(m[1]);
|
||||
return found;
|
||||
};
|
||||
|
||||
describe('uploads subdirectory parity', () => {
|
||||
const fromDockerfile = readSubdirs('Dockerfile', /\/app\/uploads\/([A-Za-z0-9_-]+)/g);
|
||||
const fromBoot = readSubdirs('server/src/index.ts', /path\.join\(uploadsDir, '([A-Za-z0-9_-]+)'\)/g);
|
||||
|
||||
it('finds both lists (guards against the regexes silently matching nothing)', () => {
|
||||
expect(fromDockerfile.size).toBeGreaterThan(0);
|
||||
expect(fromBoot.size).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('creates the same uploads subdirs in the Dockerfile and at boot', () => {
|
||||
expect([...fromBoot].sort()).toEqual([...fromDockerfile].sort());
|
||||
});
|
||||
|
||||
it('covers every uploads subdir the server writes to', () => {
|
||||
// journey/ and places/ are written by journey.controller.ts and
|
||||
// services/placeImage.ts; the rest are the long-standing upload stores.
|
||||
expect([...fromBoot].sort()).toEqual([
|
||||
'avatars',
|
||||
'covers',
|
||||
'files',
|
||||
'journey',
|
||||
'photos',
|
||||
'places',
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user