Files

154 lines
4.8 KiB
Go
Raw Permalink Normal View History

2026-05-06 11:05:20 +02:00
package main
import (
"bytes"
"reflect"
"strings"
"testing"
)
func TestProcessPlaylist_AppendsURLTvg(t *testing.T) {
in := "#EXTM3U\n" +
`#EXTINF:-1 tvg-id="Rai 1" tvg-name="Rai 1",Rai 1` + "\n" +
"http://example.com/stream\n"
var out bytes.Buffer
ids, orig, err := processPlaylist(strings.NewReader(in), &out, "https://relay/epg")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if orig != "" {
t.Errorf("originalEPG = %q, want empty", orig)
}
if got, want := ids, []string{"Rai 1"}; !reflect.DeepEqual(got, want) {
t.Errorf("tvgIDs = %v, want %v", got, want)
}
want := `#EXTM3U url-tvg="https://relay/epg"` + "\n" +
`#EXTINF:-1 tvg-id="Rai 1" tvg-name="Rai 1",Rai 1` + "\n" +
"http://example.com/stream\n"
if out.String() != want {
t.Errorf("output mismatch.\n got: %q\nwant: %q", out.String(), want)
}
}
func TestProcessPlaylist_ReplacesExistingURLTvg(t *testing.T) {
in := `#EXTM3U url-tvg="http://upstream.example/epg.xml"` + "\n" +
`#EXTINF:-1 tvg-id="Italia 1",Italia 1` + "\n" +
"http://example.com/stream\n"
var out bytes.Buffer
ids, orig, err := processPlaylist(strings.NewReader(in), &out, "https://relay/epg")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if orig != "http://upstream.example/epg.xml" {
t.Errorf("originalEPG = %q, want upstream URL captured", orig)
}
if got, want := ids, []string{"Italia 1"}; !reflect.DeepEqual(got, want) {
t.Errorf("tvgIDs = %v, want %v", got, want)
}
if !strings.Contains(out.String(), `url-tvg="https://relay/epg"`) {
t.Errorf("expected rewritten url-tvg in output, got: %q", out.String())
}
if strings.Contains(out.String(), "upstream.example") {
t.Errorf("upstream URL leaked into output: %q", out.String())
}
}
func TestProcessPlaylist_EmptyEPGURLLeavesHeaderAlone(t *testing.T) {
in := `#EXTM3U url-tvg="http://upstream.example/epg.xml"` + "\n" +
"http://example.com/stream\n"
var out bytes.Buffer
_, orig, err := processPlaylist(strings.NewReader(in), &out, "")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if orig != "http://upstream.example/epg.xml" {
t.Errorf("originalEPG = %q, want captured", orig)
}
if out.String() != in {
t.Errorf("output should match input verbatim when epgURL is empty.\n got: %q\nwant: %q", out.String(), in)
}
}
func TestProcessPlaylist_PreservesCRLF(t *testing.T) {
in := "#EXTM3U\r\n" +
`#EXTINF:-1 tvg-id="Rai 1",Rai 1` + "\r\n" +
"http://example.com/stream\r\n"
var out bytes.Buffer
if _, _, err := processPlaylist(strings.NewReader(in), &out, "https://relay/epg"); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !strings.HasPrefix(out.String(), `#EXTM3U url-tvg="https://relay/epg"`+"\r\n") {
t.Errorf("CRLF not preserved in header: %q", out.String())
}
if !strings.Contains(out.String(), "http://example.com/stream\r\n") {
t.Errorf("CRLF not preserved in body: %q", out.String())
}
}
func TestProcessPlaylist_StreamLinesPassThrough(t *testing.T) {
// All non-header lines must come through byte-for-byte; only the first
// non-empty line (the EXTM3U header) is rewritten.
in := "#EXTM3U\n" +
`#EXTINF:-1 tvg-id="A",A` + "\n" +
"http://example.com/a\n" +
`#EXTINF:-1 tvg-id="",B` + "\n" +
"http://example.com/b\n"
var out bytes.Buffer
ids, _, err := processPlaylist(strings.NewReader(in), &out, "https://relay/epg")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got, want := ids, []string{"A"}; !reflect.DeepEqual(got, want) {
t.Errorf("tvgIDs = %v, want %v (empty tvg-id must be skipped)", got, want)
}
for _, must := range []string{
`#EXTINF:-1 tvg-id="A",A` + "\n",
"http://example.com/a\n",
`#EXTINF:-1 tvg-id="",B` + "\n",
"http://example.com/b\n",
} {
if !strings.Contains(out.String(), must) {
t.Errorf("output missing line %q", must)
}
}
}
func TestProcessPlaylist_SkipsLeadingBlankLines(t *testing.T) {
in := "\n\n#EXTM3U\n#EXTINF:-1 tvg-id=\"X\",X\nhttp://example.com/x\n"
var out bytes.Buffer
ids, _, err := processPlaylist(strings.NewReader(in), &out, "https://relay/epg")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !reflect.DeepEqual(ids, []string{"X"}) {
t.Errorf("tvgIDs = %v", ids)
}
if !strings.HasPrefix(out.String(), "\n\n#EXTM3U "+`url-tvg="https://relay/epg"`+"\n") {
t.Errorf("leading blanks should be preserved before rewritten header: %q", out.String())
}
}
func TestProcessPlaylist_RejectsMissingHeader(t *testing.T) {
in := "garbage\n#EXTINF:-1 tvg-id=\"X\",X\n"
var out bytes.Buffer
_, _, err := processPlaylist(strings.NewReader(in), &out, "https://relay/epg")
if err == nil {
t.Fatal("expected error for missing #EXTM3U header")
}
}
func TestProcessPlaylist_RejectsEmptyInput(t *testing.T) {
var out bytes.Buffer
_, _, err := processPlaylist(strings.NewReader(""), &out, "https://relay/epg")
if err == nil {
t.Fatal("expected error for empty input")
}
}