fix(backend): Download-Filter konnte ohne Titel- oder Kuenstlermerkmal zugreifen

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-09-24 23:31:29 +02:00
1 parent 1432a960fb
commit 06b13caea9
3 files changed
+111 -15

No files matched your search

+42
View File
@@ -107,3 +107,45 @@ test('nothing but list entries yields no candidates', () => {
assert.deepEqual(pickYtmVideoUrls(only).urls, []);
assert.deepEqual(pickYtmVideoUrls('').urls, []);
});
// ─── Japanische Titel bekommen wieder eine Titelpruefung ────────────────────
// Regression zum 24.9.2026: "銀髪の少年" (HUNTER×HUNTER, Yoshihisa Hirano) lieferte ein anderes
// Stueck desselben Komponisten. Ursache: fuer japanische Titel gab buildTitleKeywords eine LEERE
// Liste zurueck, und die Kaskadenschritte 3/4 lassen die Kuenstlerpruefung fallen — uebrig blieb
// allein das Dauerfenster, in das auf einem Soundtrack-Album fast jeder Titel passt.
test('japanischer Titel liefert jetzt ein Muster statt gar nichts', () => {
const kws = buildTitleKeywords('銀髪の少年');
assert.equal(kws.length, 1);
assert.ok(new RegExp(kws[0], 'i').test('銀髪の少年'), 'Originaltitel muss passen');
assert.ok(!new RegExp(kws[0], 'i').test('闘う者たち'), 'anderes Stueck darf NICHT passen');
});
test('Romaji-Fassung wird als Alternative akzeptiert', () => {
const kws = buildTitleKeywords('銀髪の少年', 'ginpatsu no shounen');
const re = new RegExp(kws[0], 'i');
assert.ok(re.test('銀髪の少年'), 'Original');
assert.ok(re.test('Ginpatsu no Shounen'), 'Romaji mit Leerzeichen');
assert.ok(re.test('Ginpatsu-no-Shounen'), 'Romaji mit Bindestrichen');
assert.ok(re.test('Hunter x Hunter OST - Ginpatsu no Shounen'), 'als Teil eines laengeren Titels');
assert.ok(!re.test('Requiem Aranea'), 'anderes Stueck desselben Albums');
});
test('Romaji, die gar keine sind, werden nicht als Alternative genommen', () => {
// romajiForStorage gibt den Text unveraendert zurueck, wenn der Tokenizer fehlt
const kws = buildTitleKeywords('銀髪の少年', '銀髪の少年');
assert.equal(kws.length, 1);
assert.ok(!kws[0].includes('|'), 'keine doppelte Alternative');
});
test('Sonderzeichen im japanischen Titel bleiben woertlich', () => {
const kws = buildTitleKeywords('君の名は。(Movie ver.)');
const re = new RegExp(kws[0], 'i');
assert.ok(re.test('君の名は。(Movie ver.)'));
assert.ok(!re.test('君の名はX Movie verY'), 'Punkt darf nicht als Platzhalter wirken');
});
test('lateinische Titel bleiben unveraendert', () => {
assert.deepEqual(buildTitleKeywords('Bohemian Rhapsody'), ['Bohemian', 'Rhapsody']);
assert.deepEqual(buildTitleKeywords('Dearly Beloved'), ['Beloved', 'Dearly']);
});