67 lines
2.6 KiB
JavaScript
67 lines
2.6 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import test from 'node:test'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
import {
|
|
createRiskDispositionRequestId,
|
|
normalizeRiskDisposition,
|
|
normalizeRiskObservation
|
|
} from '../src/services/riskObservations.js'
|
|
|
|
const evidenceCard = readFileSync(
|
|
fileURLToPath(new URL('../src/components/travel/RiskObservationEvidenceCard.vue', import.meta.url)),
|
|
'utf8'
|
|
)
|
|
|
|
test('risk observation normalizes persisted json evidence and typed disposition', () => {
|
|
const observation = normalizeRiskObservation({
|
|
id: 'risk-1',
|
|
contribution_scores_json: { S_rule: 90 },
|
|
evidence_json: [{ title: '重复票据' }],
|
|
graph_node_keys_json: ['claim:1'],
|
|
similar_case_claim_ids_json: ['redacted-for-reviewer-only'],
|
|
decision_trace_json: { action: 'manual_review' },
|
|
disposition: {
|
|
id: 'disposition-1',
|
|
observation_id: 'risk-1',
|
|
adjudication: 'confirmed',
|
|
lifecycle_status: 'remediation_in_progress',
|
|
version: 2,
|
|
events: [{ id: 'event-1', action: 'confirm', version: 1 }]
|
|
}
|
|
})
|
|
|
|
assert.equal(observation.contributionScores.S_rule, 90)
|
|
assert.equal(observation.evidence[0].title, '重复票据')
|
|
assert.deepEqual(observation.graphNodeKeys, ['claim:1'])
|
|
assert.equal(observation.decisionTrace.action, 'manual_review')
|
|
assert.equal(observation.disposition.lifecycleStatus, 'remediation_in_progress')
|
|
assert.equal(observation.disposition.events[0].action, 'confirm')
|
|
})
|
|
|
|
test('risk disposition normalizer rejects absent projection and keeps version', () => {
|
|
assert.equal(normalizeRiskDisposition(null), null)
|
|
assert.equal(normalizeRiskDisposition({}), null)
|
|
assert.equal(normalizeRiskDisposition({ id: 'd1', version: 4 }).version, 4)
|
|
})
|
|
|
|
test('risk evidence card exposes typed actions and never offers direct approval', () => {
|
|
assert.match(evidenceCard, /executeRiskDispositionAction/)
|
|
assert.match(evidenceCard, /确认风险/)
|
|
assert.match(evidenceCard, /标记误报/)
|
|
assert.match(evidenceCard, /请求补材料/)
|
|
assert.match(evidenceCard, /启动整改/)
|
|
assert.match(evidenceCard, /申请豁免/)
|
|
assert.match(evidenceCard, /确认已解决/)
|
|
assert.match(evidenceCard, /expectedVersion: currentDisposition\.value\.version/)
|
|
assert.doesNotMatch(evidenceCard, /自动审批|直接通过|batchApprove/)
|
|
assert.match(evidenceCard, /RISK_DISPOSITION_VERSION_CONFLICT/)
|
|
assert.match(evidenceCard, /lifecycle !== 'supplement_requested'/)
|
|
})
|
|
|
|
test('risk action request ids bind action and observation', () => {
|
|
const requestId = createRiskDispositionRequestId('confirm', 'risk-1')
|
|
assert.match(requestId, /^risk:confirm:risk-1:/)
|
|
})
|