优化
This commit is contained in:
@@ -17,8 +17,10 @@ import { randomUUID, createHash } from 'node:crypto'
|
||||
import { resolve } from 'node:path'
|
||||
import { createInterface } from 'node:readline/promises'
|
||||
import { inflateRawSync, deflateRawSync } from 'node:zlib'
|
||||
import { normalizeFixedCustomerId } from './admin-test-env-modules/merchant-qualification-fixture.mjs'
|
||||
|
||||
const args = parseArgs(process.argv.slice(2))
|
||||
const fixedCustomerId = normalizeFixedCustomerId(process.env.ADMIN_TEST_FIXED_CUSTOMER_ID)
|
||||
if ((args.environment && args.environment !== 'test') || args['overseas-gateway'] || process.env.ADMIN_OVERSEAS_GATEWAY) throw new Error('Only one TEST gateway is supported; remove regional options')
|
||||
const gateway = trimSlash(args.gateway ?? process.env.ADMIN_TEST_GATEWAY)
|
||||
const platformUsername = args['platform-username'] ?? process.env.ADMIN_TEST_USERNAME
|
||||
@@ -26,9 +28,9 @@ const platformUsername = args['platform-username'] ?? process.env.ADMIN_TEST_USE
|
||||
const platformPassword = args['platform-password'] ?? process.env.ADMIN_TEST_PASSWORD
|
||||
?? await promptSecret('平台审核密码')
|
||||
const existingClientUsername = args['existing-client-username'] ?? process.env.MERCHANT_TEST_USERNAME
|
||||
?? await promptText('跨客户隔离测试账号(必须由正式注册/建档产生)', '')
|
||||
?? await promptText('固定客户测试账号', '')
|
||||
const existingClientPassword = args['existing-client-password'] ?? process.env.MERCHANT_TEST_PASSWORD
|
||||
?? await promptSecret('跨客户隔离测试密码')
|
||||
?? await promptSecret('固定客户测试密码')
|
||||
const reportDir = resolve(args['report-dir'] ?? process.env.CLIENT_TEST_REPORT_DIR ?? 'reports')
|
||||
const timeoutMs = Number(args['timeout-ms'] ?? process.env.CLIENT_TEST_TIMEOUT_MS ?? 30_000)
|
||||
|
||||
@@ -43,12 +45,12 @@ if (!Number.isFinite(timeoutMs) || timeoutMs < 1_000) {
|
||||
|
||||
const now = new Date()
|
||||
const marker = `${compactTimestamp(now)}-${randomUUID().slice(0, 8)}`
|
||||
const username = `client_${compactTimestamp(now)}_${randomUUID().slice(0, 6)}`.slice(0, 64)
|
||||
const username = existingClientUsername
|
||||
const temporaryUsername = `renamed_${compactTimestamp(now)}_${randomUUID().slice(0, 6)}`.slice(0, 64)
|
||||
const clientPassword = `Client${randomUUID().replaceAll('-', '').slice(0, 14)}9!`
|
||||
const clientPassword = existingClientPassword
|
||||
const phoneSuffix = `${Date.now()}`.slice(-8)
|
||||
const legalPhone = `139${phoneSuffix}`
|
||||
const companyName = `客户端全链路测试企业-${marker}`.slice(0, 128)
|
||||
let companyName = ''
|
||||
const creditCode = `91${compactTimestamp(now)}${randomUUID().replaceAll('-', '').slice(0, 2).toUpperCase()}`.slice(0, 18)
|
||||
const reportPath = resolve(reportDir, `client-test-env-${marker}.json`)
|
||||
|
||||
@@ -58,6 +60,7 @@ const report = {
|
||||
generatedAt: now.toISOString(),
|
||||
completedAt: null,
|
||||
success: false,
|
||||
fullCoverage: false,
|
||||
fatal: null,
|
||||
testAccount: { username, companyName, legalPhone },
|
||||
resources: {
|
||||
@@ -94,33 +97,34 @@ let ownerPasswordNeedsRestore = false
|
||||
let temporaryOwnerPassword
|
||||
|
||||
try {
|
||||
await registrationModule()
|
||||
await reuseFixedClient()
|
||||
await platformReviewerLogin()
|
||||
await merchantBeforeApprovalModule()
|
||||
await qualificationAndReviewModule()
|
||||
await merchantAfterApprovalModule()
|
||||
await profileManagementModule()
|
||||
await loginIdentifierModule()
|
||||
await rbacAndMemberModule()
|
||||
for (const module of ['registration', 'qualification-review', 'profile-management', 'login-identifiers',
|
||||
'rbac-members', 'isolation', 'order-submission-balance', 'order-mutation-evidence',
|
||||
'order-submission-channel', 'notification-inbox', 'account-security']) {
|
||||
recordSkipped(module, '固定客户模式排除生命周期或共享配置写入',
|
||||
'不注册客户、不修改固定账号资料或余额、不发布通知;跨客户场景需第二个固定客户')
|
||||
}
|
||||
await orderLifecycleModule()
|
||||
await isolationModule()
|
||||
await orderSubmissionBalanceGateModule()
|
||||
await orderMutationEvidenceModule()
|
||||
await orderExcelImportModule()
|
||||
await orderSubmissionChannelGateModule()
|
||||
await merchantFinanceBillsModule()
|
||||
await merchantOverseasWarehouseModule()
|
||||
await merchantCrossBorderModule()
|
||||
await merchantWarehouseOrdersModule()
|
||||
await merchantPricingCustomsModule()
|
||||
await notificationInboxModule()
|
||||
await accountSecurityModule()
|
||||
report.success = report.steps.every((step) => step.passed)
|
||||
report.fullCoverage = !report.steps.some((step) => step.skipped)
|
||||
} catch (error) {
|
||||
report.fatal = sanitizeError(error)
|
||||
report.success = false
|
||||
} finally {
|
||||
if (ownerPasswordNeedsRestore) await recoverOwnerPassword()
|
||||
if (merchantToken) {
|
||||
const logout = await softApiStep('fixed-customer', '退出固定客户测试会话', {
|
||||
method: 'POST', path: '/api/auth/logout', token: merchantToken, body: { refreshToken: merchantRefreshToken },
|
||||
}, ({ json }) => requireSuccess(json))
|
||||
if (!logout) report.success = false
|
||||
}
|
||||
report.completedAt = new Date().toISOString()
|
||||
await mkdir(reportDir, { recursive: true })
|
||||
await writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`, 'utf8')
|
||||
@@ -129,6 +133,24 @@ try {
|
||||
|
||||
process.exitCode = report.success ? 0 : 1
|
||||
|
||||
async function reuseFixedClient() {
|
||||
const login = await apiStep('fixed-customer', '登录固定客户', {
|
||||
method: 'POST', path: '/api/auth/login', body: { loginId: username, password: clientPassword },
|
||||
}, ({ json }) => { requireSuccess(json); assertPresent(json.data?.accessToken, 'accessToken') })
|
||||
merchantToken = login.json.data.accessToken
|
||||
merchantRefreshToken = login.json.data.refreshToken
|
||||
const profile = await apiStep('fixed-customer', '校验固定客户归属及状态', {
|
||||
method: 'GET', path: '/api/merchant/v1/iam/tenant/profile', token: merchantToken,
|
||||
}, ({ json }) => {
|
||||
requireSuccess(json)
|
||||
assertEqual(String(json.data?.id), fixedCustomerId, 'fixed customer identity')
|
||||
assertEqual(json.data?.status, 'ACTIVE', 'fixed customer status')
|
||||
})
|
||||
report.resources.tenantId = fixedCustomerId
|
||||
companyName = profile.json.data.tenantName
|
||||
report.testAccount = { username, reused: true }
|
||||
}
|
||||
|
||||
async function registrationModule() {
|
||||
const registrationBody = {
|
||||
username,
|
||||
@@ -3360,6 +3382,10 @@ async function softApiStep(module, name, request, validate, evidenceBuilder = de
|
||||
}
|
||||
|
||||
async function httpRequest({ method = 'GET', path, token, headers = {}, body, responseType = 'json' }) {
|
||||
if (String(method).toUpperCase() === 'POST'
|
||||
&& ['/api/auth/register', '/api/platform/v1/iam/tenants'].includes(new URL(path, 'https://acceptance.invalid').pathname.replace(/\/$/, ''))) {
|
||||
throw new Error('固定客户模式禁止注册或创建客户')
|
||||
}
|
||||
const requestHeaders = { Accept: 'application/json', 'X-Request-Id': `client-e2e-${randomUUID()}`, ...headers }
|
||||
if (token) requestHeaders.Authorization = `Bearer ${token}`
|
||||
let requestBody = body
|
||||
|
||||
Reference in New Issue
Block a user