From 41e322c53d7b4b796eb377d0df9c29ecd10ba431 Mon Sep 17 00:00:00 2001 From: Chia Date: Thu, 6 Aug 2026 09:29:41 +1200 Subject: 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 --- internal/config/config_test.go | 94 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) (limited to 'internal/config/config_test.go') diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 8e2e9bb..bb3e814 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -27,11 +27,59 @@ func TestLoadAppliesDefaultsAndResolvesSecrets(t *testing.T) { if cfg.Providers[0].BaseURL != "https://example.com/v1" { t.Fatal("provider URL was not resolved") } + if cfg.Providers[0].WireAPI != "chat_completions" { + t.Fatalf("default wire API = %q", cfg.Providers[0].WireAPI) + } + if cfg.Providers[0].Slug != "primary" { + t.Fatalf("default provider slug = %q", cfg.Providers[0].Slug) + } if cfg.Models[0].Routes[0].Weight != 1 { t.Fatalf("expected default route weight 1, got %d", cfg.Models[0].Routes[0].Weight) } } +func TestLoadValidatesPublicProviderSlugs(t *testing.T) { + t.Setenv("TEST_UPSTREAM_KEY", "secret") + t.Setenv("TEST_UPSTREAM_URL", "https://example.com") + for _, providers := range []string{ + `[{"id":"primary","slug":"Not Valid","protocol":"openai","base_url_env":"TEST_UPSTREAM_URL","api_key_env":"TEST_UPSTREAM_KEY"}]`, + `[{"id":"one","slug":"shared-provider","protocol":"openai","base_url_env":"TEST_UPSTREAM_URL","api_key_env":"TEST_UPSTREAM_KEY"},{"id":"two","slug":"shared-provider","protocol":"openai","base_url_env":"TEST_UPSTREAM_URL","api_key_env":"TEST_UPSTREAM_KEY"}]`, + } { + path := writeConfig(t, `{"providers":`+providers+`,"models":[{"id":"example/model","routes":[{"provider":"primary","upstream_model":"model"}]}]}`) + if _, err := Load(path); err == nil { + t.Fatalf("expected invalid provider slugs to be rejected: %s", providers) + } + } +} + +func TestLoadAcceptsOpenAIResponsesWireAPI(t *testing.T) { + t.Setenv("TEST_UPSTREAM_KEY", "secret") + t.Setenv("TEST_UPSTREAM_URL", "https://example.com") + path := writeConfig(t, `{ + "providers": [{"id":"responses","protocol":"openai","wire_api":"responses","base_url_env":"TEST_UPSTREAM_URL","api_key_env":"TEST_UPSTREAM_KEY"}], + "models": [{"id":"example/model","routes":[{"provider":"responses","upstream_model":"gpt-example"}]}] +}`) + cfg, err := Load(path) + if err != nil { + t.Fatal(err) + } + if cfg.Providers[0].WireAPI != "responses" { + t.Fatalf("wire API = %q", cfg.Providers[0].WireAPI) + } +} + +func TestLoadRejectsIncompatibleWireAPI(t *testing.T) { + t.Setenv("TEST_UPSTREAM_KEY", "secret") + t.Setenv("TEST_UPSTREAM_URL", "https://example.com") + path := writeConfig(t, `{ + "providers": [{"id":"bad","protocol":"anthropic","wire_api":"responses","base_url_env":"TEST_UPSTREAM_URL","api_key_env":"TEST_UPSTREAM_KEY"}], + "models": [{"id":"example/model","routes":[{"provider":"bad","upstream_model":"model"}]}] +}`) + if _, err := Load(path); err == nil { + t.Fatal("expected incompatible wire API to be rejected") + } +} + func TestLoadRejectsUnknownFieldsAndTrailingData(t *testing.T) { t.Setenv("TEST_UPSTREAM_KEY", "secret") unknown := writeConfig(t, `{"unknown":true}`) @@ -63,6 +111,7 @@ func TestLoadControlPlaneModeWithoutStaticRoutes(t *testing.T) { t.Setenv("AIGW_CREDENTIAL_KEY", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") t.Setenv("AIGW_ADMIN_TOKEN", "admin-secret") t.Setenv("AIGW_PUBLIC_URL", "http://localhost:8080/admin/") + t.Setenv("AIGW_INFERENCE_PUBLIC_URL", "https://api.example.test") path := writeConfig(t, `{ "control_plane": {"enabled":true}, "admin": {"enabled":true} @@ -78,6 +127,24 @@ func TestLoadControlPlaneModeWithoutStaticRoutes(t *testing.T) { if len(cfg.Providers) != 0 || len(cfg.Models) != 0 { t.Fatal("control-plane mode unexpectedly requires static providers or models") } + if cfg.Admin.InferencePublicURL != "https://api.example.test" { + t.Fatalf("inference public URL = %q", cfg.Admin.InferencePublicURL) + } +} + +func TestLoadDerivesInferenceURLFromConsoleOrigin(t *testing.T) { + t.Setenv("AIGW_DATABASE_URL", "postgres://aigw:aigw@postgres/aigw") + t.Setenv("AIGW_CREDENTIAL_KEY", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") + t.Setenv("AIGW_ADMIN_TOKEN", "admin-secret") + t.Setenv("AIGW_PUBLIC_URL", "https://console.example.test/admin/") + path := writeConfig(t, `{"control_plane":{"enabled":true},"admin":{"enabled":true}}`) + cfg, err := Load(path) + if err != nil { + t.Fatal(err) + } + if cfg.Admin.InferencePublicURL != "https://console.example.test" { + t.Fatalf("derived inference URL = %q", cfg.Admin.InferencePublicURL) + } } func TestLoadControlPlaneModeWithoutRedis(t *testing.T) { @@ -128,6 +195,25 @@ func TestLoadResolvesStripeSecrets(t *testing.T) { } } +func TestLoadCanDisableStripeFromEnvironmentWithoutCredentials(t *testing.T) { + t.Setenv("AIGW_DATABASE_URL", "postgres://aigw:aigw@postgres/aigw") + t.Setenv("AIGW_CREDENTIAL_KEY", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") + t.Setenv("AIGW_SETTLEMENT_SPOOL_PATH", filepath.Join(t.TempDir(), "settlements.jsonl")) + t.Setenv("TEST_STRIPE_ENABLED", "false") + path := writeConfig(t, `{ + "control_plane":{"enabled":true}, + "billing":{"enabled":true,"currency":"usd","default_max_output_tokens":1024,"min_top_up_minor":500,"max_top_up_minor":1000000, + "stripe":{"enabled_env":"TEST_STRIPE_ENABLED"}} +}`) + cfg, err := Load(path) + if err != nil { + t.Fatal(err) + } + if cfg.Billing.Stripe.Enabled || cfg.Billing.Stripe.APIKey != "" { + t.Fatalf("Stripe should be disabled without credentials: %+v", cfg.Billing.Stripe) + } +} + func TestLoadRejectsEmptyExternalServiceEnvironment(t *testing.T) { t.Setenv("TEST_UPSTREAM_KEY", "secret") t.Setenv("TEST_UPSTREAM_URL", "") @@ -165,6 +251,13 @@ func TestVersionedExamplesResolveExternalServicesFromEnvironment(t *testing.T) { if staticConfig.Providers[0].BaseURL != "https://openai.example.test/v1" { t.Fatalf("static provider URL = %q", staticConfig.Providers[0].BaseURL) } + responsesConfig, err := Load(filepath.Join("..", "..", "config.responses.example.json")) + if err != nil { + t.Fatalf("load Responses example: %v", err) + } + if len(responsesConfig.Providers) != 1 || responsesConfig.Providers[0].WireAPI != "responses" { + t.Fatalf("Responses example provider = %+v", responsesConfig.Providers) + } t.Setenv("AIGW_DATABASE_URL", "postgres://example:secret@postgres.example.test/aigw") t.Setenv("AIGW_REDIS_URL", "redis://redis.example.test:6379/0") @@ -178,6 +271,7 @@ func TestVersionedExamplesResolveExternalServicesFromEnvironment(t *testing.T) { t.Setenv("AIGW_WEBAUTHN_RP_ID", "console.example.test") t.Setenv("AIGW_WEBAUTHN_ORIGINS", "https://console.example.test") t.Setenv("AIGW_STRIPE_API_KEY", "rk_test_example") + t.Setenv("AIGW_STRIPE_ENABLED", "true") t.Setenv("AIGW_STRIPE_WEBHOOK_SECRET", "whsec_example") t.Setenv("AIGW_STRIPE_SUCCESS_URL", "https://console.example.test/admin/?topup=success") t.Setenv("AIGW_STRIPE_CANCEL_URL", "https://console.example.test/admin/?topup=cancel") -- cgit v1.2.3