149 lines
11 KiB
JavaScript
149 lines
11 KiB
JavaScript
function id(value) { return value == null ? '' : String(value) }
|
|||
|
|
|
||
|
|
export async function run(context) {
|
||
|
|
const module = 'system'
|
||
|
|
const suffix = context.marker.replace(/\D/g, '').slice(-12)
|
||
|
|
|
||
|
|
const permissionsResponse = await context.request('GET', '/api/platform/v1/iam/permissions')
|
||
|
|
const permissions = context.apiSuccess(module, '查询菜单权限资源', permissionsResponse)
|
||
|
|
context.assert(module, '权限资源返回数组', permissionsResponse, Array.isArray(permissions),
|
||
|
|
`count=${Array.isArray(permissions) ? permissions.length : 'n/a'}`)
|
||
|
|
|
||
|
|
const permissionPayload = {
|
||
|
|
type: 'BUTTON',
|
||
|
|
code: `platform:acceptance:${suffix}`,
|
||
|
|
name: `Admin验收权限-${suffix}`,
|
||
|
|
parentId: null,
|
||
|
|
routePath: null,
|
||
|
|
httpMethod: null,
|
||
|
|
sortNo: 9999,
|
||
|
|
}
|
||
|
|
const createPermissionResponse = await context.request('POST', '/api/platform/v1/iam/permissions', permissionPayload)
|
||
|
|
const permission = context.apiSuccess(module, '创建自定义权限资源', createPermissionResponse)
|
||
|
|
const permissionId = id(permission?.id)
|
||
|
|
context.assert(module, '权限创建字段正确', createPermissionResponse,
|
||
|
|
permissionId && permission?.permissionCode === permissionPayload.code && permission?.builtIn === false,
|
||
|
|
`permissionId=${permissionId || 'missing'}`)
|
||
|
|
if (!permissionId) throw new Error('权限资源创建失败,系统模块无法继续')
|
||
|
|
context.createdResources.systemPermission = { id: permissionId, code: permissionPayload.code }
|
||
|
|
|
||
|
|
const updatePermissionResponse = await context.request('PUT', `/api/platform/v1/iam/permissions/${permissionId}`, {
|
||
|
|
name: `${permissionPayload.name}-已编辑`, parentId: null, routePath: null, httpMethod: null, sortNo: 9998,
|
||
|
|
})
|
||
|
|
const updatedPermission = context.apiSuccess(module, '编辑自定义权限资源', updatePermissionResponse)
|
||
|
|
context.assert(module, '权限编辑正确回显', updatePermissionResponse,
|
||
|
|
updatedPermission?.permissionName === `${permissionPayload.name}-已编辑` && Number(updatedPermission?.sortNo) === 9998,
|
||
|
|
`permissionId=${permissionId}`)
|
||
|
|
for (const status of ['DISABLED', 'ACTIVE']) {
|
||
|
|
const response = await context.request('PUT', `/api/platform/v1/iam/permissions/${permissionId}/status`, { status })
|
||
|
|
const changed = context.apiSuccess(module, `${status === 'ACTIVE' ? '启用' : '停用'}自定义权限`, response)
|
||
|
|
context.assert(module, `权限状态回显 ${status}`, response, changed?.status === status, `status=${changed?.status ?? 'missing'}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
const rolePayload = { roleCode: `ADMIN_ACCEPT_${suffix}`, roleName: `Admin验收角色-${suffix}`, description: context.marker }
|
||
|
|
const createRoleResponse = await context.request('POST', '/api/platform/v1/iam/roles', rolePayload)
|
||
|
|
const role = context.apiSuccess(module, '创建平台自定义角色', createRoleResponse)
|
||
|
|
const roleId = id(role?.id)
|
||
|
|
context.assert(module, '角色创建字段正确', createRoleResponse,
|
||
|
|
roleId && role?.roleCode === rolePayload.roleCode && role?.roleType === 'CUSTOM', `roleId=${roleId || 'missing'}`)
|
||
|
|
if (!roleId) throw new Error('角色创建失败,系统模块无法继续')
|
||
|
|
context.createdResources.systemRole = { id: roleId, code: rolePayload.roleCode, finalStatus: 'DISABLED', retainedBecauseAssigned: true }
|
||
|
|
|
||
|
|
const editRoleResponse = await context.request('PUT', `/api/platform/v1/iam/roles/${roleId}`, {
|
||
|
|
roleName: `${rolePayload.roleName}-已编辑`, description: `${context.marker}-EDITED`,
|
||
|
|
})
|
||
|
|
const editedRole = context.apiSuccess(module, '编辑平台自定义角色', editRoleResponse)
|
||
|
|
context.assert(module, '角色编辑正确回显', editRoleResponse,
|
||
|
|
editedRole?.roleName === `${rolePayload.roleName}-已编辑`, `roleId=${roleId}`)
|
||
|
|
const grantResponse = await context.request('PUT', '/api/platform/v1/iam/roles/permissions', { roleId, permissionIds: [permissionId] })
|
||
|
|
context.apiSuccess(module, '角色全量保存权限', grantResponse)
|
||
|
|
const rolesResponse = await context.request('GET', '/api/platform/v1/iam/roles')
|
||
|
|
const roles = context.apiSuccess(module, '回查平台角色列表', rolesResponse)
|
||
|
|
const listedRole = roles?.find?.((item) => id(item.id) === roleId)
|
||
|
|
context.assert(module, '角色权限 ID 正确回显', rolesResponse,
|
||
|
|
listedRole && listedRole.permissionIds?.map(id).includes(permissionId),
|
||
|
|
`permissionIds=${listedRole?.permissionIds?.map(id).join(',') || 'missing'}`)
|
||
|
|
for (const status of ['DISABLED', 'ACTIVE']) {
|
||
|
|
const response = await context.request('PUT', `/api/platform/v1/iam/roles/${roleId}/status`, { status })
|
||
|
|
const changed = context.apiSuccess(module, `${status === 'ACTIVE' ? '启用' : '停用'}自定义角色`, response)
|
||
|
|
context.assert(module, `角色状态回显 ${status}`, response, changed?.status === status, `status=${changed?.status ?? 'missing'}`)
|
||
|
|
}
|
||
|
|
|
||
|
|
const optionsResponse = await context.request('GET', '/api/platform/v1/iam/users/options')
|
||
|
|
const options = context.apiSuccess(module, '查询内部用户可选平台角色', optionsResponse)
|
||
|
|
context.assert(module, '用户选项包含平台与测试角色', optionsResponse,
|
||
|
|
options?.tenants?.some((item) => id(item.id) === '0') && options?.roles?.some((item) => id(item.id) === roleId),
|
||
|
|
`tenants=${options?.tenants?.length ?? 'n/a'}, roles=${options?.roles?.length ?? 'n/a'}`)
|
||
|
|
|
||
|
|
const phone = await context.findAvailablePhone(module)
|
||
|
|
const username = `admin_accept_${suffix}`
|
||
|
|
const initialPassword = `Accept${suffix}A1`
|
||
|
|
const resetPassword = `Reset${suffix}B2`
|
||
|
|
const userPayload = {
|
||
|
|
username, displayName: `Admin验收用户-${suffix}`, phone,
|
||
|
|
email: `${username}@example.com`, tenantId: '0', roleIds: [roleId],
|
||
|
|
password: initialPassword, status: 'ACTIVE',
|
||
|
|
}
|
||
|
|
const createUserResponse = await context.request('POST', '/api/platform/v1/iam/users', userPayload)
|
||
|
|
const user = context.apiSuccess(module, '创建平台内部用户', createUserResponse)
|
||
|
|
const membershipId = id(user?.membershipId)
|
||
|
|
context.assert(module, '内部用户账号、平台范围和角色正确', createUserResponse,
|
||
|
|
membershipId && user?.username === username && id(user?.tenantId) === '0' && user?.roleIds?.map(id).includes(roleId),
|
||
|
|
`membershipId=${membershipId || 'missing'}`)
|
||
|
|
if (!membershipId) throw new Error('平台内部用户创建失败,系统模块无法继续')
|
||
|
|
context.createdResources.systemUser = { membershipId, username, finalStatus: 'DISABLED' }
|
||
|
|
|
||
|
|
const pageResponse = await context.request('GET', `/api/platform/v1/iam/users?page=1&size=20&keyword=${username}`)
|
||
|
|
const page = context.apiSuccess(module, '按账号查询平台内部用户', pageResponse)
|
||
|
|
const listedUser = page?.records?.find((item) => id(item.membershipId) === membershipId)
|
||
|
|
const missingUserFields = listedUser ? requiredUserFields().filter((field) => !Object.hasOwn(listedUser, field)) : requiredUserFields()
|
||
|
|
context.assert(module, '用户列表包含新账号且字段完整', pageResponse,
|
||
|
|
listedUser && missingUserFields.length === 0
|
||
|
|
&& (!Object.hasOwn(listedUser, 'lastLoginAt') || typeof listedUser.lastLoginAt === 'string'),
|
||
|
|
`records=${page?.records?.length ?? 'n/a'}, missing=${missingUserFields.join(',') || 'none'}, lastLoginAt=${listedUser?.lastLoginAt ?? 'omitted'}`)
|
||
|
|
|
||
|
|
const updateUserPayload = {
|
||
|
|
displayName: `${userPayload.displayName}-已编辑`, phone,
|
||
|
|
email: `edited-${userPayload.email}`, tenantId: '0', roleIds: [roleId],
|
||
|
|
}
|
||
|
|
const updateUserResponse = await context.request('PUT', `/api/platform/v1/iam/users/${membershipId}`, updateUserPayload)
|
||
|
|
const updatedUser = context.apiSuccess(module, '编辑平台内部用户', updateUserResponse)
|
||
|
|
context.assert(module, '用户编辑正确回显', updateUserResponse,
|
||
|
|
updatedUser?.displayName === updateUserPayload.displayName && updatedUser?.email === updateUserPayload.email,
|
||
|
|
`membershipId=${membershipId}`)
|
||
|
|
|
||
|
|
const loginResponse = await context.request('POST', '/api/auth/login', { 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 resetResponse = await context.request('PUT', `/api/platform/v1/iam/users/${membershipId}/password`, { newPassword: resetPassword })
|
||
|
|
context.apiSuccess(module, '重置平台内部用户密码', resetResponse)
|
||
|
|
const resetLoginResponse = await context.request('POST', '/api/auth/login', { 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}`)
|
||
|
|
|
||
|
|
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'}`)
|
||
|
|
const disabledLoginResponse = await context.request('POST', '/api/auth/login', { 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' })
|
||
|
|
const finalRole = context.apiSuccess(module, '清理时停用测试角色', finalDisableRoleResponse)
|
||
|
|
context.assert(module, '保留测试角色处于停用状态', finalDisableRoleResponse, finalRole?.status === 'DISABLED',
|
||
|
|
`status=${finalRole?.status ?? 'missing'}`)
|
||
|
|
const deletePermissionResponse = await context.request('DELETE', `/api/platform/v1/iam/permissions/${permissionId}`)
|
||
|
|
context.apiSuccess(module, '删除临时权限资源', deletePermissionResponse)
|
||
|
|
}
|
||
|
|
|
||
|
|
function requiredUserFields() {
|
||
|
|
return ['membershipId', 'userId', 'authUserId', 'username', 'displayName', 'phone', 'email',
|
||
|
|
'tenantId', 'tenantName', 'memberType', 'status', 'roleIds', 'roleNames', 'protectedAccount']
|
||
|
|
}
|