package server import ( "encoding/json" "net/http" "net/http/httptest" "path/filepath" "testing" ) func TestHandleBillingCatalogReturnsSeededPlans(t *testing.T) { server, err := NewWithConfig(Config{ SQLitePath: filepath.Join(t.TempDir(), "popiart.db"), SkillhubDir: makeEmptySkillhub(t), SessionSecret: "test-secret", }) if err != nil { t.Fatalf("NewWithConfig: %v", err) } req := httptest.NewRequest(http.MethodGet, "/v1/billing/catalog", nil) rec := httptest.NewRecorder() server.Handler().ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String()) } var resp struct { OK bool `json:"ok"` Data struct { Plans []billingPlan `json:"plans"` } `json:"data"` } if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { t.Fatalf("decode response: %v", err) } if !resp.OK { t.Fatalf("expected ok response, got %s", rec.Body.String()) } if len(resp.Data.Plans) != 2 { t.Fatalf("expected 2 plans, got %d", len(resp.Data.Plans)) } if resp.Data.Plans[0].ProductType != "subscription" { t.Fatalf("expected first plan to be subscription, got %#v", resp.Data.Plans[0]) } } func TestHandleBillingSubscriptionReturnsUnbound(t *testing.T) { server, err := NewWithConfig(Config{ SQLitePath: filepath.Join(t.TempDir(), "popiart.db"), SkillhubDir: makeEmptySkillhub(t), SessionSecret: "test-secret", }) if err != nil { t.Fatalf("NewWithConfig: %v", err) } sessionToken, _, ok, err := server.store.createSession("sk-billing-user") if err != nil { t.Fatalf("createSession: %v", err) } if !ok { t.Fatal("expected session creation to succeed") } req := httptest.NewRequest(http.MethodGet, "/v1/billing/subscription", nil) req.Header.Set("Authorization", "Bearer "+sessionToken) rec := httptest.NewRecorder() server.Handler().ServeHTTP(rec, req) if rec.Code != http.StatusPreconditionFailed { t.Fatalf("expected 412, got %d: %s", rec.Code, rec.Body.String()) } var resp struct { OK bool `json:"ok"` Error struct { Code string `json:"code"` } `json:"error"` } if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { t.Fatalf("decode error response: %v", err) } if resp.OK { t.Fatalf("expected error response, got %s", rec.Body.String()) } if resp.Error.Code != "BILLING_UNBOUND" { t.Fatalf("expected BILLING_UNBOUND, got %q", resp.Error.Code) } }