177 lines
7.5 KiB
JavaScript
177 lines
7.5 KiB
JavaScript
const assert = require('node:assert/strict')
|
|
const fs = require('node:fs')
|
|
const path = require('node:path')
|
|
const { test } = require('node:test')
|
|
const ts = require('typescript')
|
|
|
|
function loadTypeScript(file, mocks = {}) {
|
|
const source = fs.readFileSync(path.join(__dirname, '../src', file), 'utf8')
|
|
const { outputText } = ts.transpileModule(source, {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2017, esModuleInterop: true },
|
|
})
|
|
const module = { exports: {} }
|
|
new Function('require', 'module', 'exports', outputText)(
|
|
(id) => mocks[id] || (id.startsWith('.')
|
|
? loadTypeScript(path.join(path.dirname(file), `${id}.ts`), mocks)
|
|
: require(id)), module, module.exports,
|
|
)
|
|
return module.exports
|
|
}
|
|
|
|
const { firmwareProgressView } = loadTypeScript('components/firmware-progress/view-model.ts')
|
|
const status = (state, progress) => ({ device_id: 'test-device', update_status: state, progress, latest_version: '1.8.2' })
|
|
|
|
test('accepted update without reported progress stays indeterminate', () => {
|
|
const view = firmwareProgressView(status('accepted', 0))
|
|
assert.equal(view.hasProgress, false)
|
|
assert.match(view.message, /等待进度上报/)
|
|
})
|
|
test('received progress is used directly, including fractional values', () => {
|
|
const view = firmwareProgressView(status('updating', 65.4))
|
|
assert.equal(view.progress, 65.4)
|
|
assert.equal(view.percent, 65)
|
|
assert.equal(view.complete, false)
|
|
})
|
|
test('nearly complete progress never rounds up to 100', () => {
|
|
assert.equal(firmwareProgressView(status('updating', 99.9)).percent, 99)
|
|
})
|
|
test('100 percent still waits for the device success result', () => {
|
|
const view = firmwareProgressView(status('updating', 100))
|
|
assert.equal(view.complete, false)
|
|
assert.match(view.message, /等待设备确认/)
|
|
})
|
|
test('both backend completion statuses show a completed update', () => {
|
|
for (const state of ['success', 'completed']) {
|
|
const view = firmwareProgressView(status(state, 0))
|
|
assert.equal(view.complete, true)
|
|
assert.equal(view.percent, 100)
|
|
}
|
|
})
|
|
test('failed update keeps the last real progress and offers recovery copy', () => {
|
|
const view = firmwareProgressView(status('failed', 42))
|
|
assert.equal(view.failed, true)
|
|
assert.equal(view.progress, 42)
|
|
assert.match(view.message, /重试/)
|
|
})
|
|
test('temporary query failure is not reported as an OTA failure', () => {
|
|
const view = firmwareProgressView(status('updating', 42), true)
|
|
assert.equal(view.failed, false)
|
|
assert.equal(view.progress, 42)
|
|
assert.match(view.message, /暂时无法刷新/)
|
|
})
|
|
test('invalid progress cannot overflow or break the display', () => {
|
|
for (const value of [undefined, NaN, Infinity, -10]) {
|
|
assert.equal(firmwareProgressView(status('updating', value)).hasProgress, false)
|
|
}
|
|
assert.equal(firmwareProgressView(status('updating', 120)).progress, 100)
|
|
})
|
|
test('backend placeholder version is not displayed as a release number', () => {
|
|
const view = firmwareProgressView({ ...status('updating', 12), target_version: 'updating' })
|
|
assert.equal(view.version, '1.8.2')
|
|
})
|
|
test('custom pages clear the capsule while native pages only add content spacing', () => {
|
|
const { getPageStyle } = loadTypeScript('utils/page-style.ts', {
|
|
'@tarojs/taro': {
|
|
getSystemInfoSync: () => ({ statusBarHeight: 44 }),
|
|
getMenuButtonBoundingClientRect: () => ({ bottom: 90 }),
|
|
},
|
|
})
|
|
assert.equal(getPageStyle()['--bb-navigation-top'], '102px')
|
|
assert.equal(getPageStyle(false)['--bb-navigation-top'], '12px')
|
|
})
|
|
|
|
const { firmwareSummaryView } = loadTypeScript('utils/firmware-status.ts')
|
|
const currentFirmware = { device_id: 'test-device', current_version: '1.8.2', latest_version: '1.8.2', update_available: false, can_update: false, update_status: 'failed', progress: 40 }
|
|
|
|
test('latest version takes precedence over a historical failed update in the summary', () => {
|
|
assert.deepEqual(firmwareSummaryView(currentFirmware), { action: '已最新', subtitle: '当前已是最新版本' })
|
|
const view = firmwareProgressView(currentFirmware)
|
|
assert.equal(view.current, true)
|
|
assert.equal(view.failed, false)
|
|
assert.equal(view.complete, false) // Current firmware does not rewrite the historical OTA outcome.
|
|
assert.equal(view.title, '当前已是最新版本')
|
|
assert.equal(view.version, '1.8.2')
|
|
})
|
|
|
|
test('a failed update with a newer version still offers a retry', () => {
|
|
const pending = { ...currentFirmware, current_version: '1.8.1', update_available: true, can_update: true }
|
|
assert.deepEqual(firmwareSummaryView(pending), { action: '更新', subtitle: '更新失败,可重试' })
|
|
assert.equal(firmwareProgressView(pending).failed, true)
|
|
})
|
|
|
|
test('an active update whose target version is already installed is settled', () => {
|
|
const settled = {
|
|
...currentFirmware,
|
|
current_version: '1.8.3',
|
|
latest_version: '1.8.4',
|
|
target_version: '1.8.3',
|
|
update_available: true,
|
|
can_update: true,
|
|
update_status: 'accepted',
|
|
progress: 0,
|
|
}
|
|
assert.deepEqual(firmwareSummaryView(settled), { action: '更新', subtitle: '发现可更新版本' })
|
|
const view = firmwareProgressView(settled)
|
|
assert.equal(view.complete, true)
|
|
assert.equal(view.progress, 100)
|
|
assert.match(view.message, /已完成更新/)
|
|
})
|
|
|
|
test('an active update below its target stays in progress even at 100 percent', () => {
|
|
const pending = {
|
|
...currentFirmware,
|
|
current_version: '1.8.2',
|
|
target_version: '1.8.3',
|
|
latest_version: '1.8.4',
|
|
update_available: true,
|
|
can_update: true,
|
|
update_status: 'updating',
|
|
progress: 100,
|
|
}
|
|
assert.deepEqual(firmwareSummaryView(pending), { action: '查看进度', subtitle: '设备正在更新,请稍候' })
|
|
assert.equal(firmwareProgressView(pending).complete, false)
|
|
})
|
|
|
|
test('missing or placeholder versions never claim the device is up to date', () => {
|
|
const cases = [null, ...['', 'unknown', '0.0.0', '--', 'updating'].flatMap(value => [
|
|
{ ...currentFirmware, current_version: value }, { ...currentFirmware, latest_version: value },
|
|
])]
|
|
for (const value of cases) {
|
|
assert.notEqual(firmwareSummaryView(value).action, '已最新')
|
|
assert.equal(firmwareProgressView(value).current, false)
|
|
}
|
|
})
|
|
|
|
test('an active update continues showing progress even after the version has changed', () => {
|
|
for (const update_status of ['sent', 'accepted', 'updating']) {
|
|
const updating = { ...currentFirmware, update_status }
|
|
assert.equal(firmwareSummaryView(updating).action, '查看进度')
|
|
assert.equal(firmwareProgressView(updating).current, false)
|
|
}
|
|
})
|
|
|
|
test('title rows align to the capsule and reserve its width on both sides', () => {
|
|
const { getPageStyle } = loadTypeScript('utils/page-style.ts', {
|
|
'@tarojs/taro': {
|
|
getSystemInfoSync: () => ({ statusBarHeight: 44, windowWidth: 375 }),
|
|
getMenuButtonBoundingClientRect: () => ({ top: 50, bottom: 82, height: 32, left: 278 }),
|
|
},
|
|
})
|
|
const style = getPageStyle()
|
|
assert.equal(style['--bb-navigation-bar-top'], '50px')
|
|
assert.equal(style['--bb-navigation-bar-height'], '32px')
|
|
assert.equal(style['--bb-navigation-side'], '105px')
|
|
})
|
|
|
|
test('navigation keeps usable dimensions when the capsule is unavailable', () => {
|
|
const { getPageStyle } = loadTypeScript('utils/page-style.ts', {
|
|
'@tarojs/taro': {
|
|
getSystemInfoSync: () => ({ statusBarHeight: 24 }),
|
|
getMenuButtonBoundingClientRect: () => { throw new Error('unavailable') },
|
|
},
|
|
})
|
|
const style = getPageStyle()
|
|
assert.equal(style['--bb-navigation-bar-top'], '30px')
|
|
assert.equal(style['--bb-navigation-bar-height'], '32px')
|
|
})
|