fix: collision names must survive the sanitiser the content view applies

unique_filename produced 'manual (2).pdf'; HouseplanContentView sanitises the
name in the REQUEST too, turning ' (2)' into '_2_', so the file was written and
then 404'd. The same pattern was already in files/migrate, so a rebind that hit
a name collision has been producing dead links. Both use the shared helper now,
with '-2', which round-trips sanitize_filename — asserted.
This commit is contained in:
Matysh
2026-07-28 16:16:07 +03:00
parent 4418312b0b
commit a49b5e6d2e
7 changed files with 35 additions and 20 deletions
+4 -2
View File
@@ -798,8 +798,10 @@ test('migratePdfUrls: only confirmed copies are rewritten (review CR-3)', () =>
{ name: 'b.pdf', url: '/houseplan_files/files/v_old1/b.pdf?v=2' },
];
// сервер скопировал только a.pdf, причём переименовал из-за коллизии
const out = migratePdfUrls(pdfs, 'v_old1', 'dev99', { 'a.pdf': 'a (2).pdf' });
assert.equal(out[0].url, '/houseplan_files/files/dev99/a%20(2).pdf?v=1');
// collision names use only characters the content view accepts back in a
// request: ' (2)' was sanitised to '_2_' server-side and 404'd (v1.46.0)
const out = migratePdfUrls(pdfs, 'v_old1', 'dev99', { 'a.pdf': 'a-2.pdf' });
assert.equal(out[0].url, '/houseplan_files/files/dev99/a-2.pdf?v=1');
assert.equal(out[1].url, pdfs[1].url, 'нескопированный файл ссылается на старую папку');
// пустой маппинг = ничего не переносим
assert.deepEqual(migratePdfUrls(pdfs, 'v_old1', 'dev99', {}).map((p) => p.url),