fix: reduce userscript page blocking and stale option clicks
This commit is contained in:
@@ -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));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user