Release v0.2.34
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ponzischeme89/memby/server/internal/bazarr"
|
||||
"github.com/ponzischeme89/memby/server/internal/opensubtitles"
|
||||
"github.com/ponzischeme89/memby/server/internal/store"
|
||||
)
|
||||
|
||||
// A row has to carry the backend it came from, because the two tokens are opaque in
|
||||
// different ways and handing one to the other is a mistake nothing downstream could catch.
|
||||
func TestCandidatesCarryTheirSource(t *testing.T) {
|
||||
fromBazarr := bazarrCandidates([]bazarr.Subtitle{{Language: "eng", Token: "opaque"}})
|
||||
if len(fromBazarr) != 1 || fromBazarr[0].Source != store.SubtitleProviderBazarr {
|
||||
t.Fatalf("bazarr candidate = %+v", fromBazarr)
|
||||
}
|
||||
fromOpen := openSubtitlesCandidates([]opensubtitles.Subtitle{{FileID: 42, Language: "en"}})
|
||||
if len(fromOpen) != 1 || fromOpen[0].Source != store.SubtitleProviderOpenSubtitles {
|
||||
t.Fatalf("opensubtitles candidate = %+v", fromOpen)
|
||||
}
|
||||
if fromOpen[0].Token != "42" {
|
||||
t.Fatalf("token = %q, want the file id", fromOpen[0].Token)
|
||||
}
|
||||
}
|
||||
|
||||
// A machine translation is a real answer and sometimes the only one, so it is offered —
|
||||
// below everything a person wrote, whatever confidence the provider claims for it.
|
||||
func TestRankingSinksMachineTranslationsBelowHumanOnes(t *testing.T) {
|
||||
found := []subtitleCandidate{
|
||||
{Source: "opensubtitles", Token: "robot", Language: "en", Score: 99, MachineOnly: true},
|
||||
{Source: "bazarr", Token: "human", Language: "en", Score: 40},
|
||||
}
|
||||
results := rankMergedCandidates(found, "en")
|
||||
if results[0].Token != "human" {
|
||||
t.Fatalf("order = %q, %q", results[0].Token, results[1].Token)
|
||||
}
|
||||
if want := "English · Machine translated · 99% match"; results[1].Label != want {
|
||||
t.Fatalf("label = %q, want %q", results[1].Label, want)
|
||||
}
|
||||
}
|
||||
|
||||
// The viewer's language still outranks everything, across providers as it did within one.
|
||||
func TestRankingKeepsTheChosenLanguageFirstAcrossProviders(t *testing.T) {
|
||||
found := []subtitleCandidate{
|
||||
{Source: "bazarr", Token: "en", Language: "en", Score: 99},
|
||||
{Source: "opensubtitles", Token: "it", Language: "it", Score: 20},
|
||||
}
|
||||
if got := rankMergedCandidates(found, "it"); got[0].Token != "it" {
|
||||
t.Fatalf("first row = %q, want the Italian one", got[0].Token)
|
||||
}
|
||||
}
|
||||
|
||||
// A file nobody has rated is not a bad file, so it lands mid-scale rather than at the
|
||||
// bottom — the judgement heroUnratedScore already makes about an unrated title.
|
||||
func TestOpenSubtitlesScoreIsMidScaleWhenUnrated(t *testing.T) {
|
||||
unrated := openSubtitlesScore(opensubtitles.Subtitle{})
|
||||
if unrated < 40 || unrated > 70 {
|
||||
t.Fatalf("unrated score = %d, want mid-scale", unrated)
|
||||
}
|
||||
if rated := openSubtitlesScore(opensubtitles.Subtitle{Rating: 9.4}); rated <= unrated {
|
||||
t.Fatalf("a well-rated file scored %d, below an unrated %d", rated, unrated)
|
||||
}
|
||||
if machine := openSubtitlesScore(opensubtitles.Subtitle{Rating: 9.4, MachineOnly: true}); machine >= 94 {
|
||||
t.Fatalf("a machine translation kept its full score (%d)", machine)
|
||||
}
|
||||
}
|
||||
|
||||
// Two identically labelled rows in one drop-up is what makes a viewer distrust the whole
|
||||
// menu, so where both exist Emby's track wins: it is the one in the file.
|
||||
func TestMergeSubtitleTracksDropsWhatEmbyAlreadyHas(t *testing.T) {
|
||||
emby := []playableSubtitle{{ID: "3", Language: "eng", DeliveryMethod: "External"}}
|
||||
stored := []playableSubtitle{
|
||||
{ID: "gw:1:en:plain", Language: "en", DeliveryMethod: "External"},
|
||||
{ID: "gw:1:it:plain", Language: "it", DeliveryMethod: "External"},
|
||||
}
|
||||
merged := mergeSubtitleTracks(emby, stored)
|
||||
if len(merged) != 2 {
|
||||
t.Fatalf("merged = %+v", merged)
|
||||
}
|
||||
if merged[1].ID != "gw:1:it:plain" {
|
||||
t.Fatalf("kept %q, want only the Italian one to survive", merged[1].ID)
|
||||
}
|
||||
}
|
||||
|
||||
// A forced track is not the same track as a plain one in the same language, so it must not
|
||||
// be deduplicated away — that is exactly the subtitle somebody downloaded it for.
|
||||
func TestMergeSubtitleTracksKeepsADifferentVariant(t *testing.T) {
|
||||
emby := []playableSubtitle{{ID: "3", Language: "eng"}}
|
||||
stored := []playableSubtitle{{ID: "gw:1:en:forced", Language: "en", IsForced: true}}
|
||||
if merged := mergeSubtitleTracks(emby, stored); len(merged) != 2 {
|
||||
t.Fatalf("merged = %+v", merged)
|
||||
}
|
||||
}
|
||||
|
||||
// The id is derived from what was asked for, so fetching the same language twice replaces
|
||||
// the file rather than growing a second track a viewer has to tell apart by guessing.
|
||||
func TestStoredSubtitleIDIsStablePerVariant(t *testing.T) {
|
||||
plain := storedSubtitleID("42", subtitleCandidate{Language: "it"})
|
||||
again := storedSubtitleID("42", subtitleCandidate{Language: "it", Provider: "elsewhere"})
|
||||
if plain != again {
|
||||
t.Fatalf("%q != %q for the same title and language", plain, again)
|
||||
}
|
||||
forced := storedSubtitleID("42", subtitleCandidate{Language: "it", Forced: true})
|
||||
if forced == plain {
|
||||
t.Fatal("a forced track took the plain track's id")
|
||||
}
|
||||
if !isStoredSubtitleID(plain) {
|
||||
t.Fatalf("%q is not recognised as the gateway's own", plain)
|
||||
}
|
||||
// Emby's ids are stream indices, which are plain numbers. The two namespaces must not
|
||||
// be able to collide, because the player matches a track on the id it was handed.
|
||||
if isStoredSubtitleID("3") {
|
||||
t.Fatal("an Emby stream index was read as a gateway subtitle")
|
||||
}
|
||||
}
|
||||
|
||||
// A search restricted to nothing returns every language on earth, which is unreadable on a
|
||||
// television; English rides along because a household that never set a language gets one.
|
||||
func TestOpenSubtitlesLanguagesAlwaysNameSomething(t *testing.T) {
|
||||
for _, language := range []string{"", "auto"} {
|
||||
if got := openSubtitlesLanguages(language); len(got) != 1 || got[0] != "en" {
|
||||
t.Fatalf("languages for %q = %v", language, got)
|
||||
}
|
||||
}
|
||||
if got := openSubtitlesLanguages("it"); len(got) != 2 || got[0] != "it" {
|
||||
t.Fatalf("languages for Italian = %v, want Italian first", got)
|
||||
}
|
||||
}
|
||||
|
||||
// The allowance running out is the only failure where pressing the button again is
|
||||
// definitely not the answer, so it must not be flattened into "did not answer".
|
||||
func TestSubtitleFailureMessageSeparatesTheQuotaCase(t *testing.T) {
|
||||
if got := subtitleFailureMessage(nil); got != "No subtitles were found for this release." {
|
||||
t.Fatalf("no failures gave %q", got)
|
||||
}
|
||||
quota := subtitleFailureMessage([]error{&opensubtitles.QuotaError{}})
|
||||
other := subtitleFailureMessage([]error{&opensubtitles.APIError{StatusCode: 500}})
|
||||
if quota == other {
|
||||
t.Fatalf("an exhausted quota reads the same as any other failure: %q", quota)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user