Files
iptvc/app/web/views_test.go
T
2026-07-19 19:14:55 +08:00

361 lines
9.0 KiB
Go

package web
import (
"testing"
"axenov/iptv-checker/app/playlist"
)
func TestHasTokensString(t *testing.T) {
cases := []struct {
in string
want bool
}{
{"http://example.com/stream.m3u8?token=abc", true},
{"http://example.com/stream?user=test&pwd=secret", true},
{"http://example.com/stream?drmreq=xyz", true},
{"http://example.com/stream?u=foo", true},
{"http://example.com/stream?password=123", true},
{"http://example.com/stream.m3u8", false},
{"", false},
{"plain text without tokens", false},
}
for _, c := range cases {
got := hasTokensString(c.in)
if got != c.want {
t.Errorf("hasTokensString(%q) = %v, want %v", c.in, got, c.want)
}
}
}
func TestStatusClass(t *testing.T) {
cases := []struct {
view *PlaylistView
want string
}{
{&PlaylistView{IsKnown: false}, "secondary"},
{&PlaylistView{IsKnown: true, Playlist: playlist.Playlist{IsOnline: true}}, "success"},
{&PlaylistView{IsKnown: true, Playlist: playlist.Playlist{IsOnline: false}}, "danger"},
}
for _, c := range cases {
got := statusClass(c.view)
if got != c.want {
t.Errorf("statusClass() = %s, want %s", got, c.want)
}
}
}
func TestStatusBadge(t *testing.T) {
cases := []struct {
view *PlaylistView
want string
}{
{&PlaylistView{IsKnown: false}, "unknown"},
{&PlaylistView{IsKnown: true, Playlist: playlist.Playlist{IsOnline: true}}, "online"},
{&PlaylistView{IsKnown: true, Playlist: playlist.Playlist{IsOnline: false}}, "offline"},
}
for _, c := range cases {
got := statusBadge(c.view)
if got != c.want {
t.Errorf("statusBadge() = %s, want %s", got, c.want)
}
}
}
func TestFormatDate(t *testing.T) {
if formatDate(0) != "" {
t.Error("expected empty string for ts=0")
}
result := formatDate(1700000000)
if result == "" {
t.Error("expected non-empty date string")
}
}
func TestIsAlphanumeric(t *testing.T) {
cases := []struct {
in string
want bool
}{
{"ABC123", true},
{"abc", true},
{"123", true},
{"", false},
{"ABC-123", false},
{"ABC_123", false},
{"ABC 123", false},
{"Привет", false},
}
for _, c := range cases {
got := isAlphanumeric(c.in)
if got != c.want {
t.Errorf("isAlphanumeric(%q) = %v, want %v", c.in, got, c.want)
}
}
}
func TestParseRedisVersion(t *testing.T) {
info := "# Server\nredis_version:6.2.6\nredis_mode:standalone\n"
got := parseRedisVersion(info)
if got != "6.2.6" {
t.Errorf("expected '6.2.6', got '%s'", got)
}
}
func TestParseRedisVersion_NotFound(t *testing.T) {
info := "# Server\nsome_other_field:foo\n"
got := parseRedisVersion(info)
if got != "unknown" {
t.Errorf("expected 'unknown', got '%s'", got)
}
}
func TestContainsTag(t *testing.T) {
tags := []string{"hd", "adult", "russian"}
if !containsTag(tags, "adult") {
t.Error("expected true for 'adult'")
}
if containsTag(tags, "movies") {
t.Error("expected false for 'movies'")
}
if containsTag([]string{}, "x") {
t.Error("expected false for empty list")
}
}
func TestMakeUnknownView(t *testing.T) {
iniPls := playlist.Playlist{
Name: "Test",
Description: "Desc",
Url: "http://example.com",
Source: "public",
}
view := makeUnknownView("CODE", iniPls)
if view.Code != "CODE" {
t.Errorf("expected Code='CODE', got '%s'", view.Code)
}
if view.IsKnown {
t.Error("expected IsKnown=false")
}
if view.Name != "Test" {
t.Errorf("expected Name='Test', got '%s'", view.Name)
}
if len(view.Tags) != 0 {
t.Errorf("expected 0 tags, got %d", len(view.Tags))
}
}
func TestEnrichPlaylist_OnlinePercent(t *testing.T) {
view := &PlaylistView{
Playlist: playlist.Playlist{
IsOnline: true,
OnlineCount: 8,
OfflineCount: 2,
Channels: map[string]playlist.Channel{
"1": {},
"2": {},
"3": {},
"4": {},
"5": {},
"6": {},
"7": {},
"8": {},
"9": {},
"10": {},
},
Attributes: map[string]string{},
Groups: map[string]playlist.Group{},
Content: "#EXTM3U",
},
IsKnown: true,
}
enrichPlaylist(view)
if view.OnlinePercent != 80 {
t.Errorf("expected 80%%, got %d%%", view.OnlinePercent)
}
if view.OfflinePercent != 20 {
t.Errorf("expected 20%%, got %d%%", view.OfflinePercent)
}
}
func TestEnrichPlaylist_Unknown(t *testing.T) {
view := &PlaylistView{
Playlist: playlist.Playlist{
Channels: map[string]playlist.Channel{"1": {}},
Attributes: map[string]string{},
Groups: map[string]playlist.Group{},
Content: "",
},
IsKnown: false,
}
enrichPlaylist(view)
if view.OnlinePercent != 0 || view.OfflinePercent != 0 {
t.Errorf("expected 0%% for unknown, got online=%d%% offline=%d%%",
view.OnlinePercent, view.OfflinePercent)
}
}
func TestEnrichPlaylist_HasCatchup(t *testing.T) {
view := &PlaylistView{
Playlist: playlist.Playlist{
Content: "#EXTM3U catchup=default",
Channels: map[string]playlist.Channel{},
Attributes: map[string]string{},
Groups: map[string]playlist.Group{},
},
IsKnown: true,
}
enrichPlaylist(view)
if !view.HasCatchup {
t.Error("expected HasCatchup=true")
}
}
func TestEnrichPlaylist_HasTvg(t *testing.T) {
view := &PlaylistView{
Playlist: playlist.Playlist{
Attributes: map[string]string{"url-tvg": "http://example.com/epg.xml"},
Channels: map[string]playlist.Channel{},
Groups: map[string]playlist.Group{},
Content: "",
},
IsKnown: true,
}
enrichPlaylist(view)
if !view.HasTvg {
t.Error("expected HasTvg=true")
}
}
func TestEnrichPlaylist_HasTokens(t *testing.T) {
view := &PlaylistView{
Playlist: playlist.Playlist{
Url: "http://example.com/list.m3u8?token=abc",
Content: "#EXTM3U",
Channels: map[string]playlist.Channel{},
Attributes: map[string]string{},
Groups: map[string]playlist.Group{},
},
IsKnown: true,
}
enrichPlaylist(view)
if !view.HasTokens {
t.Error("expected HasTokens=true")
}
}
func TestEnrichPlaylist_TagsCollection(t *testing.T) {
view := &PlaylistView{
Playlist: playlist.Playlist{
Channels: map[string]playlist.Channel{
"1": {Tags: []string{"hd", "russian"}},
"2": {Tags: []string{"adult", "hd"}},
},
Attributes: map[string]string{},
Groups: map[string]playlist.Group{},
Content: "",
},
IsKnown: true,
}
enrichPlaylist(view)
if len(view.Tags) != 3 {
t.Errorf("expected 3 unique tags, got %d: %v", len(view.Tags), view.Tags)
}
}
func TestEnrichPlaylist_ChannelHasToken(t *testing.T) {
view := &PlaylistView{
Playlist: playlist.Playlist{
Channels: map[string]playlist.Channel{
"1": {URL: "http://example.com/stream?token=abc"},
},
Attributes: map[string]string{},
Groups: map[string]playlist.Group{},
Content: "",
},
IsKnown: true,
}
enrichPlaylist(view)
for _, cv := range view.ViewChannels {
if !cv.HasToken {
t.Error("expected channel HasToken=true")
}
}
}
func TestComputeStats(t *testing.T) {
playlists := []PlaylistView{
{
Playlist: playlist.Playlist{
Code: "RU",
IsOnline: true,
CheckedAt: 1700000000,
Channels: map[string]playlist.Channel{"1": {IsOnline: true}, "2": {IsOnline: false}},
Groups: map[string]playlist.Group{"g1": {}},
Attributes: map[string]string{"url-tvg": "http://epg.xml"},
Content: "#EXTM3U catchup=default",
},
IsKnown: true,
HasCatchup: true,
HasTvg: true,
Tags: []string{"adult"},
},
{
Playlist: playlist.Playlist{
Code: "EN",
IsOnline: false,
CheckedAt: 1700000100,
Channels: map[string]playlist.Channel{"1": {IsOnline: false}},
},
IsKnown: false,
},
}
stats := computeStats(playlists)
plsStats := stats["playlists"].(map[string]interface{})
if plsStats["all"].(int) != 2 {
t.Errorf("expected 2 playlists, got %d", plsStats["all"])
}
if plsStats["online"].(int) != 1 {
t.Errorf("expected 1 online, got %d", plsStats["online"])
}
if plsStats["unknown"].(int) != 1 {
t.Errorf("expected 1 unknown, got %d", plsStats["unknown"])
}
if plsStats["adult"].(int) != 1 {
t.Errorf("expected 1 adult, got %d", plsStats["adult"])
}
if plsStats["hasCatchup"].(int) != 1 {
t.Errorf("expected 1 catchup, got %d", plsStats["hasCatchup"])
}
if plsStats["hasTvg"].(int) != 1 {
t.Errorf("expected 1 tvg, got %d", plsStats["hasTvg"])
}
if plsStats["groupped"].(int) != 1 {
t.Errorf("expected 1 groupped, got %d", plsStats["groupped"])
}
chStats := stats["channels"].(map[string]interface{})
if chStats["all"].(int) != 3 {
t.Errorf("expected 3 channels, got %d", chStats["all"])
}
if chStats["online"].(int) != 1 {
t.Errorf("expected 1 online channel, got %d", chStats["online"])
}
if chStats["offline"].(int) != 2 {
t.Errorf("expected 2 offline channels, got %d", chStats["offline"])
}
latest := plsStats["latest"].(map[string]interface{})
if latest["code"] != "EN" {
t.Errorf("expected latest code 'EN', got '%v'", latest["code"])
}
}
func TestComputeStats_Empty(t *testing.T) {
stats := computeStats([]PlaylistView{})
plsStats := stats["playlists"].(map[string]interface{})
if plsStats["all"].(int) != 0 {
t.Errorf("expected 0, got %d", plsStats["all"])
}
}