Files
summercms/modules/cabana/account_token_events_test.go
Jakub Zych ccf77b9103 test(19.7-09): named tests for every framework and admin SPA fix of plans 06 and 07
- pier: TestSessionReserve (A-WR-03), TestLockScope (A-WR-07),
  TestScopeWidening (A-WR-04), TestStatelessFanOut (A-WR-05, A-WR-06),
  TestPersonalTokenBinding (A-WR-09), TestDispatchHardening (A-WR-01,
  A-WR-02, A-WR-08, A-IN-04, A-IN-05, A-IN-08), TestCatalogPathFields
  (A-WR-02, A-IN-07), TestPromptWriteCeiling (C-IN-01),
  TestTokenScopedRevoke (B-WR-04, C-IN-02), TestResolveClientAddress
  (B-IN-04); test seam WrapStore
- pact TestFrontendTokenScopes, towel TestClientIP, cabana
  TestTokenScopeNameParity
- cabana TestAccountContributionURL (B-WR-03), TestAccountContributionsIsolation
  (B-WR-06, B-IN-03), TestRecordActionPromptLocalized (B-IN-02), and the
  Postgres TestAccountTokenRevokeEvent (B-WR-04) and
  TestResolveBackendTokenRemote (B-IN-04)
- vitest: hotkeysEditing.test.ts (B-WR-01, B-WR-02) and the extended
  AccountContributions.test.ts (B-WR-03, B-WR-06, B-IN-01)
- check-phase19.7.sh requires every name (GO_TESTS, GO_TAGGED_TESTS,
  DOCKER_TESTS, ADMIN_FILES) and scans the new files (PHASE_TEST_FILES)
2026-10-23 18:36:16 +02:00

62 lines
2.0 KiB
Go

package cabana_test
import (
"context"
"encoding/json"
"net/http"
"strconv"
"sync"
"testing"
"git.golem15.com/golem15/summercms/modules/cabana"
"git.golem15.com/golem15/summercms/modules/pact"
)
// TestAccountTokenRevokeEvent pins plan 07's token-specific revocation
// (B-WR-04): revoking one g15_ token from My account fires exactly one
// revoked subject event for the admin, after the commit, whose TokenID is
// the revoked row's id, and no event for the admin as a whole (their other
// tokens and OAuth sessions stay). Postgres only: under -short nothing runs.
func TestAccountTokenRevokeEvent(t *testing.T) {
if testing.Short() {
return
}
t.Run("one revoked event with the token id", func(t *testing.T) {
env := newScreensEnv(t)
var mu sync.Mutex
var got []pact.MCPSubjectChanged
env.app.Events.Listen("test.revoke", func(_ context.Context, ev *pact.MCPSubjectChanged) error {
mu.Lock()
got = append(got, *ev)
mu.Unlock()
return nil
})
admin, jwt := env.admin(t, env.unique("revoke"), true, "")
ids := make([]uint, 2)
for i := range ids {
out := env.expect(t, http.StatusCreated, http.MethodPost, "/account/tokens", jwt, map[string]any{
"name": env.unique("agent"), "expires": "90d", "scopes": []string{"*"},
})
raw, _ := json.Marshal(out["data"])
var created cabana.AdminAPITokenCreated
if err := json.Unmarshal(raw, &created); err != nil || created.ID == 0 {
t.Fatalf("created token = %s (%v)", raw, err)
}
ids[i] = created.ID
}
mu.Lock()
got = nil
mu.Unlock()
env.expect(t, http.StatusOK, http.MethodDelete, "/account/tokens/"+strconv.FormatUint(uint64(ids[0]), 10), jwt, map[string]any{})
mu.Lock()
defer mu.Unlock()
if len(got) != 1 {
t.Fatalf("revoking one token fired %d events, want 1: %+v", len(got), got)
}
ev := got[0]
if ev.Kind != pact.MCPSubjectRevoked || ev.Guard != "backend" || ev.UserID != admin.ID || ev.TokenID != ids[0] || ev.ClientID != "" {
t.Fatalf("event = %+v, want revoked backend %d with token %d", ev, admin.ID, ids[0])
}
})
}