package user import ( "net/http" "strconv" "testing" "git.golem15.com/golem15/sm-user-plugin/classes" "git.golem15.com/golem15/summercms/modules/pact" ) // TestAPITokenRevokeEvent pins plan 08's token-specific MCP revocation // (C-IN-02, user side): DELETE /tokens/{id} fires exactly one revoked // subject event for the user carrying that TokenID, so only the sessions of // that token end. Postgres only: skipped under -short. func TestAPITokenRevokeEvent(t *testing.T) { if testing.Short() { t.Skip("Postgres") } env := newAdminEnv(t) spy := env.spySubjects() user := env.seedUser(t, "token-revoke", nil) _, kept := env.mintUserToken(t, user, "read") _, gone := env.mintUserToken(t, user, "read") spy.reset() env.expect(t, http.StatusOK, http.MethodDelete, "/_user/api/v1/tokens/"+strconv.FormatUint(uint64(gone.ID), 10), freshUserToken(t, user), nil) spy.mu.Lock() events := append([]pact.MCPSubjectChanged(nil), spy.events...) spy.mu.Unlock() want := pact.MCPSubjectChanged{Guard: classes.SubjectGuardUser, UserID: user.ID, Kind: pact.MCPSubjectRevoked, TokenID: gone.ID} if len(events) != 1 || events[0] != want { t.Fatalf("events = %+v, want exactly %+v", events, want) } if spy.hasEvent(pact.MCPSubjectChanged{Guard: classes.SubjectGuardUser, UserID: user.ID, Kind: pact.MCPSubjectRevoked, TokenID: kept.ID}) { t.Fatal("the kept token was revoked too") } }