summaryrefslogtreecommitdiff
path: root/internal/controlplane/queries_test.go
diff options
context:
space:
mode:
authorChia <Chia@93.nz>2026-08-06 09:29:41 +1200
committerChia <Chia@93.nz>2026-08-06 09:32:46 +1200
commit41e322c53d7b4b796eb377d0df9c29ecd10ba431 (patch)
treec730526150e55e39b822d5197e4a20318ecaa449 /internal/controlplane/queries_test.go
parenteadb2ffe85c43cf6fc741c9823cd28eedb4a844c (diff)
feat: complete commercial control plane, billing, auth, and model catalog
- add PostgreSQL control-plane persistence with Redis-degraded hot reload - implement prepaid balance, usage ledger, Stripe top-up and reconciliation - add registration, email verification, password reset, invitations and RBAC - support TOTP, Passkey MFA, device sessions, quotas and rate limits - add tenant billing profiles, audit logs and operational readiness checks - build authenticated admin console, Quickstart, Playground and usage analytics - add public model catalog with pricing, filtering and cost estimation - support OpenAI Responses providers and provider health failover - validate real upstream usage reporting and balance settlement
Diffstat (limited to 'internal/controlplane/queries_test.go')
-rw-r--r--internal/controlplane/queries_test.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/internal/controlplane/queries_test.go b/internal/controlplane/queries_test.go
new file mode 100644
index 0000000..4cd44b9
--- /dev/null
+++ b/internal/controlplane/queries_test.go
@@ -0,0 +1,80 @@
+package controlplane
+
+import (
+ "encoding/json"
+ "strings"
+ "testing"
+)
+
+func TestDeveloperModelsForFiltersScopeAndRedactsRouting(t *testing.T) {
+ models := []Model{
+ {ID: "public", PublicID: "acme/public", DisplayName: "Public", Enabled: true, Lifecycle: "active",
+ AllowedTenantIDs: nil, Routes: []Route{{Protocol: "openai", WireAPI: "responses", Enabled: true, ProviderEnabled: true, ProviderName: "secret-provider", UpstreamModel: "secret-model", Priority: 1, Weight: 100}}},
+ {ID: "tenant", PublicID: "acme/private", Enabled: true, Lifecycle: "active", AllowedTenantIDs: []string{"tenant-a"},
+ Routes: []Route{{Protocol: "anthropic", WireAPI: "messages", Enabled: true, ProviderEnabled: true}}},
+ {ID: "key", PublicID: "acme/key", Enabled: true, Lifecycle: "active", AllowedKeyIDs: []string{"key-a"},
+ Routes: []Route{{Protocol: "openai", Enabled: true, ProviderEnabled: true}}},
+ {ID: "retired", PublicID: "acme/retired", Enabled: true, Lifecycle: "retired", Routes: []Route{{Protocol: "openai", Enabled: true, ProviderEnabled: true}}},
+ {ID: "disabled", PublicID: "acme/disabled", Enabled: false, Lifecycle: "active", Routes: []Route{{Protocol: "openai", Enabled: true, ProviderEnabled: true}}},
+ {ID: "noroute", PublicID: "acme/noroute", Enabled: true, Lifecycle: "active", Routes: []Route{{Protocol: "openai", Enabled: false, ProviderEnabled: true}}},
+ {ID: "provider-off", PublicID: "acme/provider-off", Enabled: true, Lifecycle: "active", Routes: []Route{{Protocol: "openai", Enabled: true, ProviderEnabled: false}}},
+ }
+ got := developerModelsFor(models, "tenant-a", map[string]struct{}{"key-a": {}})
+ if len(got) != 3 {
+ t.Fatalf("developer model count = %d, want 3", len(got))
+ }
+ if got[0].PublicID != "acme/key" && got[1].PublicID != "acme/key" && got[2].PublicID != "acme/key" {
+ t.Fatal("key-allowlisted model was not included for an active tenant key")
+ }
+ for _, item := range got {
+ if len(item.SupportedWireAPIs) == 0 {
+ t.Fatalf("unexpected developer model: %+v", item)
+ }
+ if item.PublicID == "acme/public" && item.SupportedWireAPIs[0] != "responses" {
+ t.Fatalf("responses wire API was not preserved: %+v", item)
+ }
+ }
+ for _, item := range got {
+ if item.PublicID == "acme/private" && item.SupportedWireAPIs[0] != "messages" {
+ t.Fatalf("anthropic wire API was not preserved: %+v", item)
+ }
+ }
+ encoded, err := json.Marshal(got)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if strings.Contains(string(encoded), "secret-provider") || strings.Contains(string(encoded), "secret-model") || strings.Contains(string(encoded), "provider_id") {
+ t.Fatalf("developer model response leaked routing metadata: %s", encoded)
+ }
+}
+
+func TestDeveloperModelsForDoesNotExposeKeyRestrictedModelsWithoutTenantKey(t *testing.T) {
+ models := []Model{{ID: "key", PublicID: "key-only", Enabled: true, Lifecycle: "active", AllowedKeyIDs: []string{"key-a"}, Routes: []Route{{Protocol: "openai", Enabled: true, ProviderEnabled: true}}}}
+ if got := developerModelsFor(models, "tenant-a", map[string]struct{}{}); len(got) != 0 {
+ t.Fatalf("key-restricted models visible without a matching key: %+v", got)
+ }
+}
+
+func TestPublicModelsForOnlyExposesUnrestrictedCatalogData(t *testing.T) {
+ models := []Model{
+ {ID: "public", PublicID: "acme/public", DisplayName: "Public", Enabled: true, Lifecycle: "active",
+ Routes: []Route{{ProviderID: "provider-a", ProviderName: "internal provider", Protocol: "openai", WireAPI: "responses", UpstreamModel: "secret-model", Enabled: true, ProviderEnabled: true}}},
+ {ID: "tenant", PublicID: "acme/tenant", Enabled: true, Lifecycle: "active", AllowedTenantIDs: []string{"tenant-a"},
+ Routes: []Route{{ProviderID: "provider-a", Protocol: "openai", Enabled: true, ProviderEnabled: true}}},
+ {ID: "key", PublicID: "acme/key", Enabled: true, Lifecycle: "active", AllowedKeyIDs: []string{"key-a"},
+ Routes: []Route{{ProviderID: "provider-a", Protocol: "openai", Enabled: true, ProviderEnabled: true}}},
+ }
+ got := publicModelsFor(models)
+ if len(got) != 1 || got[0].PublicID != "acme/public" || got[0].ProviderCount != 1 || got[0].SupportedWireAPIs[0] != "responses" {
+ t.Fatalf("unexpected public catalog: %+v", got)
+ }
+ encoded, err := json.Marshal(got)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, forbidden := range []string{"secret-model", "internal provider", "provider_id", "upstream_model", "allowed_tenant"} {
+ if strings.Contains(string(encoded), forbidden) {
+ t.Fatalf("public catalog leaked %q: %s", forbidden, encoded)
+ }
+ }
+}