修复bug
This commit is contained in:
1 parent
c65f00c941
commit
98282d127c
33 files changed
+1104
-167
No files matched your search
@@ -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'\)\)/);
|
||||
|
||||
Reference in new issue
Block a user