test(fba): preserve verified fleet and fulfillment acceptance workflows

This commit is contained in:
2026-10-03 06:26:33 +08:00
parent c55bd7f4b6
commit d858357c5d
52 changed files with 4217 additions and 103 deletions
+27 -2
View File
@@ -1,5 +1,23 @@
function id(value) { return value == null ? '' : String(value) }
export async function verifyRevokedSessions(context, reason, sessions, accessPath = '/api/platform/v1/orders/status') {
const options = { scenario: 'unified-session-revocation', deploymentBlocker: true }
for (const [index, session] of sessions.entries()) {
const complete = Boolean(session?.accessToken && session?.refreshToken)
context.assert('system', `${reason}第${index + 1}组会话凭据完整`, null, complete,
`session=${index + 1}`, options)
if (!complete) throw new Error('会话撤销检查缺少完整 Access/Refresh 对')
const access = await context.request('GET', accessPath, undefined, session.accessToken)
context.assert('system', `${reason}旧Access失效`, access,
access.http === 401 && String(access.body?.code) === 'A0401',
`session=${index + 1}, HTTP=${access.http}, code=${access.body?.code || 'missing'}`, options)
const refresh = await context.request('POST', '/api/auth/refresh', { refreshToken: session.refreshToken }, '')
context.assert('system', `${reason}旧Refresh不能恢复会话`, refresh,
[200, 401].includes(refresh.http) && String(refresh.body?.code) === 'A0401',
`session=${index + 1}, HTTP=${refresh.http}, code=${refresh.body?.code || 'missing'}`, options)
}
}
export async function run(context) {
const module = 'system'
const suffix = context.marker.replace(/\D/g, '').slice(-12)
@@ -140,9 +158,12 @@ export async function run(context) {
const loginResponse = await context.request('POST', '/api/auth/login', { loginId: username, password: initialPassword }, '')
const loginPassed = loginResponse.http === 200 && String(loginResponse.body?.code) === '200' && Boolean(loginResponse.body?.data?.accessToken)
context.addStep(module, '新建内部用户可使用初始密码登录', loginResponse, loginPassed, `username=${username}`)
const secondLoginResponse = await context.request('POST', '/api/auth/login', { loginId: username, password: initialPassword }, '')
const secondLogin = context.apiSuccess(module, '建立同账号第二个独立会话', secondLoginResponse)
const resetResponse = await context.request('PUT', `/api/platform/v1/iam/users/${membershipId}/password`, { newPassword: resetPassword })
context.apiSuccess(module, '重置平台内部用户密码', resetResponse)
await verifyRevokedSessions(context, '密码重置撤销多端会话', [loginResponse.body?.data, secondLogin])
const resetLoginResponse = await context.request('POST', '/api/auth/login', { loginId: username, password: resetPassword }, '')
const resetLoginPassed = resetLoginResponse.http === 200 && String(resetLoginResponse.body?.code) === '200' && Boolean(resetLoginResponse.body?.data?.accessToken)
context.addStep(module, '内部用户使用重置密码登录', resetLoginResponse, resetLoginPassed, `username=${username}`)
@@ -161,16 +182,20 @@ export async function run(context) {
}
}
const clearPermissionResponse = await context.request('PUT', '/api/platform/v1/iam/roles/permissions', { roleId, permissionIds: [] })
context.apiSuccess(module, '清空测试角色权限', clearPermissionResponse)
await verifyRevokedSessions(context, '角色权限清空撤销已登录会话', [resetLoginResponse.body?.data])
const activeLoginResponse = await context.request('POST', '/api/auth/login', { loginId: username, password: resetPassword }, '')
const activeLogin = context.apiSuccess(module, '按更新后的权限重新登录', activeLoginResponse)
const disableUserResponse = await context.request('PUT', `/api/platform/v1/iam/users/${membershipId}/status`, { status: 'DISABLED' })
const disabledUser = context.apiSuccess(module, '停用平台内部用户', disableUserResponse)
context.assert(module, '内部用户停用状态正确', disableUserResponse, disabledUser?.status === 'DISABLED', `status=${disabledUser?.status ?? 'missing'}`)
await verifyRevokedSessions(context, '账号停用撤销会话', [activeLogin])
const disabledLoginResponse = await context.request('POST', '/api/auth/login', { loginId: username, password: resetPassword }, '')
context.addStep(module, '停用用户禁止登录', disabledLoginResponse,
disabledLoginResponse.http === 200 && String(disabledLoginResponse.body?.code) !== '200',
`HTTP=${disabledLoginResponse.http}, code=${disabledLoginResponse.body?.code ?? 'missing'}`)
const clearPermissionResponse = await context.request('PUT', '/api/platform/v1/iam/roles/permissions', { roleId, permissionIds: [] })
context.apiSuccess(module, '清空测试角色权限', clearPermissionResponse)
const deleteRoleResponse = await context.request('DELETE', `/api/platform/v1/iam/roles/${roleId}`)
context.expectConflict(module, '已分配成员的角色禁止删除', deleteRoleResponse, 'system-role-protection')
const finalDisableRoleResponse = await context.request('PUT', `/api/platform/v1/iam/roles/${roleId}/status`, { status: 'DISABLED' })