修复bug

This commit is contained in:
brother7 committed 2026-08-30 00:13:22 +08:00
1 parent c65f00c941
commit 98282d127c
33 files changed
+1104 -167

No files matched your search

+166 -6
View File
@@ -147,6 +147,166 @@ test('team-order customer restore accepts exact final values and rejects any pro
});
});
test('team-order protected-field drift matches the 0.5.156 core-field scope', async () => {
const inpage = await readFile(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8');
const sandbox = { window: {}, URLSearchParams };
vm.runInNewContext(inpage, sandbox);
const inspect = sandbox.window.LTJTOrderAssistant.inspectProtectedSubmitFieldChanges;
const approved = 'chufa_ri=2026-11-08&darenshu=15&ys_danwei1=customer-a&ys_danweiid1=101&ys_jine0=1500&xiadanbeizhu=approved-note';
const current = 'chufa_ri=2026-11-8&darenshu=16&ys_danwei1=customer-b&ys_danweiid1=202&ys_jine0=1600&xiadanbeizhu=current-note';
assert.deepEqual(Array.from(inspect(approved, current)), ['darenshu']);
assert.match(inpage, /__ltjt_approved_form_protected_projection = postInterceptProtectedProjection/);
});
test('team-order live prewrite blocker exposes only changed protected field names', async () => {
const source = await readFile(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8');
const inpage = source.replace(
'inspectProtectedSubmitFieldChanges: protectedSubmitFieldChanges,',
'inspectProtectedSubmitProjection: protectedSubmitProjection,\n inspectProtectedSubmitFieldChanges: protectedSubmitFieldChanges,'
);
let serialized = 'chufa_ri=2026-11-8&darenshu=16&quanrenshu=1&frenshu1=8';
let nativeAjaxCalls = 0;
const form = { elements: { length: 822 } };
const jq = () => ({ serialize: () => serialized });
jq.ajax = () => { nativeAjaxCalls += 1; };
jq.ajax.__ltjt_preflight_guard = true;
jq.ajax.__ltjt_native_ajax = () => { nativeAjaxCalls += 1; };
jq.ajax.__ltjt_intercepted_submits = [{}];
const pageWindow = {
jQuery: jq,
$: jq,
SubmitInfoForm() {},
setTimeout,
clearTimeout,
location: { href: 'https://lwlt.hisy.cc/System/Business/orders_add.asp' }
};
pageWindow.window = pageWindow;
const sandbox = {
window: pageWindow,
document: { querySelector: (selector) => selector === '#ListForm' ? form : null },
location: pageWindow.location,
crypto: globalThis.crypto,
TextEncoder,
URLSearchParams,
Blob,
FormData,
performance,
setTimeout,
clearTimeout,
console
};
vm.runInNewContext(inpage, sandbox);
const assistant = pageWindow.LTJTOrderAssistant;
const approved = 'chufa_ri=2026-11-8&darenshu=15&quanrenshu=1&frenshu1=8';
const approvedProjection = assistant.inspectProtectedSubmitProjection(approved);
const approvedHashBytes = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(approvedProjection));
const approvedHash = Array.from(new Uint8Array(approvedHashBytes), (byte) => byte.toString(16).padStart(2, '0')).join('');
jq.ajax.__ltjt_approved_form_protected_projection = approvedProjection;
const result = await assistant.liveSubmitApproved({
expectedPayloadSha256: 'approved-payload',
expectedFormProtectedFieldsSha256: approvedHash,
expectedRequestProtectedFieldsSha256: approvedHash,
expectedFormFieldCount: 4,
expectedRequestFieldCount: 4
});
assert.equal(result.status, 'live_submit_blocked');
assert.equal(result.write_attempted, false);
assert.equal(result.no_erp_write, true);
assert.equal(nativeAjaxCalls, 0);
assert.deepEqual(JSON.parse(JSON.stringify(result.protected_field_drift)), {
baseline_available: true,
baseline_matches_approved_hash: true,
changed_field_count: 1,
changed_field_names: ['darenshu'],
values_redacted: true
});
assert.deepEqual(Array.from(result.blockers), [
'current protected business fields do not match the approved preflight (changed fields: darenshu)'
]);
});
test('team-order live gate allows numbered receivable drift like 0.5.156', async () => {
const source = await readFile(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8');
const inpage = source.replace(
'inspectProtectedSubmitFieldChanges: protectedSubmitFieldChanges,',
'inspectProtectedSubmitProjection: protectedSubmitProjection,\n inspectProtectedSubmitFieldChanges: protectedSubmitFieldChanges,'
);
const approved = 'chufa_ri=2026-11-8&darenshu=15&quanrenshu=1&frenshu1=8&ys_danwei1=customer-a&ys_danweiid1=101';
const current = 'chufa_ri=2026-11-8&darenshu=15&quanrenshu=1&frenshu1=8&ys_danwei1=customer-b&ys_danweiid1=202';
let serialized = current;
let nativeAjaxCalls = 0;
const form = { elements: { length: 822 } };
const jq = () => ({ serialize: () => serialized });
jq.ajax = () => { throw new Error('preflight guard should be replaced during live submit'); };
jq.ajax.__ltjt_preflight_guard = true;
jq.ajax.__ltjt_native_ajax = (config) => {
nativeAjaxCalls += 1;
config.success?.('下单成功\n团号: TEST-ORDER', 'success');
config.complete?.({}, 'success');
return { readyState: 4, status: 200, abort() {} };
};
jq.ajax.__ltjt_intercepted_submits = [{}];
const pageWindow = {
jQuery: jq,
$: jq,
SubmitInfoForm() {
jq.ajax({
url: '/System/DAT/orders.asp',
type: 'POST',
data: `Act=DoInfoJH&${serialized}`
});
},
setTimeout,
clearTimeout,
location: { href: 'https://lwlt.hisy.cc/System/Business/orders_add.asp' },
alert() {}
};
pageWindow.window = pageWindow;
const sandbox = {
window: pageWindow,
document: {
title: '计划下单/修改',
querySelector: (selector) => selector === '#ListForm' ? form : null,
querySelectorAll: () => []
},
location: pageWindow.location,
crypto: globalThis.crypto,
TextEncoder,
URLSearchParams,
Blob,
FormData,
performance,
setTimeout,
clearTimeout,
console
};
vm.runInNewContext(inpage, sandbox);
const assistant = pageWindow.LTJTOrderAssistant;
const approvedProjection = assistant.inspectProtectedSubmitProjection(approved);
const approvedHashBytes = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(approvedProjection));
const approvedHash = Array.from(new Uint8Array(approvedHashBytes), (byte) => byte.toString(16).padStart(2, '0')).join('');
jq.ajax.__ltjt_approved_form_protected_projection = approvedProjection;
const result = await assistant.liveSubmitApproved({
expectedPayloadSha256: 'approved-payload-before-native-receivable-drift',
expectedFormProtectedFieldsSha256: approvedHash,
expectedRequestProtectedFieldsSha256: approvedHash,
expectedFormFieldCount: 6,
expectedRequestFieldCount: 6
});
assert.equal(result.status, 'live_submit_completed');
assert.equal(result.write_attempted, true);
assert.equal(nativeAjaxCalls, 1);
assert.deepEqual(Array.from(result.blockers), []);
assert.equal(result.submit_safety.approved_form_protected_fields_sha256_matched, true);
assert.equal(result.submit_safety.approved_request_protected_fields_sha256_matched, true);
clearTimeout(jq.ajax.__ltjt_restore_timer);
});
test('split-parent post-write verification retries read-only and falls back after any missed response group', async () => {
const inpage = await readFile(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8');
const createBody = inpage.slice(
@@ -1136,7 +1296,7 @@ test('passenger explicit server success is terminal without a post-save row requ
assert.doesNotMatch(passengerBranch, /passengerRequery|verifyLifecycleOperation/);
assert.doesNotMatch(background, /attemptAutomaticPassengerReconciliation/);
assert.match(background, /名单已取得 ERP 明确成功响应,按业务规则确认录入成功/);
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.158'/);
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.163'/);
});
test('uncertain lifecycle writes can only converge through a read-only plugin requery', async () => {
@@ -1766,7 +1926,7 @@ test('delete guard distinguishes independent, shared child, and shared parent ro
for (const operation of operations) assert.equal(plans.validateOperation(operation).ok, true, plans.validateOperation(operation).blockers.join('; '));
const mapping = JSON.parse(await readFile(new URL('../mappings/lifecycle.mapping.json', import.meta.url), 'utf8'));
assert.equal(mapping.current_extension_version, '0.5.158');
assert.equal(mapping.current_extension_version, '0.5.163');
assert.equal(
mapping.updates.order_update_independent.field_mapped_pending_live_validation['pax.child_no_bed'],
'ertrenshu'
@@ -2148,10 +2308,10 @@ test('schema and browser adapters contain the v2 safety fields and no confirm ov
assert.match(inpage, /`ys_danweiid\$\{index\}`, resolvedCustomerId/);
assert.doesNotMatch(inpage, /product_customer_source_region|sourceRegionCheck|source_reference/);
assert.doesNotMatch(teamBatchInpage, /product_customer_source_region|sourceRegionCheck/);
assert.equal(extensionManifest.version, '0.5.158');
assert.match(inpage, /version: '0\.5\.158'/);
assert.match(teamBatchInpage, /version: '0\.5\.158'/);
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.158'/);
assert.equal(extensionManifest.version, '0.5.163');
assert.match(inpage, /version: '0\.5\.163'/);
assert.match(teamBatchInpage, /version: '0\.5\.163'/);
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.163'/);
assert.match(inpage, /function strictIsoDate\(value\)/);
assert.match(inpage, /const startDate = strictIsoDate\(controlCanonicalValue\(form, 'riqi0'\)\)/);
assert.match(inpage, /const endDate = strictIsoDate\(controlCanonicalValue\(form, 'riqis0'\)\)/);