mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-30 04:40:18 +08:00
fix: apply pending correctness fixes
Cherry-pick the still-relevant fixes from recent draft PRs without pulling in stale release/docs changes: - serialize dashboard data loads to avoid concurrent config self-heal writes - preserve valid per-model default blocks during dashboard model self-heal - pass structured humanizeError results directly to toast for model import scan failures - align frontend kernel isLatest with suffix-aware recommended version ordering Verification: - node --test tests/*.test.js - npm run build
This commit is contained in:
17
tests/humanize-error.test.js
Normal file
17
tests/humanize-error.test.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { humanizeError, humanizeErrorText } from '../src/lib/humanize-error.js'
|
||||
|
||||
test('humanizeError must not be coerced with String() or template literals', () => {
|
||||
const h = humanizeError(new Error('ECONNREFUSED 127.0.0.1:443'), 'Import scan failed')
|
||||
assert.equal(typeof h, 'object')
|
||||
assert.equal(String(h), '[object Object]')
|
||||
assert.ok(h.message)
|
||||
})
|
||||
|
||||
test('humanizeErrorText is safe for plain-string contexts', () => {
|
||||
const line = humanizeErrorText(new Error('ENOENT no such file'), 'Import scan failed')
|
||||
assert.match(line, /Import scan failed/)
|
||||
assert.doesNotMatch(line, /\[object Object\]/)
|
||||
})
|
||||
@@ -9,8 +9,8 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { parseVersion, versionGte, buildSnapshot } from '../src/lib/kernel.js'
|
||||
import { FEATURE_CATALOG, KERNEL_FLOOR } from '../src/lib/feature-catalog.js'
|
||||
import { parseVersion, versionGte, buildSnapshot, recommendedIsNewer } from '../src/lib/kernel.js'
|
||||
import { FEATURE_CATALOG, KERNEL_FLOOR, KERNEL_TARGET } from '../src/lib/feature-catalog.js'
|
||||
|
||||
// ============================================================================
|
||||
// parseVersion
|
||||
@@ -160,14 +160,21 @@ test('buildSnapshot edge case: version slightly below 5.6 feature requirement',
|
||||
})
|
||||
|
||||
test('buildSnapshot.isLatest works against KERNEL_TARGET', () => {
|
||||
const at_target = buildSnapshot('openclaw', '2026.5.19')
|
||||
const at_chinese_target = buildSnapshot('openclaw', '2026.5.18-zh.1')
|
||||
const above_target = buildSnapshot('openclaw', '2026.6.0')
|
||||
const below_target = buildSnapshot('openclaw', '2026.5.18')
|
||||
assert.equal(at_target.isLatest, true)
|
||||
assert.equal(at_chinese_target.isLatest, true)
|
||||
assert.equal(above_target.isLatest, true)
|
||||
assert.equal(below_target.isLatest, false)
|
||||
const atOfficial = buildSnapshot('openclaw', KERNEL_TARGET.openclaw.official)
|
||||
const atChinese = buildSnapshot('openclaw', KERNEL_TARGET.openclaw.chinese)
|
||||
const aboveTarget = buildSnapshot('openclaw', '2026.6.0')
|
||||
const belowTarget = buildSnapshot('openclaw', '2026.5.18')
|
||||
assert.equal(atOfficial.isLatest, true)
|
||||
assert.equal(atChinese.isLatest, true)
|
||||
assert.equal(aboveTarget.isLatest, true)
|
||||
assert.equal(belowTarget.isLatest, false)
|
||||
})
|
||||
|
||||
test('recommendedIsNewer matches suffix patch ordering', () => {
|
||||
assert.equal(recommendedIsNewer('2026.5.18-zh.2', '2026.5.18-zh.1'), true)
|
||||
assert.equal(recommendedIsNewer('2026.5.18-zh.1', '2026.5.18-zh.2'), false)
|
||||
assert.equal(recommendedIsNewer('2026.5.18-zh.1', '2026.5.18-zh.1'), false)
|
||||
assert.equal(recommendedIsNewer('2026.5.19', '2026.5.18-zh.9'), true)
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user