fix: reduce userscript page blocking and stale option clicks

This commit is contained in:
suanyuit-cyber
2026-10-30 01:47:03 +08:00
parent 26e0a920b6
commit 4bf2de1bad
12 changed files with 1128 additions and 170 deletions
+71
View File
@@ -709,3 +709,74 @@ test('metadata validation refuses corrupt occurrences and preserves explicit ali
assert.deepEqual(core.normalizeRecord(JSON.parse(JSON.stringify(record))), record);
assert.deepEqual(core.fromCSV(core.toCSV([record])), [record]);
});
test('indexed aliases retain traversal order when a later match reveals more aliases', () => {
const rows = [
fixture({ questionId: 'root', questionIdAliases: ['root', 'bridge'], explanation: '根记录' }),
fixture({ questionId: 'earlier', explanation: '较早记录' }),
fixture({ questionId: 'bridge', questionIdAliases: ['bridge', 'earlier', 'later', 'after'], explanation: '桥接记录' }),
fixture({ questionId: 'later', explanation: '最后记录' }),
fixture({ questionId: 'bridge', bankId: 'other-bank', explanation: '另一题库' }),
fixture({ questionId: 'later', stem: '同ID别名但内容不同' }),
fixture({ questionId: 'after', explanation: '后续新增别名记录' }),
];
const result = core.upsert([], rows);
assert.deepEqual(result.map(record => [record.bankId, record.questionId]), [
['bank-1', 'root'], ['bank-1', 'earlier'], ['bank-1', 'later'], ['other-bank', 'bridge']
]);
// The late alias was not known while visiting the earlier position. Preserve
// that existing one-pass behavior rather than changing the answer's history.
assert.deepEqual(result[0].questionIdAliases, ['root', 'bridge', 'earlier', 'later', 'after']);
assert.equal(result[0].explanation, '后续新增别名记录');
assert.equal(result[2].answerStatus, 'conflict');
assert.deepEqual(core.fromCSV(core.toCSV(result)), result);
});
test('indexed anonymous promotion remains unique in both directions and preserves record order', () => {
const rows = [
fixture({ questionId: '', contentOccurrence: 0 }),
fixture({ questionId: 'unrelated', stem: '另一个题干' }),
fixture({ questionId: '', contentOccurrence: 1 }),
fixture({ questionId: 'ambiguous' }),
fixture({ questionId: 'unique', stem: '唯一可升级题干' }),
fixture({ questionId: '', stem: '唯一可升级题干', explanation: '后出现的说明' }),
];
const result = core.upsert([], rows);
assert.deepEqual(result.map(record => record.questionId), ['', 'unrelated', '', 'ambiguous', 'unique']);
assert.deepEqual(result.filter(record => !record.questionId).map(record => record.contentOccurrence), [0, 1]);
assert.equal(result.at(-1).explanation, '后出现的说明');
});
test('fast internal merges preserve fresh DOM metadata and revalidate externally mutated inputs', () => {
const original = core.normalizeRecord(fixture({ questionIndex: 3, contentOccurrence: 0, questionIdAliases: ['old'] }));
const dom = { ...original, answerStatus: 'missing', correctOptionIds: [], answerTexts: [], explanation: '新增解析',
questionIdAliases: ['another-id'], updatedAt: '2026-10-30T01:00:00Z',
source: { kind: 'dom', url: 'https://practice.example.test/new', observedAt: '2026-10-30T01:00:00Z' } };
const merged = core.upsert([original], [dom])[0];
assert.deepEqual(merged.answerTexts, original.answerTexts);
assert.deepEqual(merged.correctOptionIds, original.correctOptionIds);
assert.deepEqual(merged.answerSource, original.answerSource);
assert.deepEqual(merged.source, dom.source);
assert.equal(merged.updatedAt, dom.updatedAt);
assert.equal(merged.explanation, dom.explanation);
assert.deepEqual(merged.questionIdAliases, ['old', original.questionId, 'another-id']);
assert.equal(merged.questionIndex, 3);
assert.equal(merged.contentOccurrence, 0);
dom.options = dom.options.map(option => option.id === 'y' ? { ...option, text: '改变选项内容' } : option);
assert.equal(core.upsert([original], [dom])[0].answerStatus, 'conflict');
assert.equal(original.options.find(option => option.id === 'y').text, '提高温度');
});
test('large repeated alias banks preserve every canonical record and complete CSV content', () => {
const records = Array.from({ length: 600 }, (_, index) => core.normalizeRecord(fixture({
questionId: `canonical-${index}`, questionIdAliases: [`canonical-${index}`, `old-${index}`],
stem: `设备检查${index}:P水 > P气,面积2m²`, questionIndex: index, contentOccurrence: 0,
source: { kind: 'network', url: 'https://example.test/upm/start', observedAt: '2026-10-29T00:00:00Z', batchId: 'complete-list' }
})));
const result = core.upsert(records, records);
assert.equal(JSON.stringify(result), JSON.stringify(records));
assert.equal(core.toCSV(result), core.toCSV(records));
const compacted = core.compactRecords(result);
assert.equal(compacted.removed, 0);
assert.equal(JSON.stringify(compacted.records), JSON.stringify(records));
});