fix(prediction): 缓存不可用预测结果

This commit is contained in:
2026-05-12 00:52:43 +08:00
parent fad890abe1
commit 779c9c2338
2 changed files with 113 additions and 6 deletions
+77
View File
@@ -0,0 +1,77 @@
import { beforeAll, describe, expect, test } from 'bun:test'
import type { BatteryInfo } from '@/domain/battery'
import { MYSQL_BOOLEAN, POWER_STATUS, toBatteryInfo } from '@/domain/battery'
import type { normalizePrediction as normalizePredictionType } from './client'
type PredictionClientModule = typeof import('./client')
const battery = toBatteryInfo({
id: 10,
userId: 7,
mac: 'RING-A03',
devModel: '2401-A',
devName: 'RING-A03',
isLowPower: MYSQL_BOOLEAN.FALSE,
powerStatus: POWER_STATUS.FULL,
power: 94,
createTime: '2026-05-10 23:00:00',
remark: null,
})
const predictionResponse = {
battery_id: 10,
mac: 'RING-A03',
now_soh: 91,
month_soh: 89,
trmonth_soh: 84,
risk_score: null,
risk_level: null,
status: null,
model_name: 'xgboost',
cycles_used: 6,
updated_at: '2026-05-11T00:00:00.000Z',
}
let createPredictionRequest: PredictionClientModule['createPredictionRequest']
let isPredictionForBattery: PredictionClientModule['isPredictionForBattery']
let normalizePrediction: typeof normalizePredictionType
beforeAll(async () => {
process.env.DATABASE_URL = 'mysql://user:password@localhost:3306/database'
process.env.SOH_PREDICTION_API_BASE_URL = 'http://127.0.0.1:8000'
const client = await import('./client')
createPredictionRequest = client.createPredictionRequest
isPredictionForBattery = client.isPredictionForBattery
normalizePrediction = client.normalizePrediction
})
describe('prediction client helpers', () => {
test('normalizes prediction response shape without fake fallback values', () => {
const prediction = normalizePrediction(predictionResponse)
expect(prediction).toEqual({
batteryId: 10,
mac: 'RING-A03',
nowSoh: 91,
monthSoh: 89,
trmonthSoh: 84,
riskScore: null,
riskLevel: null,
status: null,
modelName: 'xgboost',
cyclesUsed: 6,
updatedAt: '2026-05-11T00:00:00.000Z',
})
})
test('requires prediction responses to belong to the requested battery', () => {
expect(isPredictionForBattery(normalizePrediction(predictionResponse), battery)).toBe(true)
expect(isPredictionForBattery({ batteryId: 11, mac: battery.mac }, battery as BatteryInfo)).toBe(false)
expect(isPredictionForBattery({ batteryId: battery.id, mac: 'RING-B11' }, battery as BatteryInfo)).toBe(false)
})
test('returns null for history-insufficient prediction requests', () => {
expect(createPredictionRequest(battery, [battery, battery, battery, battery])).toBeNull()
})
})