feat(version): 桌面端更新面板支持指定版本安装
- 新增公开接口 GET /api/version/list(最近 50 条,字段口径同管理端列表), 桌面端下拉不再拼 OSS 地址(版本包被删后拼地址会 404) - 更新面板(登录页 + 首页)加「指定版本更新」选择器:默认选中最新版, 可选全部已发布版本(含回退),回退/同版给出明确文案与二次确认 - 客户端无需发版:do_update_app(file_url) 本就接受任意版本包直链
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import {
|
||||
classifyTargetVersion,
|
||||
describeTargetVersion,
|
||||
parseVersionList,
|
||||
} from '../src/shared/utils/version-picker.ts'
|
||||
|
||||
/** /api/version/list 响应样例:接口按 created_at DESC 返回(旧版本重传会排最前) */
|
||||
function listResponse(items: Array<Record<string, unknown>>) {
|
||||
return { items }
|
||||
}
|
||||
|
||||
test('版本列表解析:同一版本重复上传只保留先出现(最新)的一条记录', () => {
|
||||
const items = parseVersionList(listResponse([
|
||||
{ id: 9, version: '4.0.13', file_url: 'https://oss/4.0.13-new.zip', created_at: '2026-09-14 10:00' },
|
||||
{ id: 5, version: '4.0.14', file_url: 'https://oss/4.0.14.zip', created_at: '2026-09-14 09:00' },
|
||||
{ id: 2, version: '4.0.13', file_url: 'https://oss/4.0.13-old.zip', created_at: '2026-09-13 10:00' },
|
||||
]))
|
||||
assert.equal(items.length, 2)
|
||||
const reuploaded = items.find((item) => item.version === '4.0.13')
|
||||
assert.equal(reuploaded?.fileUrl, 'https://oss/4.0.13-new.zip', '同版本应取最新上传的包')
|
||||
})
|
||||
|
||||
test('版本列表解析:无下载地址或空版本号的行被丢弃(选了也装不了)', () => {
|
||||
const items = parseVersionList(listResponse([
|
||||
{ id: 1, version: '4.0.14', file_url: 'https://oss/4.0.14.zip', created_at: '2026-09-14 10:36' },
|
||||
{ id: 2, version: '4.0.13', file_url: '', created_at: '2026-09-13 20:00' },
|
||||
{ id: 3, version: ' ', file_url: 'https://oss/blank.zip', created_at: '2026-09-13 19:00' },
|
||||
{ id: 4, version: null, file_url: 'https://oss/null.zip', created_at: '2026-09-13 18:00' },
|
||||
null,
|
||||
'not-an-object',
|
||||
]))
|
||||
assert.deepEqual(items.map((item) => item.version), ['4.0.14'])
|
||||
})
|
||||
|
||||
test('版本列表解析:按版本号从高到低排序,旧版本重传不会排到最前', () => {
|
||||
const items = parseVersionList(listResponse([
|
||||
// 旧版本刚重传:created_at 最新,但版本号最低
|
||||
{ id: 30, version: '4.0.9', file_url: 'https://oss/4.0.9.zip', created_at: '2026-09-14 11:00' },
|
||||
{ id: 29, version: '4.0.14', file_url: 'https://oss/4.0.14.zip', created_at: '2026-09-14 10:00' },
|
||||
{ id: 28, version: '4.0.13', file_url: 'https://oss/4.0.13.zip', created_at: '2026-09-13 20:00' },
|
||||
]))
|
||||
assert.deepEqual(items.map((item) => item.version), ['4.0.14', '4.0.13', '4.0.9'])
|
||||
})
|
||||
|
||||
test('版本列表解析:兼容驼峰字段、v 前缀与空/异常响应', () => {
|
||||
const items = parseVersionList(listResponse([
|
||||
{ id: 1, version: 'v4.0.14', fileUrl: 'https://oss/4.0.14.zip', createdAt: '2026-09-14 10:36' },
|
||||
]))
|
||||
assert.deepEqual(items, [
|
||||
{ id: 1, version: '4.0.14', fileUrl: 'https://oss/4.0.14.zip', createdAt: '2026-09-14 10:36' },
|
||||
])
|
||||
assert.deepEqual(parseVersionList(null), [])
|
||||
assert.deepEqual(parseVersionList({}), [])
|
||||
assert.deepEqual(parseVersionList({ items: 'oops' }), [])
|
||||
})
|
||||
|
||||
test('目标版本判定:高于本机=更新,相等=同版,低于本机=回退', () => {
|
||||
assert.equal(classifyTargetVersion('4.0.12', '4.0.14'), 'newer')
|
||||
assert.equal(classifyTargetVersion('4.0.14', '4.0.14'), 'same')
|
||||
assert.equal(classifyTargetVersion('4.0.14', '4.0.13'), 'older')
|
||||
// 多段补零后仍相等
|
||||
assert.equal(classifyTargetVersion('4.0.14', '4.0.14.0'), 'same')
|
||||
})
|
||||
|
||||
test('目标版本判定:本机版本未知时返回 unknown,不误判为升级', () => {
|
||||
assert.equal(classifyTargetVersion('', '4.0.14'), 'unknown')
|
||||
assert.equal(classifyTargetVersion(undefined as unknown as string, '4.0.14'), 'unknown')
|
||||
assert.equal(classifyTargetVersion('4.0.14', ''), 'unknown')
|
||||
})
|
||||
|
||||
test('回退文案必须写明低于当前版本(回退是显式操作,不得静默降级)', () => {
|
||||
const text = describeTargetVersion('older', '4.0.14', '4.0.13')
|
||||
assert.ok(text.includes('4.0.13'), '文案要带目标版本号')
|
||||
assert.ok(text.includes('低于当前版本'), '回退必须明确提示低于本机版本')
|
||||
assert.ok(text.includes('4.0.14'), '文案要带本机版本号')
|
||||
})
|
||||
|
||||
test('同版与更新文案各自说明动作,本机版本未知时如实说明无法比较', () => {
|
||||
assert.ok(describeTargetVersion('same', '4.0.14', '4.0.14').includes('与当前版本相同'))
|
||||
const newer = describeTargetVersion('newer', '4.0.12', '4.0.14')
|
||||
assert.ok(newer.includes('4.0.12') && newer.includes('4.0.14'))
|
||||
assert.ok(describeTargetVersion('unknown', '', '4.0.14').includes('未读到本机版本'))
|
||||
})
|
||||
Reference in New Issue
Block a user