优化
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { overseasRequest, overseasUpload, resetOverseasRequestStateForTest } from '../src/api/overseas.js'
|
||||
import { overseasDownload, overseasRequest, overseasUpload, resetOverseasRequestStateForTest } from '../src/api/overseas.js'
|
||||
import { PDA_AUTHORITY, PDA_ROLE, session, signInWithTokens, signOut } from '../src/stores/session.js'
|
||||
|
||||
const future = () => Math.floor(Date.now() / 1000) + 3600
|
||||
@@ -128,6 +128,18 @@ test('photo upload refreshes and replays once while retaining the file payload',
|
||||
])
|
||||
})
|
||||
|
||||
test('authenticated photo download maps the public api path through the H5 overseas proxy', async () => {
|
||||
const value = prepareSession(); const calls = []
|
||||
globalThis.uni.downloadFile = (options) => {
|
||||
calls.push(options)
|
||||
options.success({ statusCode: 200, tempFilePath: '/tmp/restored.jpg', header: {} })
|
||||
}
|
||||
assert.equal(await overseasDownload('/api/pda/v1/last-leg/receiving-containers/current/unload-photos/files/99/download'), '/tmp/restored.jpg')
|
||||
assert.equal(calls.length, 1)
|
||||
assert.equal(calls[0].url, '/overseas-api/pda/v1/last-leg/receiving-containers/current/unload-photos/files/99/download')
|
||||
assert.equal(calls[0].header.Authorization, `Bearer ${value.overseasAccessToken}`)
|
||||
})
|
||||
|
||||
test('business and network errors retain diagnostics without refreshing or clearing a valid session', async () => {
|
||||
prepareSession(); let refreshCount = 0
|
||||
globalThis.uni.request = (options) => {
|
||||
@@ -147,4 +159,3 @@ test('business and network errors retain diagnostics without refreshing or clear
|
||||
await assert.rejects(overseasRequest('GET', '/pda/network'), (error) => error.network === true && /socket/.test(error.message))
|
||||
assert.ok(session.currentUser)
|
||||
})
|
||||
|
||||
|
||||
@@ -57,6 +57,6 @@ test('unimplemented warehouse operations cannot submit prototype scans', async (
|
||||
])
|
||||
assert.doesNotMatch(operation, /prototypeScan|prototypeInput/)
|
||||
assert.match(operation, /功能暂未开放|扫码不会提交/)
|
||||
assert.match(home, /operation\.badge/)
|
||||
assert.match(module, /专用接口、权限与仓库范围契约完成前保持禁用/)
|
||||
assert.match(home, /暂未开放/)
|
||||
assert.match(module, /当前仅开放拆柜收货,其他作业暂未开放/)
|
||||
})
|
||||
|
||||
@@ -6,11 +6,12 @@ test('receiving adapter preserves the three signed photo roles in workflow order
|
||||
const snowflakeFileId = '2092476334483931138'
|
||||
const session = normalizeReceivingSession({
|
||||
status: 'WAIT_SIGN', totalPackages: 8, receivedPackages: 2, pendingPackages: 6,
|
||||
photos: [{ role: 'DOOR_OPEN', fileId: '3' }, { role: 'LICENSE_PLATE', fileId: snowflakeFileId }, { role: 'CONTAINER_SEAL', fileId: '2' }],
|
||||
photos: [{ role: 'DOOR_OPEN', fileId: '3' }, { role: 'LICENSE_PLATE', fileId: snowflakeFileId }, { role: 'CONTAINER_SEAL', fileId: '2' }, { role: 'DOOR_OPEN', fileId: '4' }],
|
||||
inbounds: [{ inboundCode: 'IN-1', plannedPalletCount: 2, totalPackages: 8, receivedPackages: 2, pendingPackages: 6 }]
|
||||
})
|
||||
assert.deepEqual(session.photos.map(({ role }) => role), RECEIVING_PHOTO_ROLES)
|
||||
assert.equal(session.photos[0].fileId, snowflakeFileId)
|
||||
assert.equal(session.photos.length, 3)
|
||||
assert.equal(session.inbounds[0].plannedPalletCount, 2)
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
|
||||
const read = (relative) => readFileSync(new URL(relative, import.meta.url), 'utf8')
|
||||
const page = read('../src/pages/operation/operation.vue')
|
||||
const adapter = read('../src/api/receiving-adapter.js')
|
||||
const inbound = read('../src/api/inbound.js')
|
||||
const controller = read('../../../baiyue-firstleg/lastleg-service/src/main/java/com/baiyue/lastleg/inboundplan/pda/controller/ReceivingContainerController.java')
|
||||
const openapi = read('../../../baiyue-firstleg/lastleg-service/src/main/resources/openapi/overseas-business-v1.yaml')
|
||||
|
||||
function photoUiBlockers() {
|
||||
const values = []
|
||||
const hasThumbnail = /<image[\s\S]*photoSlots\[index\]/.test(page)
|
||||
const hasPreview = /uni\.previewImage\(/.test(page)
|
||||
const hasRestoreDownload = /@GetMapping\([^\n]*unload-photos/.test(controller)
|
||||
|| /receiving-containers\/current\/unload-photos\/files\/\{fileId\}/.test(openapi)
|
||||
const hasRestoreClient = /downloadCurrentUnloadPhoto/.test(inbound) && /downloadPath/.test(page)
|
||||
const developmentLabels = ['真实接口', '待 PDA 接口', 'Mock']
|
||||
.filter((label) => page.toLowerCase().includes(label.toLowerCase()))
|
||||
if (!hasThumbnail || !hasPreview) values.push({
|
||||
code: 'PHOTO_THUMBNAIL_PREVIEW_MISSING', deploymentBlocker: true,
|
||||
reason: '上传成功后只显示完成图标,尚未渲染缩略图或调用uni.previewImage',
|
||||
})
|
||||
if (!hasRestoreDownload) values.push({
|
||||
code: 'PHOTO_RESTORE_DOWNLOAD_ENDPOINT_MISSING', deploymentBlocker: true,
|
||||
reason: 'current恢复只返回fileId/role,后端没有签收照片鉴权下载端点,无法恢复后回显',
|
||||
})
|
||||
else if (!hasRestoreClient) values.push({
|
||||
code: 'PHOTO_RESTORE_CLIENT_PENDING', deploymentBlocker: true,
|
||||
reason: '后端下载契约仍在冻结中,前端尚未接入重载后的鉴权照片回显',
|
||||
})
|
||||
if (developmentLabels.length) values.push({
|
||||
code: 'DEVELOPMENT_LABELS_VISIBLE', deploymentBlocker: true,
|
||||
reason: `页面仍含开发标识:${developmentLabels.join(',')}`,
|
||||
})
|
||||
return values
|
||||
}
|
||||
|
||||
test('three fixed receiving photo roles and string file IDs are frozen', () => {
|
||||
assert.match(adapter, /RECEIVING_PHOTO_ROLES = \['LICENSE_PLATE', 'CONTAINER_SEAL', 'DOOR_OPEN'\]/)
|
||||
assert.match(adapter, /fileId: String\(photo\.fileId\)/)
|
||||
assert.match(page, /fileId: String\(file\.fileId\)/)
|
||||
assert.match(page, /fileId: String\(item\.fileId\)/)
|
||||
assert.doesNotMatch(inbound, /customerId|planNo|allocationId|warehouseId|locationId/)
|
||||
})
|
||||
|
||||
test('camera or album replaces only one fixed slot and failed replacement preserves its previous success', () => {
|
||||
assert.match(page, /choosePhotos\(index, sourceType\)[\s\S]*uni\.chooseImage\(\{ count: 1, sourceType: \[sourceType\]/)
|
||||
assert.match(page, /choosePhotos\(index, 'camera'\)/)
|
||||
assert.match(page, /choosePhotos\(index, 'album'\)/)
|
||||
assert.match(page, /async replacePhoto\(index, path\)[\s\S]*const previous = receiving\.photoSlots\[index\]/)
|
||||
assert.match(page, /await uploadCurrentUnloadPhoto\(path\)[\s\S]*fileId: String\(file\.fileId\)[\s\S]*localPath: path/)
|
||||
assert.match(page, /previous\?\.fileId \? \{ \.\.\.previous, status: 'error'/)
|
||||
assert.match(page, /status: 'uploading'/)
|
||||
assert.match(page, /status: 'error'/)
|
||||
assert.match(page, /已保留原图/)
|
||||
assert.match(page, /photoSlots\[index\]\?\.fileId \? '重拍' : '拍照'/)
|
||||
assert.match(page, /photoSlots\[index\]\?\.fileId \? '重新选择' : '从相册选择'/)
|
||||
assert.match(page, /previewPhoto\(index\)/)
|
||||
assert.match(page, /uploadedPhotoCount\(\) \{ return this\.photoSlots\.filter\(\(item\) => item\?\.fileId\)\.length \}/)
|
||||
assert.match(page, /photosReady\(\) \{ return this\.uploadedPhotoCount === 3 && !this\.photoSlots\.some/)
|
||||
assert.match(page, /:disabled="busy \|\| !photosReady" @tap="signContainer"/)
|
||||
assert.match(page, /async signContainer\(\) \{ if \(!this\.photosReady\) return;/)
|
||||
assert.match(page, /const photos = this\.photoSlots\.map\(/)
|
||||
assert.doesNotMatch(page, /count:\s*9|flatMap\(|photoSlots\[index\]\.push/)
|
||||
})
|
||||
|
||||
test('local thumbnail, preview, and authenticated session restore are wired to the frozen contract', () => {
|
||||
assert.match(page, /restorePhotoPreviews\(\)[\s\S]*photo\?\.downloadPath[\s\S]*downloadCurrentUnloadPhoto\(photo\.downloadPath\)/)
|
||||
assert.deepEqual(photoUiBlockers().map((item) => item.code), [])
|
||||
assert.ok(photoUiBlockers().every((item) => item.deploymentBlocker === true && item.reason))
|
||||
})
|
||||
@@ -11,7 +11,6 @@ test('only operations backed by a dedicated overseas PDA contract are enabled',
|
||||
for (const name of pendingNames) {
|
||||
const operation = operations.find((item) => item.name === name)
|
||||
assert.equal(operation?.available, false, `${name} must fail closed until its PDA API exists`)
|
||||
assert.equal(operation?.badge, '待 PDA 接口')
|
||||
assert.equal(operation?.badge, undefined)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user