package cmd import ( "testing" "axenov/iptv-checker/app" "axenov/iptv-checker/app/config" "github.com/spf13/cobra" ) func newCmdWithFlags() *cobra.Command { cmd := &cobra.Command{Use: "test"} // persistent flags normally set on rootCmd cmd.PersistentFlags().BoolVar(&app.Args.Debug, "debug", false, "") cmd.PersistentFlags().StringVar(&app.Args.LogLevel, "log-level", "", "") addCommonCheckFlags(cmd, 0) return cmd } func resetArgs() { app.Args = app.Arguments{} } func resetConfig() { app.Config = &config.Config{ App: config.AppConfig{ Debug: false, LogLevel: "info", Playlists: "./playlists.ini", Tags: "./channels.json", }, Check: config.CheckConfig{ Playlists: config.CheckPlaylistsConfig{ Timeout: 10000, AllCooldown: config.IntRange{Min: 0, Max: 0}, OneCooldown: config.IntRange{Min: 0, Max: 0}, MaxRoutines: 5, PerRoutine: 1, UserAgent: config.UserAgents{"default"}, }, Channels: config.CheckChannelsConfig{ Timeout: 10000, ByteRange: 512, Cooldown: config.IntRange{Min: 0, Max: 0}, MaxRoutines: 50, PerRoutine: 10, UserAgent: config.UserAgents{"default"}, }, }, Cache: config.CacheConfig{ Enabled: false, Host: "localhost", Port: 6379, Ttl: 1800, }, Server: config.ServerConfig{Port: 8800}, } } func TestApplyAppOverrides_NothingChanged(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{}) applyAppOverrides(cmd) if app.Config.App.Debug { t.Error("debug should remain false") } } func TestApplyAppOverrides_Debug(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--debug"}) applyAppOverrides(cmd) if !app.Config.App.Debug { t.Error("expected debug=true") } } func TestApplyAppOverrides_LogLevel(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--log-level", "error"}) applyAppOverrides(cmd) if app.Config.App.LogLevel != "error" { t.Errorf("expected 'error', got '%s'", app.Config.App.LogLevel) } } func TestApplyAppOverrides_Ini(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"-i", "/custom/path.ini"}) applyAppOverrides(cmd) if app.Config.App.Playlists != "/custom/path.ini" { t.Errorf("expected '/custom/path.ini', got '%s'", app.Config.App.Playlists) } } func TestApplyAppOverrides_Tags(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"-t", "/custom/tags.json"}) applyAppOverrides(cmd) if app.Config.App.Tags != "/custom/tags.json" { t.Errorf("expected '/custom/tags.json', got '%s'", app.Config.App.Tags) } } func TestApplyCacheOverrides_NothingChanged(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{}) applyCacheOverrides(cmd) if app.Config.Cache.Enabled { t.Error("cache should remain disabled") } } func TestApplyCacheOverrides_Enable(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--cache-enabled"}) applyCacheOverrides(cmd) if !app.Config.Cache.Enabled { t.Error("expected cache enabled") } } func TestApplyCacheOverrides_DisableWhenAlreadyEnabled(t *testing.T) { resetArgs() resetConfig() app.Config.Cache.Enabled = true cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--cache-enabled=false"}) applyCacheOverrides(cmd) if app.Config.Cache.Enabled { t.Error("expected cache disabled") } } func TestApplyCacheOverrides_Host(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--cache-host", "db.local"}) applyCacheOverrides(cmd) if app.Config.Cache.Host != "db.local" { t.Errorf("expected 'db.local', got '%s'", app.Config.Cache.Host) } } func TestApplyCacheOverrides_Port(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--cache-port", "6380"}) applyCacheOverrides(cmd) if app.Config.Cache.Port != 6380 { t.Errorf("expected 6380, got %d", app.Config.Cache.Port) } } func TestApplyCacheOverrides_Ttl(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--cache-ttl", "3600"}) applyCacheOverrides(cmd) if app.Config.Cache.Ttl != 3600 { t.Errorf("expected 3600, got %d", app.Config.Cache.Ttl) } } func TestApplyCheckOverrides_NothingChanged(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{}) applyCheckOverrides(cmd) if app.Config.Check.Playlists.Timeout != 10000 { t.Errorf("expected 10000, got %d", app.Config.Check.Playlists.Timeout) } } func TestApplyCheckOverrides_PlaylistsTimeout(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--playlists-timeout", "5"}) applyCheckOverrides(cmd) if app.Config.Check.Playlists.Timeout != 5000 { t.Errorf("expected 5000 ms from 5 s, got %d", app.Config.Check.Playlists.Timeout) } } func TestApplyCheckOverrides_PlaylistsAllCooldown(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--playlists-all-cooldown", "3"}) applyCheckOverrides(cmd) if app.Config.Check.Playlists.AllCooldown.Min != 3000 || app.Config.Check.Playlists.AllCooldown.Max != 3000 { t.Errorf("expected [3000,3000] ms from 3 s, got [%d,%d]", app.Config.Check.Playlists.AllCooldown.Min, app.Config.Check.Playlists.AllCooldown.Max) } } func TestApplyCheckOverrides_PlaylistsMaxRoutines(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--playlists-max-routines", "10"}) applyCheckOverrides(cmd) if app.Config.Check.Playlists.MaxRoutines != 10 { t.Errorf("expected 10, got %d", app.Config.Check.Playlists.MaxRoutines) } } func TestApplyCheckOverrides_PlaylistsUserAgent(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--playlists-user-agent", "UA1,UA2"}) applyCheckOverrides(cmd) if len(app.Config.Check.Playlists.UserAgent) != 2 { t.Fatalf("expected 2 user-agents, got %d", len(app.Config.Check.Playlists.UserAgent)) } if app.Config.Check.Playlists.UserAgent[0] != "UA1" || app.Config.Check.Playlists.UserAgent[1] != "UA2" { t.Errorf("unexpected user-agents: %v", app.Config.Check.Playlists.UserAgent) } } func TestApplyCheckOverrides_ChannelsTimeout(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--channels-timeout", "8"}) applyCheckOverrides(cmd) if app.Config.Check.Channels.Timeout != 8000 { t.Errorf("expected 8000 ms from 8 s, got %d", app.Config.Check.Channels.Timeout) } } func TestApplyCheckOverrides_ChannelsByteRange(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--channels-byte-range", "1024"}) applyCheckOverrides(cmd) if app.Config.Check.Channels.ByteRange != 1024 { t.Errorf("expected 1024, got %d", app.Config.Check.Channels.ByteRange) } } func TestApplyCheckOverrides_ChannelsCooldown(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--channels-cooldown", "1"}) applyCheckOverrides(cmd) if app.Config.Check.Channels.Cooldown.Min != 1000 || app.Config.Check.Channels.Cooldown.Max != 1000 { t.Errorf("expected [1000,1000] ms from 1 s, got [%d,%d]", app.Config.Check.Channels.Cooldown.Min, app.Config.Check.Channels.Cooldown.Max) } } func TestApplyCheckOverrides_ChannelsMaxRoutines(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--channels-max-routines", "100"}) applyCheckOverrides(cmd) if app.Config.Check.Channels.MaxRoutines != 100 { t.Errorf("expected 100, got %d", app.Config.Check.Channels.MaxRoutines) } } func TestApplyCheckOverrides_ChannelsUserAgent(t *testing.T) { resetArgs() resetConfig() cmd := newCmdWithFlags() cmd.ParseFlags([]string{"--channels-user-agent", "VLC"}) applyCheckOverrides(cmd) if len(app.Config.Check.Channels.UserAgent) != 1 || app.Config.Check.Channels.UserAgent[0] != "VLC" { t.Errorf("expected [VLC], got %v", app.Config.Check.Channels.UserAgent) } }