mirror of
https://github.com/hanzoai/notify.git
synced 2026-10-30 15:04:32 +00:00
- 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.
88 lines
2.6 KiB
Go
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)
|
|
}
|
|
}
|