Files
notify/internal/marketing/listunsubscribe_test.go
zeekay 39028a6437 chore: scrub <tenant> brand integration from notify
- DefaultBrand const flipped from 'liquidity' to 'hanzo' (plivo_resolver.go,
  chain.go and all doc comments)
- Replace <vendor> unsubscribe / mailto hostnames with hanzo.ai in
  listunsubscribe.go and all marketing tests (raw_test, category_test,
  marketing_test, etc.)
- Rename seed<tenant> test fixture → seedDefault and switch its tenant
  literals from 'liquidity' to use DefaultBrand
- Replace 'liquidity' tenant literals in chain_test / chain_marketing_test
  / preferences_test / router_test / kmsbridge client_test with 'acme'
  (generic test tenant) — tests still cover the brand→default fallback
  semantics
- Drop github.com/<tenant>/* from GOPRIVATE in Dockerfile
- Drop <tenant>/operator + '<tenant>/bd#105' references from
  k8s/kustomization.yaml + pkg/types/types.go comments
- Replace 'LiquidReplicate sidecar' with generic 'replicator sidecar'
  in schema.go consent-log retention comment
- Rewrite LLM.md fleet-default KMS path examples to use brand/hanzo/*

Tests pass: tenant, marketing, preferences, kmsbridge, router.
2026-06-10 12:04:08 -07:00

88 lines
2.6 KiB
Go

package marketing
import (
"strings"
"testing"
"time"
"github.com/hanzoai/notify/internal/unsubscribe"
)
func TestBuildHeaders(t *testing.T) {
t.Parallel()
signer, err := unsubscribe.NewSigner("test-secret")
if err != nil {
t.Fatalf("NewSigner: %v", err)
}
cfg := Config{Env: "dev", Signer: signer}
now := time.Date(2026, 6, 3, 12, 0, 0, 0, time.UTC)
h, err := cfg.Build("u1", "promotional", now, unsubscribe.Default30Days)
if err != nil {
t.Fatalf("Build: %v", err)
}
if !strings.HasPrefix(h.URL, "https://notify.dev.hanzo.ai/v1/notify/unsubscribe/") {
t.Fatalf("unexpected URL host: %s", h.URL)
}
if !strings.Contains(h.ListUnsubscribe, "<"+h.URL+">") {
t.Fatalf("List-Unsubscribe missing HTTPS URL: %s", h.ListUnsubscribe)
}
if !strings.Contains(h.ListUnsubscribe, "mailto:unsubscribe+") {
t.Fatalf("List-Unsubscribe missing mailto: %s", h.ListUnsubscribe)
}
if h.ListUnsubscribePost != "List-Unsubscribe=One-Click" {
t.Fatalf("unexpected List-Unsubscribe-Post: %s", h.ListUnsubscribePost)
}
}
func TestBuildHeadersProdHost(t *testing.T) {
t.Parallel()
signer, _ := unsubscribe.NewSigner("k")
for _, env := range []string{"", "main", "prod", "production"} {
cfg := Config{Env: env, Signer: signer}
h, err := cfg.Build("u1", "", time.Now().UTC(), unsubscribe.Default30Days)
if err != nil {
t.Fatalf("Build(%q): %v", env, err)
}
if !strings.HasPrefix(h.URL, "https://notify.hanzo.ai/") {
t.Fatalf("env=%q: want notify.hanzo.ai host, got %s", env, h.URL)
}
}
}
func TestBuildHeadersTokenRoundTrip(t *testing.T) {
t.Parallel()
signer, _ := unsubscribe.NewSigner("k")
cfg := Config{Env: "test", Signer: signer}
now := time.Date(2026, 6, 3, 12, 0, 0, 0, time.UTC)
h, err := cfg.Build("user-42", "newsletter", now, time.Hour)
if err != nil {
t.Fatalf("Build: %v", err)
}
// Pull the token out of the URL and verify it.
tok := strings.TrimPrefix(h.URL, "https://notify.test.hanzo.ai/v1/notify/unsubscribe/")
p, err := signer.Verify(tok, now)
if err != nil {
t.Fatalf("Verify minted token: %v", err)
}
if p.UserID != "user-42" || p.Category != "newsletter" {
t.Fatalf("unexpected payload: %+v", p)
}
}
func TestBuildHeadersNilSigner(t *testing.T) {
t.Parallel()
cfg := Config{}
if _, err := cfg.Build("u1", "", time.Now().UTC(), time.Hour); err == nil {
t.Fatalf("nil signer should yield error")
}
}
func TestFooterLine(t *testing.T) {
t.Parallel()
h := Headers{URL: "https://notify.hanzo.ai/v1/notify/unsubscribe/abc"}
want := "Unsubscribe: https://notify.hanzo.ai/v1/notify/unsubscribe/abc"
if h.FooterLine() != want {
t.Fatalf("FooterLine = %q, want %q", h.FooterLine(), want)
}
}