feat(approval): add safe risk disposition workflow
This commit is contained in:
66
web/tests/risk-disposition-ui.test.mjs
Normal file
66
web/tests/risk-disposition-ui.test.mjs
Normal file
@@ -0,0 +1,66 @@
|
||||
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:/)
|
||||
})
|
||||
Reference in New Issue
Block a user