Files
silo-server/internal/playback/audio_select_test.go
T

183 lines
5.1 KiB
Go

package playback_test
import (
"testing"
"github.com/Silo-Server/silo-server/internal/models"
"github.com/Silo-Server/silo-server/internal/playback"
"github.com/Silo-Server/silo-server/internal/userstore"
)
func TestSelectAudioTrack(t *testing.T) {
tracks := []models.AudioTrack{
{Language: "en", Codec: "aac", Default: true, Channels: 2},
{Language: "ja", Codec: "aac", Channels: 2},
{Language: "ja", Codec: "flac", Channels: 6, Layout: "5.1"},
{Language: "de", Codec: "aac", Channels: 2},
}
tests := []struct {
name string
preferredLang string
seriesPrefIdx int
seriesPrefLang string
hasSeriesPref bool
want int
}{
{
name: "series pref index+lang match",
preferredLang: "en",
seriesPrefIdx: 2, seriesPrefLang: "ja", hasSeriesPref: true,
want: 2,
},
{
name: "series pref index out of bounds falls back to lang",
preferredLang: "en",
seriesPrefIdx: 99, seriesPrefLang: "ja", hasSeriesPref: true,
want: 1,
},
{
name: "series pref index wrong lang falls back to lang match",
preferredLang: "en",
seriesPrefIdx: 0, seriesPrefLang: "ja", hasSeriesPref: true,
want: 1,
},
{
name: "no series pref uses profile language",
preferredLang: "de",
hasSeriesPref: false,
want: 3,
},
{
name: "no matching language uses default track",
preferredLang: "fr",
hasSeriesPref: false,
want: 0,
},
{
name: "empty preferred lang uses default track",
preferredLang: "",
hasSeriesPref: false,
want: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var seriesPref *playback.AudioTrackPreference
if tt.hasSeriesPref {
seriesPref = &playback.AudioTrackPreference{
AudioTrackIndex: tt.seriesPrefIdx,
AudioLanguage: tt.seriesPrefLang,
}
}
got := playback.SelectAudioTrack(tracks, tt.preferredLang, seriesPref)
if got != tt.want {
t.Errorf("SelectAudioTrack() = %d, want %d", got, tt.want)
}
})
}
}
func TestSelectAudioTrack_NoTracks(t *testing.T) {
got := playback.SelectAudioTrack(nil, "en", nil)
if got != 0 {
t.Errorf("SelectAudioTrack(nil) = %d, want 0", got)
}
}
func TestSelectAudioTrack_NoDefaultFallsToFirst(t *testing.T) {
tracks := []models.AudioTrack{
{Language: "ja", Codec: "aac"},
{Language: "en", Codec: "aac"},
}
got := playback.SelectAudioTrack(tracks, "fr", nil)
if got != 0 {
t.Errorf("SelectAudioTrack() = %d, want 0", got)
}
}
// TestSelectAudioTrack_ISO639CrossFormat tests that 2-letter profile
// preferences match 3-letter FFmpeg track codes and vice versa.
func TestSelectAudioTrack_ISO639CrossFormat(t *testing.T) {
// Real-world FFmpeg track languages use 3-letter ISO 639-2 codes.
tracks := []models.AudioTrack{
{Language: "spa", Codec: "aac", Default: true, Channels: 2},
{Language: "eng", Codec: "aac", Channels: 6, Layout: "5.1"},
{Language: "jpn", Codec: "flac", Channels: 2},
}
tests := []struct {
name string
preferredLang string
want int
}{
{"2-letter en matches 3-letter eng", "en", 1},
{"2-letter es matches 3-letter spa", "es", 0},
{"2-letter ja matches 3-letter jpn", "ja", 2},
{"3-letter eng matches 3-letter eng", "eng", 1},
{"unmatched falls to default", "fr", 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := playback.SelectAudioTrack(tracks, tt.preferredLang, nil)
if got != tt.want {
t.Errorf("SelectAudioTrack() = %d, want %d", got, tt.want)
}
})
}
}
func TestSelectAudioTrack_SeriesPrefCrossFormat(t *testing.T) {
tracks := []models.AudioTrack{
{Language: "spa", Codec: "aac", Default: true, Channels: 2},
{Language: "eng", Codec: "aac", Channels: 6},
{Language: "jpn", Codec: "flac", Channels: 2},
}
// Series pref stored with 3-letter code (from track), profile uses 2-letter.
pref := &playback.AudioTrackPreference{
AudioTrackIndex: 2,
AudioLanguage: "jpn",
}
got := playback.SelectAudioTrack(tracks, "en", pref)
if got != 2 {
t.Errorf("series pref jpn at index 2: got %d, want 2", got)
}
// Series pref language fallback with 2-letter stored code.
pref2 := &playback.AudioTrackPreference{
AudioTrackIndex: 99, // out of bounds
AudioLanguage: "ja", // 2-letter
}
got = playback.SelectAudioTrack(tracks, "en", pref2)
if got != 2 {
t.Errorf("series pref ja fallback: got %d, want 2", got)
}
}
func TestSelectAudioTrack_PrefersExactTrackSignatureOverIndexFallback(t *testing.T) {
tracks := []models.AudioTrack{
{Language: "eng", Codec: "aac", Channels: 2, Layout: "stereo", Title: "English Stereo", Default: true},
{Language: "eng", Codec: "flac", Channels: 6, Layout: "5.1", Title: "English 5.1"},
}
pref := &playback.AudioTrackPreference{
AudioTrackIndex: 0,
AudioLanguage: "en",
TrackSignature: &userstore.AudioTrackSignature{
Language: "eng",
Title: "English 5.1",
Codec: "flac",
Layout: "5.1",
Channels: 6,
Default: false,
},
}
got := playback.SelectAudioTrack(tracks, "en", pref)
if got != 1 {
t.Fatalf("SelectAudioTrack() = %d, want 1", got)
}
}