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) } }