Files
member-console/internal/server/operator_grants_page_gate_test.go
T
cgalo5758 88db730fcc Add dual licensing and SPDX headers
Introduce a commercial license option alongside AGPL-3.0-only, require a
CLA for contributors, and document the terms in COMMERCIAL.md and
NOTICE. Add a script to stamp SPDX headers on Go files and apply it
across the tree.
2026-09-06 02:29:42 -05:00

83 lines
2.8 KiB
Go

// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
package server_test
// DB-backed handler tests for the grants list's empty-state gate
// (ux-first-run 3.3): naming "no product has been published yet" when
// blocked, versus pointing at the per-organization issue flow once at
// least one product has been published but no grant has been issued.
//
// DB-backed via TEST_DATABASE_URL (shared testDB helper). Reuses
// cleanCatalogTables and gateGet (operator_product_create_gate_test.go) and
// otcHarness/newOtcHarness (operator_org_type_change_test.go), all in this
// same package.
import (
"context"
"net/http"
"strings"
"testing"
"git.coopcloud.tech/wiki-cafe/member-console/internal/billing"
"git.coopcloud.tech/wiki-cafe/member-console/internal/entitlements"
"github.com/google/uuid"
)
func TestGrantsPage_BlockedWhenNoPublishedProduct(t *testing.T) {
database := testDB(t)
cleanCatalogTables(t, database)
h := newOtcHarness(t, database, "grants-gate-blocked")
code, body := gateGet(t, h.ctx, h.handler.GetGrantsPage)
if code != http.StatusOK {
t.Fatalf("status = %d, body: %s", code, body)
}
if !strings.Contains(body, "no product has been published yet") {
t.Errorf("expected the blocked explanation naming the missing prerequisite, got:\n%s", body)
}
if !strings.Contains(body, `href="/operator/products"`) {
t.Errorf("expected a link to Products, got:\n%s", body)
}
}
func TestGrantsPage_EmptyPointsAtIssueFlowWhenProductPublished(t *testing.T) {
database := testDB(t)
cleanCatalogTables(t, database)
ctx := context.Background()
eq := entitlements.New(database)
bq := billing.New(database)
es, err := eq.CreateEntitlementSet(ctx, entitlements.CreateEntitlementSetParams{
Name: "grants-gate-set",
IsActive: true,
})
if err != nil {
t.Fatalf("create entitlement set: %v", err)
}
if _, err := bq.CreateProduct(ctx, billing.CreateProductParams{
Name: "Grants Gate Product",
IsActive: true,
IsPublic: true,
EntitlementSetID: uuid.NullUUID{UUID: uuid.MustParse(es.SetID), Valid: true},
LifecycleStatus: "published",
}); err != nil {
t.Fatalf("create product: %v", err)
}
h := newOtcHarness(t, database, "grants-gate-unblocked")
code, body := gateGet(t, h.ctx, h.handler.GetGrantsPage)
if code != http.StatusOK {
t.Fatalf("status = %d, body: %s", code, body)
}
if strings.Contains(body, "no product has been published yet") {
t.Errorf("must not render the blocked explanation once a product is published, got:\n%s", body)
}
if !strings.Contains(body, "issued from each organization's detail page") {
t.Errorf("expected the empty state to point at the issue flow, got:\n%s", body)
}
if !strings.Contains(body, "No grants issued yet.") {
t.Errorf("expected the empty-state headline, got:\n%s", body)
}
}