fix: preserve billing response shape

This commit is contained in:
brother7 committed 2026-08-17 11:28:08 +08:00
1 parent 600cba023c
commit 2ef3da7af5
7 files changed
+488 -6

No files matched your search

+58
View File
@@ -28,6 +28,15 @@ func TestBillingMemberRoutesUseRefreshedSessionScope(t *testing.T) {
}
}
func TestBillingOverviewResponsesEncodeEmptyCollectionsAsArrays(t *testing.T) {
service := billing.NewService(&emptyBillingStore{}, nil)
member := billingTestHandler(t, identity.Session{AuthMode: identity.AuthModeUser, User: identity.User{ID: "user", ClientID: "platform", OrganizationID: "org", Role: "user"}}, service, nil)
admin := billingTestHandler(t, identity.Session{AuthMode: identity.AuthModeAdmin, User: identity.User{ID: "root", ClientID: "platform", Role: "super_admin"}}, service, nil)
assertJSONArrays(t, serveJSON(t, member, http.MethodGet, "/api/billing", nil), "ledger")
assertJSONArrays(t, serveJSON(t, admin, http.MethodGet, "/api/admin/billing", nil), "organizations", "members", "ledger", "priceRules")
}
func TestBillingQuotePreparesProviderAndModelFromServerOwnedEngineTargets(t *testing.T) {
service := &billingHTTPServiceStub{}
h := billingTestHandler(t, identity.Session{User: identity.User{ID: "db-user", ClientID: "platform", OrganizationID: "db-org", Role: "user"}}, service, nil)
@@ -165,6 +174,39 @@ func (s *billingAccountStoreStub) Save(_ context.Context, value billing.AccountC
return nil
}
type emptyBillingStore struct{}
func (*emptyBillingStore) BillingWallet(context.Context, string) (billing.Wallet, error) {
return billing.Wallet{}, nil
}
func (*emptyBillingStore) BillingWallets(context.Context) ([]billing.Wallet, error) {
return nil, nil
}
func (*emptyBillingStore) BillingLedger(context.Context, string, string, int) ([]billing.LedgerEntry, error) {
return nil, nil
}
func (*emptyBillingStore) BillingOrganizations(context.Context) ([]billing.Organization, error) {
return nil, nil
}
func (*emptyBillingStore) BillingMembers(context.Context) ([]billing.Member, error) {
return nil, nil
}
func (*emptyBillingStore) BillingOrganizationExists(context.Context, string) (bool, error) {
return false, nil
}
func (*emptyBillingStore) ListBillingPriceRules(context.Context, bool) ([]billing.PriceRule, error) {
return nil, nil
}
func (*emptyBillingStore) GetBillingPriceRule(context.Context, string) (*billing.PriceRule, error) {
return nil, nil
}
func (*emptyBillingStore) UpdateBillingPriceRule(context.Context, string, billing.PricePatch) (*billing.PriceRule, error) {
return nil, nil
}
func (*emptyBillingStore) PostBillingWalletEntry(context.Context, billing.WalletPostParams) (billing.WalletPosting, error) {
return billing.WalletPosting{}, nil
}
func billingTestHandler(t *testing.T, session identity.Session, service BillingHTTPService, accounts BillingAccountStore) http.Handler {
t.Helper()
authorizer, err := NewPlatformAuthorizer(AuthState{Required: true, Configured: true}, &fixedSessionResolver{session: session})
@@ -192,3 +234,19 @@ func serveJSON(t *testing.T, h http.Handler, method, path string, body any) *htt
h.ServeHTTP(response, req)
return response
}
func assertJSONArrays(t *testing.T, response *httptest.ResponseRecorder, fields ...string) {
t.Helper()
if response.Code != http.StatusOK {
t.Fatalf("status=%d body=%s", response.Code, response.Body.String())
}
var payload map[string]json.RawMessage
if err := json.Unmarshal(response.Body.Bytes(), &payload); err != nil {
t.Fatalf("decode response: %v", err)
}
for _, field := range fields {
if string(payload[field]) != "[]" {
t.Errorf("%s = %s, want [] (body=%s)", field, payload[field], response.Body.String())
}
}
}