37 lines
2.4 KiB
JavaScript
37 lines
2.4 KiB
JavaScript
import test from 'node:test';
|
|||
|
|
import assert from 'node:assert/strict';
|
||
|
|
import { mutationOutcomeUnknown, needsSaveVerification, subjectSaveLabel, subjectMatchesUpdate, verifiedSaveStatus } from '../src/pages/subject-save.ts';
|
||
|
|
|
||
|
|
const original = { id: 'synthetic-elder', household_id: 'synthetic-home', version: 4, preferred_name: '合成长者', profile_data: { interests: ['养花'], background: '合成背景' } };
|
||
|
|
const input = { preferred_name: '合成长者(已编辑)', profile_data: { background: '合成背景', interests: ['养花'] } };
|
||
|
|
const attempt = { householdID: original.household_id, baseVersion: 4, input, status: 'uncertain' };
|
||
|
|
|
||
|
|
test('lost and gateway responses are unknown, while explicit rejection is distinct', () => {
|
||
|
|
for (const status of [0, 408, 500, 502, 503, 504]) assert.equal(mutationOutcomeUnknown({ status }), true);
|
||
|
|
for (const status of [400, 401, 403, 409, 412, 422, 429]) assert.equal(mutationOutcomeUnknown({ status }), false);
|
||
|
|
assert.equal(mutationOutcomeUnknown(new TypeError('network failure')), true);
|
||
|
|
assert.equal(mutationOutcomeUnknown(new SyntaxError('invalid JSON')), true);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a background refresh does not convert an uncertain save into a success label', () => {
|
||
|
|
assert.match(subjectSaveLabel(attempt, false), /尚未确认/);
|
||
|
|
assert.equal(needsSaveVerification(attempt), true);
|
||
|
|
assert.doesNotMatch(subjectSaveLabel(undefined, false), /已保存|最新版本/);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('read-only verification requires matching all submitted fields and a non-stale version', () => {
|
||
|
|
const committed = { ...original, ...input, version: 5 };
|
||
|
|
assert.equal(subjectMatchesUpdate(committed, input), true);
|
||
|
|
assert.equal(verifiedSaveStatus(committed, attempt), 'verified');
|
||
|
|
assert.equal(verifiedSaveStatus(original, attempt), 'uncertain');
|
||
|
|
assert.equal(verifiedSaveStatus({ ...committed, version: 3 }, attempt), 'uncertain');
|
||
|
|
assert.equal(verifiedSaveStatus({ ...committed, preferred_name: '另一项并发修改' }, attempt), 'conflict');
|
||
|
|
assert.equal(verifiedSaveStatus({ ...committed, profile_data: { ...input.profile_data, interests: [] } }, attempt), 'conflict');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('editing after an acknowledged save has a draft label again', () => {
|
||
|
|
assert.equal(subjectSaveLabel({ ...attempt, status: 'saved' }, true), '修改尚未保存');
|
||
|
|
assert.equal(subjectSaveLabel({ ...attempt, status: 'saved' }, false), '服务器已确认保存');
|
||
|
|
assert.equal(needsSaveVerification({ ...attempt, status: 'saved' }), false);
|
||
|
|
});
|