Files
story/web/test/subject-save.test.mjs
T

37 lines
2.4 KiB
JavaScript
Raw Normal View History

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);
});