64 lines
3.6 KiB
JavaScript
64 lines
3.6 KiB
JavaScript
import test from 'node:test'
|
|||
|
|
import assert from 'node:assert/strict'
|
||
|
|
import { AcceptanceRun } from '../admin-test-env-acceptance.mjs'
|
||
|
|
import { FIXED_RESOURCE_READONLY_MODULES } from './fixed-resource-readonly.mjs'
|
||
|
|
|
||
|
|
function runner(mutate = value => value) {
|
||
|
|
const context = new AcceptanceRun({ environment: 'test', fixedCustomerId: '123', quiet: true })
|
||
|
|
const calls = []
|
||
|
|
context.request = async (method, path) => {
|
||
|
|
calls.push({ method, path })
|
||
|
|
assert.equal(method, 'GET', '固定资源只读检查不得写入或创建资源')
|
||
|
|
let value = path.includes('?page=') ? { page: 1, size: 20, total: 0, records: [] } : []
|
||
|
|
if (path.endsWith('/tenants/123')) value = { id: '123', status: 'ACTIVE' }
|
||
|
|
if (path.endsWith('/dimension-initialization')) value = { status: 'READY' }
|
||
|
|
if (path.endsWith('/permissions')) value = [{ id: '1', permissionCode: 'platform:customer:list' }]
|
||
|
|
if (path.endsWith('/roles')) value = [{ id: '2', roleCode: 'EXISTING_ROLE' }]
|
||
|
|
if (path.includes('/iam/users?')) value.records = [{ membershipId: '3', tenantId: '0' }], value.total = 1
|
||
|
|
if (path.includes('/warehouse-admin?')) value.records = [{ id: '4', tenantId: '0' }], value.total = 1
|
||
|
|
return { method, path, http: 200, body: { code: '200', data: mutate(value, path) } }
|
||
|
|
}
|
||
|
|
return { context, calls }
|
||
|
|
}
|
||
|
|
|
||
|
|
for (const module of FIXED_RESOURCE_READONLY_MODULES) test(`${module}复用现有数据,只读通过且保留生命周期缺口`, async () => {
|
||
|
|
const { context, calls } = runner()
|
||
|
|
await context.executeModule(module, () => assert.fail('不得调用原生命周期处理器'))
|
||
|
|
const result = context.modules[0]
|
||
|
|
assert.equal(result.success, true)
|
||
|
|
assert.ok(result.passed > 0)
|
||
|
|
assert.equal(result.skipped, undefined)
|
||
|
|
assert.equal(result.coverageMode, 'READ_ONLY')
|
||
|
|
assert.equal(result.lifecycleSkipped, true)
|
||
|
|
assert.ok(calls.length > 0)
|
||
|
|
assert.ok(calls.every(row => row.method === 'GET'))
|
||
|
|
assert.equal(context.coverageGaps.length, 1)
|
||
|
|
assert.equal(context.coverageGaps[0].blocking, false)
|
||
|
|
assert.equal(context.createdResources.fixedResourceReadOnly[module].lifecycle, 'NOT_TESTED')
|
||
|
|
})
|
||
|
|
|
||
|
|
for (const [label, module, mutate] of [
|
||
|
|
['客户不匹配', 'customers', (value, path) => path.endsWith('/123') ? { ...value, id: '999' } : value],
|
||
|
|
['客户被停用', 'customers', (value, path) => path.endsWith('/123') ? { ...value, status: 'DISABLED' } : value],
|
||
|
|
['初始化未就绪', 'customers', (value, path) => path.endsWith('/dimension-initialization') ? { status: 'PENDING' } : value],
|
||
|
|
['仓库非公共归属', 'master-data', value => ({ ...value, records: [{ id: '4', tenantId: '999' }], total: 1 })],
|
||
|
|
['平台账号非平台归属', 'system', (value, path) => path.includes('/users?')
|
||
|
|
? { ...value, records: [{ membershipId: '3', tenantId: '123' }] } : value],
|
||
|
|
['分页结构缺失', 'notifications', () => []],
|
||
|
|
['分页范围错误', 'notifications', value => ({ ...value, page: 2 })],
|
||
|
|
['价格目录结构错误', 'pricing', () => ({ records: [] })],
|
||
|
|
]) test(`${label}必须失败,禁止补建或执行原写入处理器`, async () => {
|
||
|
|
const { context, calls } = runner(mutate)
|
||
|
|
await context.executeModule(module, () => assert.fail('不能回退创建数据'))
|
||
|
|
assert.equal(context.modules[0].success, false)
|
||
|
|
assert.ok(context.modules[0].failed > 0)
|
||
|
|
assert.ok(calls.every(row => row.method === 'GET'))
|
||
|
|
})
|
||
|
|
|
||
|
|
test('权限错误保留为真实失败,不以空目录通过', async () => {
|
||
|
|
const { context } = runner()
|
||
|
|
context.request = async () => ({ http: 403, body: { code: 'A0403' } })
|
||
|
|
await context.executeModule('system', () => assert.fail('不能修改授权'))
|
||
|
|
assert.equal(context.modules[0].success, false)
|
||
|
|
})
|