В карточке подтверждения и уведомлении о готовности бот теперь показывает
запись матча метабазы — провайдер, id и кликабельную ссылку на страницу
записи, — как веб-страница /download/{id} и экран ревью. Так ошибочную
привязку видно и из Telegram.
Билдер URL записи (providerURL/matchURL) вынесен из internal/httpapi в ядро
internal/worker (worker.ProviderURL + метод (*ReviewData).MatchURL()), чтобы
оба транспорта строили ссылку одинаково; httpapi делегирует туда. baseLine
переведён на эффективные provider/id (с учётом ручных правок), URL в href
экранируется escHref (сверх esc закрывает кавычку — иначе изготовленный id
разорвал бы атрибут и Telegram отклонил бы сообщение). При отсутствии матча
карточка ревью показывает «нет матча», уведомление о готовности строку
опускает.
Capability notifications: ADDED «Показ записи матча метабазы» + MODIFIED
требования об экранировании (id матча и URL, контекст href).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
45 lines
1.7 KiB
Go
45 lines
1.7 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestParseManualSource(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
provider string
|
|
raw string
|
|
wantProvider string
|
|
wantID string
|
|
wantErr bool
|
|
}{
|
|
{"id с провайдером", "tmdb", "60622", "tmdb", "60622", false},
|
|
{"id обрезается позже воркером", "TVDB", "269613", "tvdb", "269613", false},
|
|
{"URL TMDB со slug", "", "https://www.themoviedb.org/tv/60622-fargo", "tmdb", "60622", false},
|
|
{"URL TMDB без схемы", "", "themoviedb.org/tv/60622", "tmdb", "60622", false},
|
|
{"URL TMDB movie", "", "https://www.themoviedb.org/movie/693134", "tmdb", "693134", false},
|
|
{"URL IMDb", "", "https://www.imdb.com/title/tt0111161/", "imdb", "tt0111161", false},
|
|
{"URL TVDB dereferrer", "", "https://www.thetvdb.com/dereferrer/series/269613", "tvdb", "269613", false},
|
|
{"URL TVDB slug — без id → ошибка", "", "https://www.thetvdb.com/series/fargo", "", "", true},
|
|
{"мусорный URL → ошибка", "", "https://example.com/foo/bar", "", "", true},
|
|
{"пустой ввод → ошибка", "tmdb", " ", "", "", true},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
p, id, err := parseManualSource(c.provider, c.raw)
|
|
if c.wantErr {
|
|
if err == nil {
|
|
t.Fatalf("ожидалась ошибка, получено %q:%q", p, id)
|
|
}
|
|
return
|
|
}
|
|
if err != nil {
|
|
t.Fatalf("неожиданная ошибка: %v", err)
|
|
}
|
|
if p != c.wantProvider || id != c.wantID {
|
|
t.Errorf("parseManualSource(%q,%q) = %q:%q, want %q:%q", c.provider, c.raw, p, id, c.wantProvider, c.wantID)
|
|
}
|
|
})
|
|
}
|
|
}
|