124 lines
3.3 KiB
Go
124 lines
3.3 KiB
Go
package playback
|
|
|
|
import (
|
|
"context"
|
|
"mal/internal/domain"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestWatchModeSourcesDefersProviderResolution(t *testing.T) {
|
|
provider := &sourceCacheProvider{get: func(context.Context, int, []string, string, string) (*domain.StreamResult, error) {
|
|
t.Fatal("deferred watch page resolved a provider source")
|
|
return nil, nil
|
|
}}
|
|
svc := newSourceCacheService(provider)
|
|
|
|
sources, result, mode, from := svc.watchModeSources(
|
|
context.Background(), 42, nil, "1", "sub", "", false, true,
|
|
)
|
|
|
|
if len(sources) != 0 || result != nil || mode != "sub" || from != "" {
|
|
t.Fatalf("deferred result = (%v, %v, %q, %q)", sources, result, mode, from)
|
|
}
|
|
if provider.calls.Load() != 0 {
|
|
t.Fatalf("provider calls = %d, want 0", provider.calls.Load())
|
|
}
|
|
}
|
|
|
|
func TestWatchAnimeUsesLocalRow(t *testing.T) {
|
|
svc := &playbackService{repo: &fakePlaybackRepository{}}
|
|
|
|
anime, err := svc.watchAnime(context.Background(), 12)
|
|
if err != nil {
|
|
t.Fatalf("watchAnime() error = %v", err)
|
|
}
|
|
if anime.MalID != 12 || anime.Title != "Anime 12" {
|
|
t.Fatalf("watchAnime() = %+v", anime.Anime)
|
|
}
|
|
}
|
|
|
|
func TestFallbackModes(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
mode string
|
|
want []string
|
|
}{
|
|
{name: "sub falls back to dub", mode: "sub", want: []string{"dub"}},
|
|
{name: "dub falls back to sub", mode: "dub", want: []string{"sub"}},
|
|
{name: "unknown tries both canonical modes", mode: "raw", want: []string{"sub", "dub"}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := fallbackModes(tt.mode)
|
|
if len(got) != len(tt.want) {
|
|
t.Fatalf("len(got) = %d, want %d", len(got), len(tt.want))
|
|
}
|
|
for i, want := range tt.want {
|
|
if got[i] != want {
|
|
t.Fatalf("got[%d] = %q, want %q", i, got[i], want)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEpisodeAvailabilityWarning(t *testing.T) {
|
|
now := time.Date(2026, time.June, 27, 11, 0, 0, 0, time.UTC)
|
|
tests := []struct {
|
|
name string
|
|
list domain.CanonicalEpisodeList
|
|
want string
|
|
}{
|
|
{
|
|
name: "fresh availability does not warn",
|
|
list: domain.CanonicalEpisodeList{
|
|
Episodes: []domain.CanonicalEpisode{{Number: 1, HasSub: true}},
|
|
LastSuccessAt: "2026-06-27T10:00:00Z",
|
|
NextRefreshAt: "2026-06-27T12:00:00Z",
|
|
},
|
|
},
|
|
{
|
|
name: "stale availability warns",
|
|
list: domain.CanonicalEpisodeList{
|
|
Episodes: []domain.CanonicalEpisode{{Number: 1, HasSub: true}},
|
|
LastSuccessAt: "2026-06-27T09:00:00Z",
|
|
NextRefreshAt: "2026-06-27T10:00:00Z",
|
|
},
|
|
want: episodeAvailabilityUncertainWarning,
|
|
},
|
|
{
|
|
name: "retrying availability warns",
|
|
list: domain.CanonicalEpisodeList{
|
|
Episodes: []domain.CanonicalEpisode{{Number: 1, HasSub: true}},
|
|
NextRefreshAt: "2026-06-27T11:05:00Z",
|
|
RetryUntilAt: "2026-06-27T11:30:00Z",
|
|
FailureCount: 1,
|
|
},
|
|
want: episodeAvailabilityUncertainWarning,
|
|
},
|
|
{
|
|
name: "failed availability warns",
|
|
list: domain.CanonicalEpisodeList{
|
|
Episodes: []domain.CanonicalEpisode{{Number: 1, HasSub: true}},
|
|
FailureCount: 3,
|
|
},
|
|
want: episodeAvailabilityUncertainWarning,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := episodeAvailabilityWarning(tt.list, now)
|
|
if got != tt.want {
|
|
t.Fatalf("episodeAvailabilityWarning() = %q, want %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|