feat(客户端更新): 登录页/首页更新面板显示更新包下载进度条
- 新增 shared/utils/update-progress.ts:进度事件解析/百分比钳制/文案格式化(纯函数) - 新增 shared/components/UpdateProgressBar.vue:两页共用,失败态琥珀色并停在断点 百分比、总大小未知走不确定态 - useVersionUpdate:先挂监听再发桥调用(避免丢首帧),监听 pywebview-update-progress (Python 侧 evaluate_js 推送,同 pywebview-download-progress 约定);失败保留上次进度 - 测试:tests/update-progress.test.ts(8 用例) 兼容:老客户端没有该事件源,进度条不出现,其余行为不变(优雅降级)。 注:本仓库 modules-withdraw / modules-image-video 有 3 个既存失败用例(隔离复现), 与本次改动无关;全仓库仅新增测试引用本次新增模块。
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import {
|
||||
formatBytes,
|
||||
formatUpdateProgressText,
|
||||
normalizeUpdateProgress,
|
||||
updateProgressPercent,
|
||||
type UpdateProgress,
|
||||
} from '../src/shared/utils/update-progress.ts'
|
||||
|
||||
function progressOf(partial: Partial<UpdateProgress>): UpdateProgress {
|
||||
return {
|
||||
status: 'downloading',
|
||||
message: '',
|
||||
downloaded: 0,
|
||||
total: 0,
|
||||
percent: -1,
|
||||
...partial,
|
||||
}
|
||||
}
|
||||
|
||||
test('更新进度:正常进度帧解析出字节数与百分比', () => {
|
||||
const progress = normalizeUpdateProgress({
|
||||
status: 'downloading',
|
||||
message: '正在下载更新包...',
|
||||
downloaded: 62914560,
|
||||
total: 104857600,
|
||||
percent: 60,
|
||||
error: '',
|
||||
})
|
||||
assert.ok(progress, '合法事件必须解析成功')
|
||||
assert.equal(progress.status, 'downloading')
|
||||
assert.equal(progress.downloaded, 62914560)
|
||||
assert.equal(progress.total, 104857600)
|
||||
assert.equal(progress.percent, 60)
|
||||
assert.equal(updateProgressPercent(progress), 60)
|
||||
})
|
||||
|
||||
test('更新进度:状态缺失或非法的事件必须丢弃(不得把进度打回初始态)', () => {
|
||||
assert.equal(normalizeUpdateProgress(null), null)
|
||||
assert.equal(normalizeUpdateProgress(undefined), null)
|
||||
assert.equal(normalizeUpdateProgress({}), null)
|
||||
assert.equal(normalizeUpdateProgress({ downloaded: 100 }), null)
|
||||
assert.equal(normalizeUpdateProgress({ status: 'unknown-stage' }), null)
|
||||
assert.equal(normalizeUpdateProgress('downloading'), null)
|
||||
})
|
||||
|
||||
test('更新进度:缺字段的脏事件按 0 字节/未知总大小兜底,不产生 NaN', () => {
|
||||
const progress = normalizeUpdateProgress({ status: 'failed', message: '下载失败' })
|
||||
assert.ok(progress)
|
||||
assert.equal(progress.downloaded, 0)
|
||||
assert.equal(progress.total, 0)
|
||||
assert.equal(progress.percent, -1, '缺百分比按未知处理')
|
||||
assert.equal(updateProgressPercent(progress), -1, '未知总大小走不确定态')
|
||||
assert.equal(Number.isNaN(progress.downloaded), false)
|
||||
})
|
||||
|
||||
test('更新进度:百分比越界钳制到 0-100,负值视为不确定态', () => {
|
||||
assert.equal(updateProgressPercent(progressOf({ percent: 120 })), 100)
|
||||
assert.equal(updateProgressPercent(progressOf({ percent: -5 })), -1)
|
||||
assert.equal(updateProgressPercent(progressOf({ percent: 99.6 })), 100, '四舍五入取整')
|
||||
assert.equal(updateProgressPercent(null), -1)
|
||||
})
|
||||
|
||||
test('更新进度文案:下载中显示百分比与已下载/总大小', () => {
|
||||
const text = formatUpdateProgressText(progressOf({
|
||||
downloaded: 62914560,
|
||||
total: 104857600,
|
||||
percent: 60,
|
||||
}))
|
||||
assert.equal(text, '正在下载更新包 60%(60.0 MB/100.0 MB)')
|
||||
})
|
||||
|
||||
test('更新进度文案:总大小未知时显示已下载量,刚开始时退回阶段文案', () => {
|
||||
assert.equal(
|
||||
formatUpdateProgressText(progressOf({ downloaded: 3145728, percent: -1 })),
|
||||
'正在下载更新包(已下载 3.0 MB)',
|
||||
)
|
||||
assert.equal(
|
||||
formatUpdateProgressText(progressOf({ message: '正在准备下载更新包...' })),
|
||||
'正在准备下载更新包...',
|
||||
)
|
||||
})
|
||||
|
||||
test('更新进度文案:校验中/已就绪/失败直接用 Python 侧说明(失败停在断点处)', () => {
|
||||
assert.equal(
|
||||
formatUpdateProgressText(progressOf({
|
||||
status: 'verifying',
|
||||
message: '安装包下载完成,正在校验完整性...',
|
||||
})),
|
||||
'安装包下载完成,正在校验完整性...',
|
||||
)
|
||||
assert.equal(
|
||||
formatUpdateProgressText(progressOf({
|
||||
status: 'ready',
|
||||
message: '安装包已就绪,正在启动更新程序,程序即将退出...',
|
||||
percent: 100,
|
||||
})),
|
||||
'安装包已就绪,正在启动更新程序,程序即将退出...',
|
||||
)
|
||||
const failed = progressOf({
|
||||
status: 'failed',
|
||||
message: '下载中断(65536/307510 字节),断点已保留,请重试续传',
|
||||
downloaded: 65536,
|
||||
total: 307510,
|
||||
percent: 21.3,
|
||||
})
|
||||
assert.equal(formatUpdateProgressText(failed), '下载中断(65536/307510 字节),断点已保留,请重试续传')
|
||||
assert.equal(updateProgressPercent(failed), 21, '失败时进度条停在断点百分比')
|
||||
assert.equal(formatUpdateProgressText(null), '')
|
||||
})
|
||||
|
||||
test('更新进度文案:字节数格式化覆盖 KB/MB 与异常输入', () => {
|
||||
assert.equal(formatBytes(0), '0 MB')
|
||||
assert.equal(formatBytes(-1), '0 MB')
|
||||
assert.equal(formatBytes(Number.NaN), '0 MB')
|
||||
assert.equal(formatBytes(512 * 1024), '512 KB')
|
||||
assert.equal(formatBytes(3 * 1024 * 1024), '3.0 MB')
|
||||
})
|
||||
Reference in New Issue
Block a user