Null-DRM-Official/apps/modules/tg4/tg4_test.go
404errordeveloper 2fa8f2435f Initial commit: Null DRM Official
Capture, decrypt, and restream toolkit with compiled-in app modules
(RTE, TG4, BBC), on-device MITM proxy, streamd control plane, and www.
BBC module.yaml is published (clear streams); other module values stay local.
2026-10-06 00:25:35 +02:00

129 lines
3.6 KiB
Go

package tg4
import (
"testing"
appreg "drmdecryption/app"
"drmdecryption/modcfg"
"drmdecryption/modules/provider"
)
// Compile-time proof the plugin satisfies every interface the host expects.
var (
_ appreg.App = (*App)(nil)
_ appreg.Catalog = (*App)(nil)
_ appreg.StreamDefaults = (*App)(nil)
)
func testApp(t *testing.T) *App {
t.Helper()
cfg := Config{
AccountID: "acct",
PolicyKey: "pk",
PlaybackConfigURL: "https://cfg.test/playback.json",
Channels: map[string]Channel{
"main": {Label: "Main", VideoID: "111", TokenField: "mainToken", LiveCardIndex: 0},
"extra": {Label: "Extra", StreamIDField: "extraStreamId", TokenField: "extraToken", LiveCardIndex: 1},
"phone": {Label: "Phone only", PhoneOnly: true, LiveCardIndex: 3},
},
Common: provider.Common{
Aliases: map[string]string{"primary": "main", "second": "extra"},
},
}.withDefaults()
labels := map[string]string{}
for id, ch := range cfg.Channels {
labels[id] = ch.Label
}
return &App{Base: provider.New(Name, cfg.Common, labels, modcfg.Result{Path: "test"}), cfg: cfg}
}
func TestAliasesResolveFromConfig(t *testing.T) {
a := testApp(t)
for in, want := range map[string]string{
"main": "main", "MAIN": "main", "primary": "main",
"second": "extra", "extra": "extra",
} {
got, err := a.Base.Resolve(in)
if err != nil {
t.Fatalf("resolve %q: %v", in, err)
}
if got != want {
t.Errorf("resolve(%q) = %q, want %q", in, got, want)
}
}
if _, err := a.Base.Resolve("nope"); err == nil {
t.Error("unknown channel must error")
}
}
// A video id pinned in config wins; otherwise it is read from the named remote
// playback-config field. Both paths are data-driven, no channel name switch.
func TestResolveChannelReadsConfiguredFields(t *testing.T) {
a := testApp(t)
pc := playbackConfig{
"mainToken": "tok-main",
"extraToken": "tok-extra",
"extraStreamId": "222",
}
_, vid, tok, err := a.resolveChannel(pc, "main")
if err != nil {
t.Fatalf("main: %v", err)
}
if vid != "111" || tok != "tok-main" {
t.Errorf("main → video %q token %q", vid, tok)
}
_, vid, tok, err = a.resolveChannel(pc, "extra")
if err != nil {
t.Fatalf("extra: %v", err)
}
if vid != "222" || tok != "tok-extra" {
t.Errorf("extra → video %q token %q", vid, tok)
}
}
// A phone-only channel must say so rather than fail with a confusing catalog error.
func TestPhoneOnlyChannelExplainsItself(t *testing.T) {
a := testApp(t)
_, _, _, err := a.resolveChannel(playbackConfig{}, "phone")
if err == nil {
t.Fatal("phone-only channel must not resolve from the catalog")
}
if want := "drm capture"; !contains(err.Error(), want) {
t.Errorf("error %q should point at %q", err, want)
}
}
func TestPlaybackConfigCoercesNumericIDs(t *testing.T) {
pc := playbackConfig{"a": "123", "b": float64(456), "c": true}
if pc.str("a") != "123" {
t.Error("string field")
}
if pc.str("b") != "456" {
t.Errorf("numeric field = %q, want 456", pc.str("b"))
}
if pc.str("missing") != "" || pc.str("") != "" {
t.Error("missing field must be empty")
}
if !pc.Flags()["c"] {
t.Error("bool flags should be reported")
}
}
// No provider identity may be compiled in.
func TestNoHardcodedCredentials(t *testing.T) {
cfg := Config{}.withDefaults()
if cfg.AccountID != "" || cfg.PolicyKey != "" || cfg.PlaybackConfigURL != "" || cfg.Package != "" {
t.Fatal("account id / policy key / config URL / package must come from module.yaml")
}
}
func contains(s, sub string) bool {
return len(s) >= len(sub) && (func() bool {
for i := 0; i+len(sub) <= len(s); i++ {
if s[i:i+len(sub)] == sub {
return true
}
}
return false
})()
}