变更问题修复

This commit is contained in:
andy committed 2026-09-14 16:34:36 +08:00
1 parent 6de4422733
commit 9625110f44
62 files changed
+18116 -95

No files matched your search

+73 -4
View File
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import vm from 'node:vm';
import { readFileSync } from 'node:fs';
import { loadPageActionRealm } from './page-action-test-realm.mjs';
const inpage = readFileSync(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8')
.replace('inspectArrangementLookupReadiness(form,', 'testResolveHotel: resolveArrangementExecutionOperation,\n inspectArrangementLookupReadiness(form,');
@@ -14,7 +14,7 @@ const adapter = readFileSync(new URL('../chrome-extension/ltjt-order-assistant/l
assistant.testResource = arrangementResourceProof;
assistant.preflightLifecycleOperation = preflightLifecycleOperation;`);
function fixture({ duplicate = false, slotIndex = 1, onSelection = () => {} } = {}) {
function fixture({ duplicate = false, slotIndex = 1, onSelection = () => {}, omitDateMatcher = false } = {}) {
let now = 10000;
let nativeSelections = 0;
const form = { elements: [], id: 'InfoForm1' };
@@ -60,8 +60,7 @@ function fixture({ duplicate = false, slotIndex = 1, onSelection = () => {} } =
setTimeout(callback, ms) { now += ms; callback(); }
};
window.setTimeout = sandbox.setTimeout;
vm.runInNewContext(inpage, sandbox);
vm.runInNewContext(adapter, sandbox);
loadPageActionRealm(window, sandbox, { 'inpage.js': inpage, 'lifecycle-adapters.js': adapter }, omitDateMatcher ? ['operation-plans.js'] : []);
const api = window.LTJTOrderAssistant;
const input = {
action: 'arrangement_hotel', data: {
@@ -106,6 +105,34 @@ test('hotel replacement resolves a dated existing row and uses native linked sel
}
});
test('fresh ERP MAIN world resolves the reported 2027 hotel update using the actual injection list', async () => {
const f = fixture();
f.fields.get('riqi1').value = '2027-9-12';
f.fields.get('riqis1').value = '2027-9-13';
f.input.data.existing_refs.identifier = 'LLW-270911A-A';
f.input.data.arrangement.selection = { start_date: '09-12', end_date: '09-13' };
f.input.data.arrangement.changes.room_count = 10;
const resolved = f.api.testResolveHotel(f.form, f.input);
assert.equal(resolved.ok, true, JSON.stringify(resolved));
assert.equal(resolved.operation.data.arrangement.start_date, '2027-09-12');
assert.equal(resolved.operation.data.arrangement.end_date, '2027-09-13');
const result = await f.api.testApply(f.form, resolved.operation);
assert.equal(result.blockers.length, 0, JSON.stringify(result));
assert.equal(f.fields.get('jianshu1').value, '10');
assert.equal(f.fields.get('riqi1').value, '2027-9-12');
assert.equal(f.fields.get('riqis1').value, '2027-9-13');
});
test('missing page date dependency is diagnosed before matching and never reported as zero ERP records', () => {
const f = fixture({ omitDateMatcher: true });
const before = [...f.fields].map(([key, control]) => [key, control.value]);
const resolved = f.api.testResolveHotel(f.form, f.input);
assert.equal(resolved.ok, false);
assert.deepEqual(Array.from(resolved.blockers), ['arrangement_date_matcher_unavailable']);
assert.equal(f.nativeSelections(), 0);
assert.deepEqual([...f.fields].map(([key, control]) => [key, control.value]), before);
});
test('hotel replacement stops on ambiguous or missing dated rows before selecting a hotel', () => {
const duplicate = fixture({ duplicate: true });
const result = duplicate.api.testResolveHotel(duplicate.form, duplicate.input);
@@ -135,3 +162,45 @@ test('hotel replacement rejects native callbacks that change another row or chan
assert.ok(result.blockers.length, field);
}
});
test('month/day hotel selector freezes the unique actual ERP year and preserves native dates on replacement', async () => {
for (const year of [2026, 2027]) {
const f = fixture();
f.fields.get('riqi1').value = `${year}-9-4`;
f.fields.get('riqis1').value = `${year}-9-5`;
f.input.data.arrangement.selection = { start_date: '09-04', end_date: '09-05' };
const resolved = f.api.testResolveHotel(f.form, f.input);
assert.equal(resolved.ok, true, JSON.stringify(resolved));
assert.equal(resolved.operation.data.arrangement.start_date, `${year}-09-04`);
assert.equal(resolved.operation.data.arrangement.end_date, `${year}-09-05`);
assert.equal(resolved.operation.data.arrangement.selection, undefined);
const applied = await f.api.testApply(f.form, resolved.operation);
assert.equal(applied.blockers.length, 0, JSON.stringify(applied));
assert.equal(f.fields.get('riqi1').value, `${year}-9-4`);
assert.equal(f.fields.get('riqis1').value, `${year}-9-5`);
}
});
test('cross-year duplicate month/day rows remain ambiguous and report original dates before any mutation', () => {
const f = fixture();
for (const [index, year] of [[0,2026],[1,2027]]) {
f.fields.get(`riqi${index}`).value = `${year}-12-31`;
f.fields.get(`riqis${index}`).value = `${year+1}-1-2`;
}
f.input.data.arrangement.selection = { start_date: '12-31', end_date: '01-02' };
let resolved = f.api.testResolveHotel(f.form, f.input);
assert.equal(resolved.ok, false);
assert.match(resolved.blockers.join(), /target_candidate_count:2/);
assert.equal(resolved.evidence.candidates[0].date, '2026-12-31');
assert.equal(resolved.evidence.candidates[1].end_date, '2028-01-02');
assert.equal(f.nativeSelections(), 0);
f.input.data.arrangement.selection.start_date = '2027-12-31';
resolved = f.api.testResolveHotel(f.form, f.input);
assert.equal(resolved.ok, true);
assert.equal(resolved.operation.data.arrangement.target.slot_index, 1);
f.input.data.arrangement.selection.end_date = '2027-01-02';
assert.equal(f.api.testResolveHotel(f.form, f.input).ok, false, 'explicit wrong year must not fall back to month/day');
f.input.data.arrangement.selection = { start_date: '02-30', end_date: '03-01' };
f.fields.get('riqi1').value = '2026-02-30';
assert.equal(f.api.testResolveHotel(f.form, f.input).ok, false, 'invalid actual dates never match');
});