1111
This commit is contained in:
@@ -23,7 +23,7 @@ const dashboardRecord = (name = '演示用户') => ({ user: { id: 1, displayName
|
||||
profile: {}, hasCompletedAssessment: false, tcmResult: { hasCompleted: true, constitutionName: '平和质' } })
|
||||
const deviceStatus = () => ({ connected: true, sceneDevices: { available: 3 } })
|
||||
|
||||
function environment(overrides = {}) {
|
||||
function environment(overrides = {}, ib43Get) {
|
||||
const disposed = [], toasts = [], navigations = [], tokenWrites = [], mounted = []
|
||||
const router = { replace: location => navigations.push(location), push: location => navigations.push(location) }
|
||||
const vue = { defineComponent: options => options, ref: value => ({ value }), reactive: value => value,
|
||||
@@ -43,6 +43,7 @@ function environment(overrides = {}) {
|
||||
const file = path.resolve(root, /\.(vue|ts)$/.test(relative) ? relative : relative + '.ts')
|
||||
const normalized = file.replaceAll('\\', '/')
|
||||
if (normalized.endsWith('services/health.ts')) return { healthApi }
|
||||
if (normalized.endsWith('services/http.ts') && ib43Get) return { default: { get: ib43Get } }
|
||||
if (normalized.endsWith('services/auth.ts')) return { saveTokens: (...args) => tokenWrites.push(args), clearTokens: () => tokenWrites.push('clear') }
|
||||
if (file.endsWith('AppTabBar.vue')) return { default: {} }
|
||||
if (file.endsWith('useDeviceScenes.ts')) return { useDeviceScenes: options => {
|
||||
@@ -158,14 +159,79 @@ async function render(name, values = {}, routePath = '/dashboard') {
|
||||
|
||||
test('home renders a prominent scene, collapsed presets, a real profile entry and the required navigation order', async () => {
|
||||
const record = { ...dashboardRecord(), bmi: 31.1, sceneConfig: { targetHumidity: 55, fanLevel: '1挡', lightBrightnessPercent: 50, lightColorTemperatureKelvin: 2700 } }
|
||||
const html = await render('DashboardView', { loading: false, dashboard: record, homeAssistant: deviceStatus() })
|
||||
for (const value of ['我的舒睡空间', '一键开启舒睡', '查看舒睡设备', '查看体质启动预设', '打开我的健康档案']) assert.ok(html.includes(value), value)
|
||||
const html = await render('DashboardView', { loading: false, dashboard: record, homeAssistant: {
|
||||
...deviceStatus(), scenePresets: [{ deviceName: '米家除湿机', entityId: 'humidifier.keep', action: '恒湿', detail: '目标 55%', available: true }],
|
||||
} })
|
||||
for (const value of ['我的舒睡空间', '一键开启舒睡', '查看舒睡设备', '睡眠数据', '查看体质启动预设', '打开我的健康档案']) assert.ok(html.includes(value), value)
|
||||
assert.match(html, /<details class="startup-preset-details">/)
|
||||
assert.match(html, /米家除湿机/)
|
||||
assert.doesNotMatch(html, /助眠灯光|2700K/)
|
||||
assert.ok(html.indexOf('首页</span>') < html.indexOf('中医四诊</span>'))
|
||||
assert.ok(html.indexOf('中医四诊</span>') < html.indexOf('健康评估</span>'))
|
||||
assert.ok(html.indexOf('健康评估</span>') < html.indexOf('我的</span>'))
|
||||
})
|
||||
|
||||
const sleepBed = { id: 'left-bed', bedName: '卧室左侧', side: 'left', simulation: true, endedAtMs: null }
|
||||
const rightBed = { id: 'right-bed', bedName: '卧室右侧', side: 'right', simulation: false, endedAtMs: null }
|
||||
|
||||
test('sleep data renders stale readings and missing fields separately, with the same time for UTC strings and history milliseconds', async () => {
|
||||
const instant = Date.parse('2026-11-11T01:55:21Z')
|
||||
const readings = {
|
||||
heartRate: { value: 72, receivedAt: '2026-11-11 01:55:21', freshness: 'stale' },
|
||||
respiration: { value: null, receivedAt: '2026-11-11 01:55:21', freshness: 'recent' },
|
||||
snoring: { value: 0, receivedAt: '2026-11-11 01:55:21', freshness: 'stale' },
|
||||
}
|
||||
const html = await render('SleepDataView', {
|
||||
bindingsLoading: false, beds: [sleepBed], bedId: sleepBed.id,
|
||||
current: { bed: sleepBed, active: true, transport: 'connected', readings },
|
||||
history: [{ id: '1', receivedAtMs: String(instant), readings }],
|
||||
}, '/sleep-data')
|
||||
assert.match(html, /模拟设备/)
|
||||
assert.match(html, /数据服务已连接/)
|
||||
assert.match(html, /数据已过期/)
|
||||
assert.match(html, /暂无有效读数/)
|
||||
assert.match(html, /暂无上报/)
|
||||
assert.match(html, /未打鼾/)
|
||||
assert.doesNotMatch(html, /离床/)
|
||||
const { formatIb43Time } = await server.ssrLoadModule('/src/services/ib43.ts')
|
||||
assert.equal(formatIb43Time(readings.heartRate.receivedAt), formatIb43Time(String(instant)))
|
||||
const empty = await render('SleepDataView', { bindingsLoading: false }, '/sleep-data')
|
||||
assert.match(empty, /暂无绑定床位/)
|
||||
assert.doesNotMatch(empty, /最近读数|历史记录/)
|
||||
})
|
||||
|
||||
test('sleep data discards late results from a previous bed and keeps the time range and cursor when paging', async () => {
|
||||
const oldCurrent = deferred(), oldHistory = deferred(), historyRequests = []
|
||||
const cursor = '9007199254740993'
|
||||
const env = environment({}, async (url, options) => {
|
||||
if (url.endsWith('/bindings')) return [sleepBed, rightBed]
|
||||
if (url.includes('/left-bed/')) return url.endsWith('/current') ? oldCurrent.promise : oldHistory.promise
|
||||
if (url.endsWith('/right-bed/current')) return { bed: rightBed, readings: {} }
|
||||
if (url.endsWith('/right-bed/history')) {
|
||||
historyRequests.push(options.params)
|
||||
return options.params.beforeId == null ? { items: [{ id: 'right-1' }], nextBeforeId: cursor } :
|
||||
{ items: [{ id: 'right-2' }], nextBeforeId: null }
|
||||
}
|
||||
throw new Error(`Unexpected request: ${url}`)
|
||||
})
|
||||
const page = env.page('SleepDataView')
|
||||
await page.loadBindings()
|
||||
assert.equal(page.bedId.value, 'left-bed')
|
||||
page.bedId.value = 'right-bed'
|
||||
page.loadBed()
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
oldCurrent.resolve({ bed: sleepBed }); oldHistory.resolve({ items: [{ id: 'left-1' }] })
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
assert.equal(page.current.value.bed.id, 'right-bed')
|
||||
assert.equal(page.history.value[0].id, 'right-1')
|
||||
await page.loadHistory(true)
|
||||
assert.equal(historyRequests[1].beforeId, cursor)
|
||||
assert.equal(historyRequests[1].fromMs, historyRequests[0].fromMs)
|
||||
assert.equal(historyRequests[1].toMs, historyRequests[0].toMs)
|
||||
assert.equal(page.history.value[1].id, 'right-2')
|
||||
assert.equal(page.nextBeforeId.value, undefined)
|
||||
})
|
||||
|
||||
test('error pages render retry controls without mistaken missing-assessment or device actions', async () => {
|
||||
for (const [name, path] of [['DashboardView', '/dashboard'], ['ProfileView', '/profile']]) {
|
||||
const html = await render(name, { loading: false, loadError: '测试连接失败' }, path)
|
||||
|
||||
Reference in New Issue
Block a user