playlist model

This commit is contained in:
Dmitry Sergeev
2026-09-01 19:13:12 +03:00
parent 9bc08109fc
commit e50ad8adb5
2 changed files with 244 additions and 0 deletions
+153
View File
@@ -0,0 +1,153 @@
package playback
import (
"errors"
"testing"
"time"
)
func TestPlaylistEntryValidate(t *testing.T) {
tests := []struct {
name string
entry PlaylistEntry
wantErr error
}{
{name: "video only", entry: PlaylistEntry{Video: PlaylistFeed{Domain: "video-domain", UUID: "video"}}},
{name: "audio only", entry: PlaylistEntry{Audio: PlaylistFeed{Domain: "audio-domain", UUID: "audio"}}},
{
name: "independent feeds from different domains",
entry: PlaylistEntry{
Video: PlaylistFeed{Domain: "video-domain", UUID: "video"},
Audio: PlaylistFeed{Domain: "audio-domain", UUID: "audio"},
},
},
{
name: "synchronized pair",
entry: PlaylistEntry{
Video: PlaylistFeed{Domain: "domain", UUID: "video"},
Audio: PlaylistFeed{Domain: "domain", UUID: "audio"},
SyncRequested: true,
Duration: 10 * time.Second,
},
},
{name: "zero duration", entry: PlaylistEntry{Video: PlaylistFeed{Domain: "domain", UUID: "video"}}},
{name: "empty entry", entry: PlaylistEntry{}, wantErr: ErrPlaylistEntryEmpty},
{
name: "video UUID without domain",
entry: PlaylistEntry{Video: PlaylistFeed{UUID: "video"}},
wantErr: ErrFeedDomainRequired,
},
{
name: "audio domain without UUID",
entry: PlaylistEntry{Audio: PlaylistFeed{Domain: "audio-domain"}},
wantErr: ErrPlaylistFeedUUIDRequired,
},
{
name: "sync without audio",
entry: PlaylistEntry{
Video: PlaylistFeed{Domain: "domain", UUID: "video"},
SyncRequested: true,
},
wantErr: ErrPlaylistSyncFeedsRequired,
},
{
name: "sync without video",
entry: PlaylistEntry{
Audio: PlaylistFeed{Domain: "domain", UUID: "audio"},
SyncRequested: true,
},
wantErr: ErrPlaylistSyncFeedsRequired,
},
{
name: "negative duration",
entry: PlaylistEntry{
Video: PlaylistFeed{Domain: "domain", UUID: "video"},
Duration: -time.Second,
},
wantErr: ErrPlaylistDurationNegative,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := test.entry.Validate()
if !errors.Is(err, test.wantErr) {
t.Fatalf("Validate() error = %v, want %v", err, test.wantErr)
}
})
}
}
func TestPlaylistEntrySessionConfig(t *testing.T) {
retry := RetryPolicy{MaxAttempts: 3, InitialDelay: time.Second, MaxDelay: 5 * time.Second}
entry := PlaylistEntry{
Video: PlaylistFeed{Domain: "video-domain", UUID: "video"},
Audio: PlaylistFeed{Domain: "audio-domain", UUID: "audio"},
SyncRequested: true,
Duration: 10 * time.Second,
}
got := entry.SessionConfig(retry)
want := SessionConfig{
Video: FeedConfig{Domain: "video-domain", UUID: "video", Active: true},
Audio: FeedConfig{Domain: "audio-domain", UUID: "audio", Active: true},
SyncRequested: true,
Retry: retry,
}
if got != want {
t.Fatalf("SessionConfig() = %#v, want %#v", got, want)
}
}
func TestPlaylistEntrySessionConfigLeavesMissingFeedInactive(t *testing.T) {
entry := PlaylistEntry{Video: PlaylistFeed{Domain: "domain", UUID: "video"}}
got := entry.SessionConfig(RetryPolicy{})
if !got.Video.Active {
t.Fatal("SessionConfig() video is inactive, want active")
}
if got.Audio != (FeedConfig{}) {
t.Fatalf("SessionConfig() audio = %#v, want zero value", got.Audio)
}
}
func TestPlaylistValidate(t *testing.T) {
valid := PlaylistEntry{Video: PlaylistFeed{Domain: "domain", UUID: "video"}}
tests := []struct {
name string
playlist Playlist
wantErr error
}{
{name: "empty playlist", playlist: Playlist{}},
{name: "valid entries", playlist: Playlist{Entries: []PlaylistEntry{valid, valid}, Loop: true}},
{
name: "invalid entry",
playlist: Playlist{Entries: []PlaylistEntry{
valid,
{Audio: PlaylistFeed{UUID: "audio"}},
}},
wantErr: ErrFeedDomainRequired,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := test.playlist.Validate()
if !errors.Is(err, test.wantErr) {
t.Fatalf("Validate() error = %v, want %v", err, test.wantErr)
}
})
}
}
func TestPlaylistValidateReportsEntryIndex(t *testing.T) {
playlist := Playlist{Entries: []PlaylistEntry{
{Video: PlaylistFeed{Domain: "domain", UUID: "video"}},
{},
}}
err := playlist.Validate()
if err == nil || err.Error() != "playlist entry 1: playlist entry must contain at least one feed" {
t.Fatalf("Validate() error = %v, want indexed entry error", err)
}
}