wip8
This commit is contained in:
@@ -0,0 +1,360 @@
|
||||
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"])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user