优化
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { openFixedActor, requireFixedActors, POOL_ACTOR_SLOTS } from './admin-test-env-modules/fixed-test-actors.mjs'
|
||||
import { mkdirSync, openSync, writeFileSync, fsyncSync, closeSync, readFileSync } from 'node:fs'
|
||||
import { resolve, dirname, join } from 'node:path'
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
import { createHash, randomUUID } from 'node:crypto'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { AcceptanceRun } from './admin-test-env-acceptance.mjs'
|
||||
import { normalizeFixedCustomerId } from './admin-test-env-modules/merchant-qualification-fixture.mjs'
|
||||
import { parseCrossCustomerArguments, runCrossCustomer } from './fleet-cross-customer-test-env.mjs'
|
||||
import { guardFleetWrites, redactFleetWrite, findFleetActorPhone } from './fleet-test-env-acceptance.mjs'
|
||||
import { guardFleetWrites, redactFleetWrite } from './fleet-test-env-acceptance.mjs'
|
||||
import { confirmFleetLoading } from './admin-test-env-modules/fleet-trip-fulfillment.mjs'
|
||||
import { testPlannedCapacity } from './admin-test-env-modules/fleet-booking-reservation-acceptance.mjs'
|
||||
import { pickAll, saveReceiptAndComplete, readAutomaticDispatchDelivery } from './admin-test-env-modules/phase5-overseas-fulfillment.mjs'
|
||||
@@ -291,25 +293,14 @@ async function poolScenario(context, fixture, { execute = false, readInventory,
|
||||
check(label, denied(response) && response.requestId && response.traceId, response)
|
||||
return response
|
||||
}
|
||||
const permissions = await request('GET', `${IAM}/permissions`)
|
||||
requireFixedActors(context.options, POOL_ACTOR_SLOTS)
|
||||
const actorSessions = [], merchantSessions = []
|
||||
const businessPath = order => `${API}/${order.businessType === 'US_TRUCK' ? 'us-truck-orders' : 'local-looseboard-orders'}/${encode(order.businessOrderNo)}?customerId=${encode(order.customerId)}`
|
||||
const createActor = async (kind, index, codes) => {
|
||||
const suffix = createHash('sha256').update(`${context.marker}:${kind}:${index}`).digest('hex').slice(0, 16)
|
||||
const found = codes.map(code => permissions.filter(p => p.permissionCode === code && p.status === 'ACTIVE'))
|
||||
check('Exact pool permissions exist', found.every(rows => rows.length === 1 && rows[0].id))
|
||||
const role = await request('POST', `${IAM}/roles`, { roleCode: `POOL_${kind}_${suffix}`.toUpperCase(), roleName: `${context.marker}-${kind}-${index}`, description: context.marker })
|
||||
const actor = { kind, index, roleId: id(role.id) }; proof.actors.push(actor)
|
||||
await request('PUT', `${IAM}/roles/permissions`, { roleId: actor.roleId, permissionIds: found.map(rows => id(rows[0].id)) })
|
||||
const username = `pool_${kind}_${suffix}`, password = `Pool${randomUUID().replaceAll('-', '')}A9`
|
||||
const user = await request('POST', `${IAM}/users`, { username, displayName: `${context.marker}-同名测试人员`,
|
||||
phone: await findFleetActorPhone(context, suffix), email: `${username}@example.com`, tenantId: '0', roleIds: [actor.roleId], password, status: 'ACTIVE' })
|
||||
actor.membershipId = id(user.membershipId)
|
||||
const login = await request('POST', '/api/auth/login', { loginId: username, password }, '')
|
||||
actorSessions.push({ accessToken: login.accessToken, refreshToken: login.refreshToken })
|
||||
const effective = await request('GET', `${IAM}/authorization/permissions`, undefined, login.accessToken)
|
||||
check('Temporary actor has exact permissions', Array.isArray(effective) && JSON.stringify([...effective].sort()) === JSON.stringify([...codes].sort()))
|
||||
return login.accessToken
|
||||
const session = await openFixedActor(context, `pool.${kind}.${index}`, codes)
|
||||
actorSessions.push(session)
|
||||
proof.actors.push({ kind, index, roleId: session.roleId, membershipId: session.membershipId, username: session.username, reused: true })
|
||||
return session.token
|
||||
}
|
||||
try {
|
||||
const sales = [], dispatchers = []
|
||||
@@ -531,11 +522,8 @@ async function poolScenario(context, fixture, { execute = false, readInventory,
|
||||
return proof
|
||||
} catch (error) { proof.status = 'FAILED'; throw error }
|
||||
finally {
|
||||
for (const actor of proof.actors) {
|
||||
if (actor.membershipId) await request('PUT', `${IAM}/users/${actor.membershipId}/status`, { status: 'DISABLED' })
|
||||
if (actor.roleId) await request('PUT', `${IAM}/roles/${actor.roleId}/status`, { status: 'DISABLED' })
|
||||
}
|
||||
// The outer runner tracks and logs out all successful login sessions, including these.
|
||||
const closed = await Promise.allSettled(actorSessions.map(actor => actor.close()))
|
||||
if (closed.some(row => row.status === 'rejected')) throw Error('固定拼车账号会话退出未全部确认')
|
||||
actorSessions.length = 0; merchantSessions.length = 0
|
||||
}
|
||||
}
|
||||
@@ -653,14 +641,12 @@ export async function runPoolAcceptance(config, { env = process.env, outputRoot
|
||||
try {
|
||||
const result = await runner(config, { env, outputRoot, verificationScope: 'CAPACITY_POOL',
|
||||
contextFactory: options => {
|
||||
const context = new AcceptanceRun(options), original = context.request
|
||||
context.request = async function (...args) {
|
||||
const response = await original.apply(this, args)
|
||||
if (args[0] === 'POST' && args[1] === `${IAM}/tenants` && success(response)) {
|
||||
const data = response.body.data, customer = data.tenant || data.customer || data
|
||||
credentials.set(id(customer.id || data.tenantId), { username: data.administratorUsername, password: data.temporaryPassword })
|
||||
}
|
||||
return response
|
||||
const context = new AcceptanceRun(options)
|
||||
requireFixedActors(context.options, POOL_ACTOR_SLOTS)
|
||||
for (const customer of [{ customerId: context.options.fixedCustomerId, username: context.options.merchantUsername,
|
||||
password: context.options.merchantPassword }, context.options.fixedSecondaryCustomer]) {
|
||||
if (customer?.customerId && customer.username && customer.password)
|
||||
credentials.set(normalizeFixedCustomerId(customer.customerId), { username: customer.username, password: customer.password })
|
||||
}
|
||||
const directory = join(outputRoot, 'reports', poolReportName(config), 'pool-write-journal')
|
||||
mkdirSync(directory)
|
||||
@@ -670,7 +656,12 @@ export async function runPoolAcceptance(config, { env = process.env, outputRoot
|
||||
}, { guardFetch: true })
|
||||
return context
|
||||
},
|
||||
verify: (context, fixture, options) => poolScenario(context, fixture, { ...options, credentials }) })
|
||||
verify: (context, fixture, options) => {
|
||||
requireThat(fixture?.members?.length === 2 && new Set(fixture.members.map(member => id(member.customerId))).size === 2
|
||||
&& fixture.members.every(member => credentials.has(id(member.customerId))),
|
||||
'CURRENT_FIXED_POOL_CUSTOMER_CREDENTIALS_REQUIRED')
|
||||
return poolScenario(context, fixture, { ...options, credentials })
|
||||
} })
|
||||
result.scope = config.environment === 'GRAY' ? 'FLEET_CAPACITY_POOL_GRAY' : 'FLEET_CAPACITY_POOL_HTTP'; result.fullAcceptance = false
|
||||
result.remainingSeparateAcceptance = [...POOL_REMAINING]
|
||||
const output = join(outputRoot, 'reports', poolReportName(config))
|
||||
|
||||
Reference in New Issue
Block a user