package token_test import "testing" // 说明: // 1. 本文件保留完整 TOK-LIFE 模板清单作为覆盖基线。 // 2. 首批可执行用例已在 lifecycle_executable_test.go 落地: // TOK-LIFE-001 / TOK-LIFE-004 / TOK-LIFE-005 / TOK-LIFE-008。 type lifecycleTemplateCase struct { ID string Name string Preconditions []string Steps []string Assertions []string } func TestTokenLifecycleTemplateCases(t *testing.T) { t.Parallel() cases := []lifecycleTemplateCase{ { ID: "TOK-LIFE-001", Name: "签发成功", Preconditions: []string{ "tenant_id=1001", "subject_owner=2001", }, Steps: []string{ "调用 POST /api/v1/platform/tokens/issue", "记录 token_id/issued_at/expires_at/status", }, Assertions: []string{ "status=active", "expires_at>issued_at", "token_id 唯一", }, }, { ID: "TOK-LIFE-002", Name: "签发参数非法", Preconditions: []string{ "ttl_seconds 超上限", }, Steps: []string{ "调用 POST /api/v1/platform/tokens/issue", }, Assertions: []string{ "返回 400", "不落 active token", }, }, { ID: "TOK-LIFE-003", Name: "幂等签发重放", Steps: []string{ "相同 Idempotency-Key 重复调用签发接口", }, Assertions: []string{ "返回同一 token_id", "无重复写入", }, }, { ID: "TOK-LIFE-004", Name: "续期成功", Steps: []string{ "调用 POST /api/v1/platform/tokens/{tokenId}/refresh", }, Assertions: []string{ "expires_at 延后", "status=active", }, }, { ID: "TOK-LIFE-005", Name: "吊销成功", Steps: []string{ "调用 POST /api/v1/platform/tokens/{tokenId}/revoke", "立即调用 introspect 查询状态", }, Assertions: []string{ "status 最终为 revoked", "吊销生效延迟 <=5s", }, }, { ID: "TOK-LIFE-006", Name: "吊销后访问受限接口", Steps: []string{ "使用已吊销 token 访问受保护接口", }, Assertions: []string{ "返回 401 AUTH_TOKEN_INACTIVE", }, }, { ID: "TOK-LIFE-007", Name: "过期自动失效", Steps: []string{ "签发短 TTL token", "等待 token 过期", "调用 introspect 查询状态", }, Assertions: []string{ "status=expired", "返回不可用错误", }, }, { ID: "TOK-LIFE-008", Name: "viewer 越权写操作", Preconditions: []string{ "viewer scope=supply:read", }, Steps: []string{ "viewer token 调用写接口", }, Assertions: []string{ "返回 403 AUTH_SCOPE_DENIED", "无写入副作用", }, }, } for _, tc := range cases { tc := tc t.Run(tc.ID, func(t *testing.T) { t.Skipf("模板用例,待接入实现: %s", tc.Name) }) } }