194 lines
6.7 KiB
TypeScript
194 lines
6.7 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
buildCustomerSuccessReply,
|
|
buildCustomerSuccessReceipt,
|
|
replyAttachmentsFromReceipt,
|
|
replyTextFromReceipt
|
|
} from '../src/reply-contract.js';
|
|
|
|
test('hotel arrangement uses the customer bilingual booking template', () => {
|
|
const operation = {
|
|
action: 'arrangement_hotel',
|
|
data: {
|
|
customer: { name: '老挝联泰' },
|
|
existing_refs: { kind: 'independent_order', identifier: 'LW-260603Z-A' },
|
|
arrangement: {
|
|
mode: 'create',
|
|
start_date: '2026-06-03',
|
|
end_date: '2026-06-04',
|
|
room_count: 6
|
|
}
|
|
}
|
|
};
|
|
const result = {
|
|
report: {
|
|
requery: {
|
|
subpage: {
|
|
arrangement_target: {
|
|
item_value: 'TWN',
|
|
quantity_value: '6'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const receipt = { success: true, group_number: 'LW-260603Z-A' };
|
|
const reply = buildCustomerSuccessReply(receipt, result, operation);
|
|
assert.ok(reply);
|
|
assert.equal(reply.profile, 'hotel-arrangement-lwlt-v1');
|
|
assert.equal(reply.text, [
|
|
'①NEW BOOKING',
|
|
'GROUP CODE: LW-260603Z-A',
|
|
'IN. 03/06/2026',
|
|
'OUT 04/06/2026',
|
|
'1Night. 6Twin',
|
|
'②新订单',
|
|
'团号:LW-260603Z-A 老挝联泰',
|
|
'入住日期:2026.06.03',
|
|
'退房日期:2026.06.04',
|
|
'几 晚:1晚',
|
|
'房型/房数:标间 6间'
|
|
].join('\n'));
|
|
});
|
|
|
|
test('hotel clear and update replies stay business-readable when the booking template is not applicable', () => {
|
|
const clearReply = buildCustomerSuccessReply(
|
|
{ success: true, group_number: 'LW-260603Z-A' },
|
|
{},
|
|
{
|
|
action: 'arrangement_hotel',
|
|
data: {
|
|
existing_refs: { identifier: 'LW-260603Z-A' },
|
|
arrangement: { mode: 'clear' }
|
|
}
|
|
}
|
|
);
|
|
assert.ok(clearReply);
|
|
assert.equal(clearReply.text, '酒店安排已清除\n团号:LW-260603Z-A');
|
|
|
|
const updateReply = buildCustomerSuccessReply(
|
|
{ success: true, group_number: 'LW-260603Z-A' },
|
|
{ report: { changes: [{ target: 'room_count', after: 9 }] } },
|
|
{
|
|
action: 'arrangement_hotel',
|
|
data: {
|
|
existing_refs: { identifier: 'LW-260603Z-A' },
|
|
arrangement: { mode: 'update', end_date: '2026-06-05', room_count: 9 }
|
|
}
|
|
}
|
|
);
|
|
assert.ok(updateReply);
|
|
assert.equal(updateReply.text, '酒店安排成功\n团号:LW-260603Z-A\n退房日期:2026-06-05\n房数:9间');
|
|
});
|
|
|
|
test('batch newbooking receipt preserves every group number', () => {
|
|
const reply = buildCustomerSuccessReply(
|
|
{ success: true, group_number: 'LW-260603A-A', group_numbers: ['LW-260603A-A', 'LW-260605A-A'] },
|
|
{},
|
|
{ action: 'team_order_batch_create', data: {} }
|
|
);
|
|
assert.ok(reply);
|
|
assert.equal(reply.text, '批量下单成功\n团号:LW-260603A-A、LW-260605A-A');
|
|
});
|
|
|
|
test('update and file replies expose business fields without technical evidence', () => {
|
|
const updateReply = buildCustomerSuccessReply(
|
|
{ success: true, group_number: 'LW-260603A-A' },
|
|
{ report: { changes: [{ target: 'planned_capacity', after: 45 }] } },
|
|
{
|
|
action: 'order_update_shared_plan',
|
|
data: {
|
|
existing_refs: { identifier: 'LW-260603A-A' },
|
|
updates: { actions: [{ target: 'planned_capacity', operation: 'set', value: 45 }] }
|
|
}
|
|
}
|
|
);
|
|
assert.ok(updateReply);
|
|
assert.equal(updateReply.text, '散拼母团信息修改成功\n团号:LW-260603A-A\n计划收客数:45');
|
|
assert.doesNotMatch(updateReply.text, /sha256|verification|blocker|execution/iu);
|
|
|
|
const baseReceipt = buildCustomerSuccessReceipt(
|
|
{ success: true, group_number: 'LW-260603A-A' },
|
|
{
|
|
report: {
|
|
artifacts: [{
|
|
file_name: 'liantai-confirm.docx',
|
|
content_type: 'application/msword',
|
|
bytes: 28892,
|
|
download_url: '/api/tasks/TASK-1/artifacts/ART-1',
|
|
sha256: 'secret-hash'
|
|
}]
|
|
}
|
|
},
|
|
{ action: 'confirmation_export', data: { existing_refs: { identifier: 'LW-260603A-A' } } }
|
|
);
|
|
assert.equal(replyTextFromReceipt(baseReceipt), '团队文件已准备\n团号:LW-260603A-A\n文件:liantai-confirm.docx');
|
|
assert.deepEqual(replyAttachmentsFromReceipt(baseReceipt), [{
|
|
name: 'liantai-confirm.docx',
|
|
content_type: 'application/msword',
|
|
size: 28892,
|
|
download_url: '/api/tasks/TASK-1/artifacts/ART-1'
|
|
}]);
|
|
assert.doesNotMatch(JSON.stringify(baseReceipt), /secret-hash/);
|
|
});
|
|
|
|
test('visitor export reply exposes only the mobile XLSX delivery artifact', () => {
|
|
const receipt = buildCustomerSuccessReceipt(
|
|
{ success: true, group_number: 'LW-260816Z-A' },
|
|
{
|
|
report: {
|
|
artifacts: [
|
|
{
|
|
file_name: 'LW-260816Z-A Visitor.xls',
|
|
content_type: 'application/vnd.ms-excel',
|
|
bytes: 9377,
|
|
agentbus_visible: false,
|
|
download_url: '/api/tasks/TASK-VISITOR/artifacts/ART-XLS'
|
|
},
|
|
{
|
|
file_name: 'LW-260816Z-A Visitor.xlsx',
|
|
content_type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
bytes: 5211,
|
|
agentbus_visible: true,
|
|
download_url: '/api/tasks/TASK-VISITOR/artifacts/ART-XLSX'
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{ action: 'confirmation_export', data: { existing_refs: { identifier: 'LW-260816Z-A' } } }
|
|
);
|
|
assert.equal(replyTextFromReceipt(receipt!), '团队文件已准备\n团号:LW-260816Z-A\n文件:LW-260816Z-A Visitor.xlsx');
|
|
assert.deepEqual(replyAttachmentsFromReceipt(receipt!), [{
|
|
name: 'LW-260816Z-A Visitor.xlsx',
|
|
content_type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
size: 5211,
|
|
download_url: '/api/tasks/TASK-VISITOR/artifacts/ART-XLSX'
|
|
}]);
|
|
assert.doesNotMatch(JSON.stringify(receipt), /Visitor\.xls(?!x)/u);
|
|
});
|
|
|
|
test('legacy ERP mojibake filenames are repaired when a stored receipt is read', () => {
|
|
const receipt = buildCustomerSuccessReceipt(
|
|
{ success: true, group_number: 'LW-261202A-A' },
|
|
{
|
|
report: {
|
|
artifacts: [{
|
|
file_name: 'LLW-261202A-A 客æ·ç¡®è®¤ä¹¦.doc',
|
|
content_type: 'application/msword',
|
|
bytes: 30649,
|
|
download_url: '/api/tasks/TASK-LEGACY/artifacts/ART-LEGACY'
|
|
}]
|
|
}
|
|
},
|
|
{ action: 'confirmation_export', data: { existing_refs: { identifier: 'LW-261202A-A' } } }
|
|
);
|
|
assert.equal(replyTextFromReceipt(receipt), '团队文件已准备\n团号:LW-261202A-A\n文件:LLW-261202A-A 客户确认书.doc');
|
|
assert.deepEqual(replyAttachmentsFromReceipt(receipt), [{
|
|
name: 'LLW-261202A-A 客户确认书.doc',
|
|
content_type: 'application/msword',
|
|
size: 30649,
|
|
download_url: '/api/tasks/TASK-LEGACY/artifacts/ART-LEGACY'
|
|
}]);
|
|
});
|