Files
LWLT-AIBOT/tools/record-split-probe-result.test.mjs
2026-08-25 10:33:29 +08:00

136 lines
5.5 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { recordSplitProbeResult } from './record_split_probe_result.mjs';
function fixture() {
const runId = 'sept-2026-lifecycle-contract-split-probe';
const marker = 'TEST-202609';
const account = 'AI_TEST_ACCOUNT';
const allowlistId = 'ALLOW-CONTRACT-SPLIT-PROBE';
const targetDates = ['2026-09-02', '2026-09-15', '2026-09-28'];
const state = {
run: {
run_id: runId,
marker,
account,
native_baseline_id: 'contract-baseline-shared-batch-split',
target_dates: targetDates
},
creation: {
order_suffix: 'TEST-202609-E2E3',
shared: {
batch_dates: targetDates,
batch_split_order_probe: true
}
},
cleanup: {
allowlist_id: allowlistId,
objects: [],
shared_plans_with_no_children: [],
delete_authorized: false
}
};
const allowlist = {
allowlist_id: allowlistId,
run_id: runId,
marker,
account,
created_refs: [],
delete_enabled: false,
delete_authorized: false
};
return { state, allowlist };
}
function resultFor(state, { children = true, incomplete = false } = {}) {
const dates = [...state.creation.shared.batch_dates].sort();
const perDate = dates.map((date, index) => {
const compact = date.replaceAll('-', '').slice(2);
const tid = String(17001 + index);
const ddid = String(18001 + index);
return {
// ERP list responses use non-zero-padded month/day values such as 2026-9-2.
date: date.replace(/-0(\d)/g, '-$1'),
facts_determined: !incomplete || index !== 1,
outcome: children ? 'concrete_shared_children_with_requested_facts' : 'parent_row_facts_without_concrete_child',
parent_group_no: `LW-${compact}TEST-202609-E2E3-A`,
parent_tid: tid,
customer_requested: true,
customer_persisted_on_native_list: true,
passenger_counts_requested: true,
passenger_counts_persisted_on_native_list: true,
child_reference_scan_complete: true,
child_count: children ? 1 : 0,
child_refs: children ? [{ tid, ddid, child_order_no: `D${ddid}`, value_redacted: true }] : [],
ownership: { group_suffix_matched: true, marker_matched: true, account_matched: true }
};
});
const groupNumbers = perDate.map((fact) => fact.parent_group_no);
return {
extension: {
status: children ? 'completed' : 'execution_uncertain',
write_attempted: true,
no_erp_write: false,
manual_review_required: !children,
erp_receipt: {
group_numbers: groupNumbers,
split_order_probe: {
status: incomplete ? 'partial_dates_facts_determined' : 'all_dates_facts_determined',
per_date: perDate,
manual_review_required: !children
}
},
verification: {
status: incomplete ? 'parent_groups_partial' : 'parent_groups_and_split_order_facts_determined',
group_numbers: groupNumbers,
split_order_probe: {
facts_status: incomplete ? 'partial_dates_facts_determined' : 'all_dates_facts_determined',
per_date: perDate
}
}
}
};
}
test('records every C04 parent and concrete child into state and canonical allowlist refs', async () => {
const { state, allowlist } = await fixture();
const existingStateRefCount = state.cleanup.objects.length;
const existingAllowlistRefCount = allowlist.created_refs.length;
const result = recordSplitProbeResult(state, allowlist, resultFor(state), state.run.run_id);
assert.equal(result.recorded_refs.length, 6);
assert.equal(result.recorded_refs.filter((ref) => ref.kind === 'shared_plan').length, 3);
assert.equal(result.recorded_refs.filter((ref) => ref.kind === 'shared_child_order').length, 3);
assert.equal(result.state.cleanup.objects.length, existingStateRefCount + 6);
assert.equal(result.allowlist.created_refs.length, existingAllowlistRefCount + 6);
assert.equal(Object.hasOwn(result.allowlist, 'created_objects'), false);
assert.equal(result.allowlist.delete_enabled, false);
assert.equal(result.allowlist.delete_authorized, false);
assert.equal(result.business_child_creation_passed, true);
assert.ok(result.recorded_refs.every((ref) => /^\d{4}-\d{2}-\d{2}$/.test(ref.departure_date)));
assert.equal(result.recorded_refs[0].departure_date, '2026-09-02');
});
test('records parent-only facts for cleanup without declaring batch child creation successful', async () => {
const { state, allowlist } = await fixture();
const existingChildFreeParents = [...(state.cleanup.shared_plans_with_no_children || [])];
const result = recordSplitProbeResult(state, allowlist, resultFor(state, { children: false }), state.run.run_id);
assert.equal(result.recorded_refs.length, 3);
assert.ok(result.recorded_refs.every((ref) => ref.kind === 'shared_plan'));
assert.equal(result.business_child_creation_passed, false);
assert.equal(result.state.creation_evidence.shared_batch_split_order_probe.manual_review_required, true);
assert.deepEqual(result.state.cleanup.shared_plans_with_no_children, existingChildFreeParents);
});
test('refuses to record partial facts or a mismatched independent run id', async () => {
const { state, allowlist } = await fixture();
assert.throws(
() => recordSplitProbeResult(state, allowlist, resultFor(state, { incomplete: true }), state.run.run_id),
/probe_facts_not_complete/
);
assert.throws(
() => recordSplitProbeResult(state, allowlist, resultFor(state), 'another-run'),
/expected_run_id_mismatch/
);
});