| index 9cf52a5d1..fc96b90f1 100644 |
| --- a/internal/domains/aliases_test.go |
| +++ b/internal/domains/aliases_test.go |
| @@ -3,6 +3,7 @@ package domains |
| import ( |
| "context" |
| "encoding/json" |
| + "fmt" |
| "path/filepath" |
| "strings" |
| "testing" |
| @@ -324,6 +325,76 @@ func TestReconcileDerivesWildcardState(t *testing.T) { |
| } |
| } |
| |
| +func TestReconcileWildcardHostCollisionMismatchedTenant(t *testing.T) { |
| + // A named-Route wildcard claim whose own Host is itself a REAL local |
| + // route owned by a DIFFERENT tenant: the wildcard row (and any |
| + // catch-all) must be refused, same spirit as the plain-alias half |
| + // already refusing to shadow a real route. The claim's Route names a |
| + // primary that DOES belong to the claim's own tenant, so the |
| + // primary-tenancy check alone would pass — the collision on c.Host |
| + // itself is the only gate that can catch this case. |
| + ctx := context.Background() |
| + s := release.NewDirStore(t.TempDir()) |
| + reg := aliasRegWith(t) |
| + addRoute(t, reg, "primary.bab.oncarlos.com", "bab", "appA") |
| + addRoute(t, reg, "hostx.example", "bad", "appB") // real route, different tenant |
| + |
| + putClaim(t, s, Claim{Host: "hostx.example", Account: "bab", App: "appA", |
| + Route: "primary.bab.oncarlos.com", CreatedAt: "2026-08-13T00:00:00Z", |
| + Wildcard: true, Catchall: true}) |
| + |
| + if err := ReconcileAliases(ctx, s, reg, func() time.Time { return time.Unix(1000, 0) }); err != nil { |
| + t.Fatal(err) |
| + } |
| + wds, err := reg.ListWildcardDomains() |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + if len(wds) != 0 { |
| + t.Fatalf("wildcard_domains = %+v, want none (real route under a different tenant owns the host)", wds) |
| + } |
| + aliases, err := reg.ListAliases() |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + for _, a := range aliases { |
| + if strings.HasPrefix(a.Alias, "*.") { |
| + t.Fatalf("no catch-all should derive from a refused wildcard claim: %+v", a) |
| + } |
| + } |
| +} |
| + |
| +func TestReconcileWildcardCap(t *testing.T) { |
| + ctx := context.Background() |
| + s := release.NewDirStore(t.TempDir()) |
| + reg := aliasRegWith(t) |
| + addRoute(t, reg, "primary.bab.oncarlos.com", "bab", "appA") |
| + |
| + // 33 valid wildcard claims sharing one local primary, with deterministic |
| + // zero-padded hosts so bucket-list (lexicographic) order matches numeric |
| + // order: w00.example .. w32.example. |
| + for i := 0; i < 33; i++ { |
| + putClaim(t, s, Claim{Host: fmt.Sprintf("w%02d.example", i), Account: "bab", App: "appA", |
| + Route: "primary.bab.oncarlos.com", CreatedAt: "2026-08-13T00:00:00Z", Wildcard: true}) |
| + } |
| + |
| + if err := ReconcileAliases(ctx, s, reg, func() time.Time { return time.Unix(1000, 0) }); err != nil { |
| + t.Fatal(err) |
| + } |
| + wds, err := reg.ListWildcardDomains() |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + if len(wds) != 32 { |
| + t.Fatalf("got %d wildcard_domains, want 32 (per-box cap): %+v", len(wds), wds) |
| + } |
| + for _, w := range wds { |
| + if w.Host == "w32.example" { |
| + t.Fatalf("w32.example (33rd claim, lexicographically last) should have been dropped over the cap: %+v", wds) |
| + } |
| + } |
| +} |
| + |
| func TestReconcileWildcardEmptyRouteClaim(t *testing.T) { |
| // First-route claim (#82's shape): empty Route, the claim's own host IS |
| // the primary once materialized. Catchall aliases that primary. |