package main
import (
"bytes"
"io"
"strings"
"testing"
)
// Fixtures modelled on real open-epg output: ids of the form "Italia 1 HD.it",
// single-line channel/programme elements, "YYYYMMDDHHMMSS +0000" times.
const epgSource1 = `
Italia 1 HD.it
Rai 1 HD.it
Unmatched
Show A
Show B
Dropped programme
`
const epgSource2 = `
From src2 - duplicate
TV8 HD
Src2 dup show
TV8 show
`
func runMerge(t *testing.T, tvgIDs []string, sources ...string) string {
t.Helper()
rs := make([]io.ReadSeeker, len(sources))
for i, s := range sources {
rs[i] = bytes.NewReader([]byte(s))
}
var buf bytes.Buffer
if err := mergeEPG(rs, buildIDMap(tvgIDs), &buf); err != nil {
t.Fatalf("mergeEPG: %v", err)
}
return buf.String()
}
func TestMergeEPG_SingleSourceFiltersAndRewrites(t *testing.T) {
out := runMerge(t, []string{"Italia 1", "Rai 1"}, epgSource1)
mustContain(t, out, ``)
mustContain(t, out, ``)
mustNotContain(t, out, `Unmatched HD.it`)
mustNotContain(t, out, `Dropped programme`)
mustContain(t, out, `channel="Italia 1"`)
mustContain(t, out, `channel="Rai 1"`)
mustContain(t, out, `Show A`)
mustContain(t, out, `Show B`)
}
func TestMergeEPG_TwoSourcesFirstWinsAndProgrammesScoped(t *testing.T) {
out := runMerge(t,
[]string{"Italia 1", "Rai 1", "TV8"},
epgSource1, epgSource2,
)
// All three matched playlist channels should be present, exactly once.
for _, want := range []string{
``,
``,
``,
} {
if c := strings.Count(out, want); c != 1 {
t.Errorf("%q appears %d times in output, want 1", want, c)
}
}
// Source 1 owns "Italia 1" — its show appears, src2's must NOT.
mustContain(t, out, `Show A`)
mustNotContain(t, out, `Src2 dup show`)
mustNotContain(t, out, `From src2 - duplicate`) // dedup at channel level too
// Source 2 owns "TV8" — its programme should appear.
mustContain(t, out, `TV8 show`)
// "Unmatched" is not in the playlist tvg-id set.
mustNotContain(t, out, `Unmatched`)
mustNotContain(t, out, `Dropped programme`)
}
func TestMergeEPG_EmptyOutputForUnmatchedPlaylist(t *testing.T) {
out := runMerge(t, []string{"Channel That Does Not Exist"}, epgSource1)
mustNotContain(t, out, "")
}
func TestMergeEPG_NoSourcesProducesValidEmptyTV(t *testing.T) {
var buf bytes.Buffer
if err := mergeEPG(nil, buildIDMap([]string{"Italia 1"}), &buf); err != nil {
t.Fatalf("mergeEPG: %v", err)
}
out := buf.String()
mustContain(t, out, "")
}
func mustContain(t *testing.T, hay, needle string) {
t.Helper()
if !strings.Contains(hay, needle) {
t.Errorf("expected output to contain %q\n--- output ---\n%s", needle, hay)
}
}
func mustNotContain(t *testing.T, hay, needle string) {
t.Helper()
if strings.Contains(hay, needle) {
t.Errorf("expected output NOT to contain %q\n--- output ---\n%s", needle, hay)
}
}