Files
jellybit/internal/recognize/sanitize_test.go
T
av 9aecf757e0 recognize: название из метабазы санитизируется перед попаданием в план
- чистка стоит на каждой точке входа значения метабазы в план — сборка матча,
  копия кандидата для ревью, набор закреплённых значений источника и его
  чтение: гарантия, поставленная только на запись, обходится данными,
  сохранёнными прежними версиями
- название, непригодное как имя каталога (пустое или без единой буквы и
  цифры), не подставляется — раздача уходит в review с названной причиной
- гейт подтверждения матча не сдвинут: сравнение с планом идёт по значениям
  провайдера, чистится только копия, уходящая дальше
2026-08-10 10:41:16 +03:00

103 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package recognize
import (
"bytes"
"log/slog"
"strings"
"testing"
)
func TestFoldHomoglyphs(t *testing.T) {
cases := map[string]string{
// Latin-доминантный токен: кириллический двойник 'а' (U+0430) → 'a'.
"Hаrold and the Purple Crayon": "Harold and the Purple Crayon",
// Честная кириллица — не трогаем.
"Тёмный рыцарь": "Тёмный рыцарь",
// Честная латиница — не трогаем.
"The Dark Knight": "The Dark Knight",
// Cyrillic-доминантный токен (М р з) с латинскими 'o' (U+006F) → 'о'.
"Мoрoз": "Мороз",
// Равенство скриптов в токене (кир. О U+041E + лат. k) — не трогаем.
"Оk": "Оk",
// Двуязычные, но одно-скриптовые токены — каждый нетронут.
"Fargo Фарго": "Fargo Фарго",
// Буква-меньшинство без двойника в таблице (кир. 'б' U+0431) остаётся.
"Harбld": "Harбld",
// Пустая строка.
"": "",
}
for in, want := range cases {
if got := foldHomoglyphs(in); got != want {
t.Errorf("foldHomoglyphs(%q) = %q, want %q", in, got, want)
}
}
}
func TestSanitizeTitle(t *testing.T) {
cases := map[string]string{
// Zero-width (U+200B) внутри слова удаляется, слово склеивается.
"a\u200bb": "ab",
// Zero-width + двойник + лишние пробелы → strip + fold + collapse + trim.
" Hаrold\u200b Crayon ": "Harold Crayon",
// Табы/переводы строк как пробелы, сведены к одиночным.
"Harold\tand the": "Harold and the",
// Управляющий символ (BEL U+0007) удаляется.
"Harold\u0007": "Harold",
// BOM (U+FEFF) удаляется.
"\ufeffFargo": "Fargo",
// Уже чистое — без изменений.
"The Matrix": "The Matrix",
}
for in, want := range cases {
if got := SanitizeTitle(in); got != want {
t.Errorf("SanitizeTitle(%q) = %q, want %q", in, got, want)
}
}
}
func TestSanitizePlan_FieldsCleanedSrcUntouched(t *testing.T) {
// src намеренно содержит кириллический двойник — sanitizePlan его не трогает.
dirtySrc := "Hаrold.mkv"
p := Plan{
Title: "Hаrold",
OriginalTitle: " spaced ",
ProviderHint: "clean\u200b",
Files: []PlanFile{{Src: dirtySrc, Role: RoleMain}},
}
sanitizePlan(&p, nil)
if p.Title != "Harold" {
t.Errorf("Title = %q, want %q", p.Title, "Harold")
}
if p.OriginalTitle != "spaced" {
t.Errorf("OriginalTitle = %q, want %q", p.OriginalTitle, "spaced")
}
if p.ProviderHint != "clean" {
t.Errorf("ProviderHint = %q, want %q", p.ProviderHint, "clean")
}
if p.Files[0].Src != dirtySrc {
t.Errorf("files[].src изменён санитайзингом: %q != %q", p.Files[0].Src, dirtySrc)
}
}
func TestSanitizePlan_LogsOnChange(t *testing.T) {
var buf bytes.Buffer
log := slog.New(slog.NewTextHandler(&buf, &slog.HandlerOptions{Level: slog.LevelDebug}))
p := Plan{Title: "Hаrold"} // 'а' — кириллица, санитайзинг перепишет
sanitizePlan(&p, log)
out := buf.String()
if !strings.Contains(out, "recognition plan field sanitized") || !strings.Contains(out, "field=title") {
t.Errorf("ожидался Debug-лог о санитайзинге title, got: %q", out)
}
}
func TestSanitizePlan_NoLogWhenClean(t *testing.T) {
var buf bytes.Buffer
log := slog.New(slog.NewTextHandler(&buf, &slog.HandlerOptions{Level: slog.LevelDebug}))
p := Plan{Title: "Harold", OriginalTitle: "The Matrix"}
sanitizePlan(&p, log)
if buf.Len() != 0 {
t.Errorf("для чистых полей лога быть не должно, got: %q", buf.String())
}
}