优化
This commit is contained in:
@@ -4,6 +4,20 @@ const CONTAINERS = '/api/platform/v1/containers'
|
||||
|
||||
function id(value) { return value == null ? '' : String(value) }
|
||||
|
||||
export function controlledPhotoDownload(downloadPath, response) {
|
||||
const controlledPath = typeof downloadPath === 'string'
|
||||
&& downloadPath.startsWith('/api/')
|
||||
&& !downloadPath.startsWith('//')
|
||||
&& !downloadPath.includes('://')
|
||||
const contentType = String(response?.contentType || '').toLowerCase()
|
||||
return controlledPath
|
||||
&& response?.http === 200
|
||||
&& response?.bytes?.length > 0
|
||||
&& Boolean(contentType)
|
||||
&& !contentType.includes('json')
|
||||
&& !contentType.includes('text/html')
|
||||
}
|
||||
|
||||
export async function run(context) {
|
||||
const loadingRequested = context.options?.modules?.includes('phase3-loading') === true
|
||||
const fixture = loadingRequested
|
||||
@@ -39,7 +53,7 @@ export async function run(context) {
|
||||
if (overview?.pda) {
|
||||
const expectsPhotos = fixture === context.createdResources?.phase3Loading
|
||||
&& Array.isArray(fixture?.evidenceTypes) && fixture.evidenceTypes.length > 0
|
||||
const requiredFields = ['taskId', 'taskStatus', 'taskVersion', 'itemCount', 'completedItemCount', 'unresolvedItemCount']
|
||||
const requiredFields = ['taskId', 'taskStatus', 'workflowStatus', 'taskVersion', 'itemCount', 'completedItemCount', 'unresolvedItemCount']
|
||||
const missingFields = requiredFields.filter((field) => overview.pda[field] === undefined)
|
||||
context.assert(MODULE, 'overview PDA 摘要字段完整', overviewResponse,
|
||||
missingFields.length === 0
|
||||
@@ -48,10 +62,29 @@ export async function run(context) {
|
||||
&& Array.isArray(overview.pda.exceptionReasons)
|
||||
&& (!expectsPhotos || overview.pda.photos.length > 0),
|
||||
`taskId=${id(overview.pda.taskId)}, photos=${overview.pda.photos?.length ?? 'not-array'}, missingFields=${missingFields.join('|') || 'none'}, photoCountsArray=${Array.isArray(overview.pda.photoCounts)}, photosArray=${Array.isArray(overview.pda.photos)}, exceptionReasonsArray=${Array.isArray(overview.pda.exceptionReasons)}`, OPTIONS)
|
||||
const progressIsComplete = Number(overview.pda.itemCount) > 0
|
||||
&& Number(overview.pda.completedItemCount) === Number(overview.pda.itemCount)
|
||||
&& Number(overview.pda.unresolvedItemCount) === 0
|
||||
context.assert(MODULE, 'overview PDA 100%进度区分作业中与待复核', overviewResponse,
|
||||
!progressIsComplete || overview.pda.taskStatus !== 'LOADING'
|
||||
|| overview.pda.workflowStatus === 'AWAITING_REVIEW',
|
||||
`taskStatus=${overview.pda.taskStatus || 'missing'}, workflowStatus=${overview.pda.workflowStatus || 'missing'}, completed=${overview.pda.completedItemCount ?? 'missing'}/${overview.pda.itemCount ?? 'missing'}`, OPTIONS)
|
||||
for (const [index, photo] of overview.pda.photos.entries()) {
|
||||
context.assert(MODULE, `overview PDA 照片摘要 ${index + 1} 字段完整`, overviewResponse,
|
||||
['evidenceId', 'fileId', 'status', 'downloadPath'].every((field) => photo[field] !== undefined),
|
||||
`fileId=${id(photo.fileId)}`, OPTIONS)
|
||||
const downloadPath = String(photo.downloadPath || '')
|
||||
const controlledPath = downloadPath.startsWith('/api/')
|
||||
&& !downloadPath.startsWith('//') && !downloadPath.includes('://')
|
||||
if (!controlledPath) {
|
||||
context.assert(MODULE, `overview PDA 照片 ${index + 1} 下载路径受控`, overviewResponse, false,
|
||||
`fileId=${id(photo.fileId)}, downloadPath=${downloadPath || 'missing'}`, OPTIONS)
|
||||
continue
|
||||
}
|
||||
const download = await context.requestBinary('GET', downloadPath)
|
||||
context.assert(MODULE, `overview PDA 照片 ${index + 1} 可鉴权下载`, download,
|
||||
controlledPhotoDownload(downloadPath, download),
|
||||
`fileId=${id(photo.fileId)}, bytes=${download?.bytes?.length ?? 0}, contentType=${download?.contentType || 'missing'}`, OPTIONS)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user