Files
member-console/internal/server/operator_grants_delivery_state_test.go
T
cgalo5758 8e3c68c6be Make UI surfaces honestly reflect system state
- Add deployment-name branding to titles, mastheads, and OG tags
- Share one grant delivery-state query with lineage across grants
  surfaces
- Show pool status/usage, org owners, and config readiness
- Make billing views projection-aware with recency and sync vocabulary
- Guard FedWiki creation without domains and render route-aware 404s
2026-08-23 01:45:52 -05:00

147 lines
6.4 KiB
Go

package server_test
// DB-backed integration coverage for the shared ListGrantsWithDelivery query
// (ux-honest-surfaces design decision 1) end to end: real IssueGrant / Extend
// / Revoke flows against a real Postgres, read back through both the
// org-detail composite and the grants index, asserting the two surfaces
// agree on delivery-state wording and that supersession lineage is visible.
//
// Also locks in the derivation's precise "superseded" boundary: a grant
// whose provision simply ended with no recorded successor (a plain revoke)
// renders "Inactive", not "Superseded" -- "Superseded" is reserved for the
// case a replacing grant is actually on record (extends_grant_id), because
// the UI must be able to name what replaced a superseded row.
import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
)
// postOrg posts to a handler with only {orgID} set (Issue Grant's form has
// no pool-scoped path parameter). Success/error copy fires as an HX-Trigger
// toast (fireSuccessToast/fireErrorToast), not inline body text -- callers
// assert against the returned trigger header, mirroring postOrgPool.
func (h *otcHarness) postOrg(handler http.HandlerFunc, orgID string, form url.Values) (int, string, string) {
h.t.Helper()
req := httptest.NewRequestWithContext(h.ctx, http.MethodPost, "/", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetPathValue("orgID", orgID)
rec := httptest.NewRecorder()
handler(rec, req)
return rec.Code, rec.Body.String(), rec.Header().Get("HX-Trigger")
}
// postGrant posts to a handler with {grantID} set (Revoke).
func (h *otcHarness) postGrant(handler http.HandlerFunc, grantID string, form url.Values) (int, string, string) {
h.t.Helper()
req := httptest.NewRequestWithContext(h.ctx, http.MethodPost, "/", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.SetPathValue("grantID", grantID)
rec := httptest.NewRecorder()
handler(rec, req)
return rec.Code, rec.Body.String(), rec.Header().Get("HX-Trigger")
}
// getOrg issues a GET against a handler with {orgID} set.
func (h *otcHarness) getOrg(handler http.HandlerFunc, orgID string) (int, string) {
h.t.Helper()
req := httptest.NewRequestWithContext(h.ctx, http.MethodGet, "/", nil)
req.SetPathValue("orgID", orgID)
rec := httptest.NewRecorder()
handler(rec, req)
return rec.Code, rec.Body.String()
}
func TestGrantDeliveryState_EndToEnd(t *testing.T) {
database := testDB(t)
f := newOtcFixture(t, database)
h := newOtcHarness(t, database, f.operatorID)
org, pool := otcOrg(t, database, f, "Delivery State Org", true)
// Issue on ladder A's product: creates a live grant with no lineage.
code, body, trigger := h.postOrg(h.handler.IssueGrant, org, url.Values{
"product_id": {f.prodA}, "reason": {"manual"}, "quantity": {"1"},
})
if code != http.StatusOK || !strings.Contains(trigger, "issued") {
t.Fatalf("issue grant A: status=%d trigger=%q body=%s", code, trigger, body)
}
// Issue on ladder B's product too: this one gets revoked with no
// successor, so it must land on "Inactive", not "Superseded".
code, body, trigger = h.postOrg(h.handler.IssueGrant, org, url.Values{
"product_id": {f.prodB}, "reason": {"manual"}, "quantity": {"1"},
})
if code != http.StatusOK || !strings.Contains(trigger, "issued") {
t.Fatalf("issue grant B: status=%d trigger=%q body=%s", code, trigger, body)
}
grantA := otcScalar(t, database, `SELECT count(*) FROM core.grants WHERE granted_to_org_id = $1 AND product_id = $2`, org, f.prodA)
if grantA != 1 {
t.Fatalf("expected exactly one grant for product A, found %d", grantA)
}
var grantBID string
if err := database.QueryRow(`SELECT grant_id FROM core.grants WHERE granted_to_org_id = $1 AND product_id = $2`, org, f.prodB).Scan(&grantBID); err != nil {
t.Fatalf("resolve grant B id: %v", err)
}
// Extend A's delivery: the handler resolves the pool's active
// grant-backed provision (A) and issues+confers a replacement, which
// must supersede A's position and mark A "Superseded" / the new grant
// "Live", with lineage naming each other.
code, body, trigger = h.postOrgPool(h.handler.ExtendGrant, org, pool, url.Values{"reason": {"extend test"}})
if code != http.StatusOK || !strings.Contains(trigger, "extended") {
t.Fatalf("extend grant A: status=%d trigger=%q body=%s", code, trigger, body)
}
// Revoke B with no successor.
code, body, trigger = h.postGrant(h.handler.RevokeGrantAndTransition, grantBID, url.Values{"org_id": {org}})
if code != http.StatusOK || !strings.Contains(trigger, "revoked") {
t.Fatalf("revoke grant B: status=%d trigger=%q body=%s", code, trigger, body)
}
// Org-detail composite: A is Superseded with a named replacement, the
// new grant is Live and names A as what it extends, and B is Inactive
// with no "replaced by" (it was revoked outright, no successor).
code, orgBody := h.getOrg(h.handler.GetOrgEnrollment, org)
if code != http.StatusOK {
t.Fatalf("get org enrollment: status=%d body=%s", code, orgBody)
}
assertDeliveryRendering(t, "org-detail", orgBody)
// Grants index: same derivation, same wording -- design decision 1
// ("one query, two consumers") means these two reads must agree.
req := httptest.NewRequestWithContext(h.ctx, http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
h.handler.GetGrantsPage(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("get grants page: status=%d body=%s", rec.Code, rec.Body.String())
}
assertDeliveryRendering(t, "grants index", rec.Body.String())
}
// assertDeliveryRendering checks the delivery-state vocabulary and
// supersession lineage shared between the org-detail composite and the
// grants index (ux-honest-surfaces UX-3).
func assertDeliveryRendering(t *testing.T, surface, body string) {
t.Helper()
if !strings.Contains(body, ">Live<") {
t.Errorf("%s: expected a Live delivery badge, got:\n%s", surface, body)
}
if !strings.Contains(body, ">Superseded<") {
t.Errorf("%s: expected a Superseded delivery badge, got:\n%s", surface, body)
}
if !strings.Contains(body, ">Inactive<") {
t.Errorf("%s: expected an Inactive delivery badge (the plain revoke with no successor), got:\n%s", surface, body)
}
if !strings.Contains(body, "replaced by") {
t.Errorf("%s: expected the superseded grant to name its replacement, got:\n%s", surface, body)
}
if !strings.Contains(body, "extends") {
t.Errorf("%s: expected the replacing grant to name what it extends, got:\n%s", surface, body)
}
}