package api import ( "testing" "time" "pargar/backend/internal/config" ) func TestStableMediaExpiryHoldsInsideWindow(t *testing.T) { start := time.Unix((1_700_000_000/900)*900, 0) ttl := time.Hour window := 15 * time.Minute a := stableMediaExpiry(start, ttl, window) b := stableMediaExpiry(start.Add(14*time.Minute), ttl, window) if a != b { t.Fatalf("same window should keep one expiry: %d vs %d", a, b) } c := stableMediaExpiry(start.Add(15*time.Minute), ttl, window) if c == a { t.Fatal("next window should mint a new expiry") } if c < a { t.Fatal("expiry should move forward") } } func TestMediaSignatureRoundTrip(t *testing.T) { s := &Server{cfg: &config.Config{JWTSecret: "test-secret-at-least-32-chars-long!!", PublicURL: "http://localhost", MediaURLTTL: time.Hour}} url := s.signMediaURL("videos/lesson-1.mp4") if url == "" || !containsAll(url, "/media/", "exp=", "sig=") { t.Fatalf("bad signed url: %s", url) } key := mediaKeyFromURL(url) if key != "videos/lesson-1.mp4" { t.Fatalf("key extract: %q", key) } // parse query manually exp := "" sig := "" for _, part := range splitQuery(url) { if len(part) > 4 && part[:4] == "exp=" { exp = part[4:] } if len(part) > 4 && part[:4] == "sig=" { sig = part[4:] } } if !s.verifyMediaSignature(key, exp, sig) { t.Fatal("signature should verify") } if s.verifyMediaSignature(key, "1", sig) { t.Fatal("expired should fail") } } func containsAll(s string, parts ...string) bool { for _, p := range parts { if !containsStr(s, p) { return false } } return true } func containsStr(s, sub string) bool { return len(s) >= len(sub) && (s == sub || len(sub) == 0 || indexOf(s, sub) >= 0) } func indexOf(s, sub string) int { for i := 0; i+len(sub) <= len(s); i++ { if s[i:i+len(sub)] == sub { return i } } return -1 } func splitQuery(u string) []string { i := indexOf(u, "?") if i < 0 { return nil } q := u[i+1:] var parts []string start := 0 for j := 0; j <= len(q); j++ { if j == len(q) || q[j] == '&' { parts = append(parts, q[start:j]) start = j + 1 } } return parts }