fix(freight): gate loading on booking paymentStatus only; default schedule voyage no. to train's voyage number

This commit is contained in:
marshal
2026-09-02 21:15:48 +00:00
parent d51bed5630
commit 3e274cc2a2
30 changed files with 629 additions and 117 deletions

View File

@@ -0,0 +1,76 @@
import { BookingNotifierService } from './booking-notifier.service';
/**
* Message wording for the schedule-related customer notices: every one must
* quote the SCHEDULE's train + voyage numbers, and reschedules must carry the
* staff-entered reason instead of a hard-coded "for maintenance".
*/
describe('BookingNotifierService messages', () => {
const schedule = { trainNumber: '8001', voyageNumber: 'V-117' };
const booking = { id: 'b1', reference: 'BK-2026-000928', companyId: 'c1' } as never;
const departure = new Date('2026-09-01T05:00:00.000Z');
let sent: string[];
let inbox: string[];
let service: BookingNotifierService;
beforeEach(() => {
sent = [];
inbox = [];
const notifications = {
directSend: jest.fn(async (_m: string, _to: string, msg: string) => {
sent.push(msg);
}),
};
const inboxSvc = {
notify: jest.fn(async (input: { body: string }) => {
inbox.push(input.body);
}),
};
const trainSchedules = {
findByIdWithStations: jest.fn(async () => ({ ...schedule, reference: 'S-2026-00012' })),
};
// Company contact lookup goes through raw SQL; return one phone + email.
const dataSource = {
query: jest.fn(async () => [{ phone: '+251900000000', email: 'ops@example.com' }]),
};
service = new BookingNotifierService(
notifications as never,
inboxSvc as never,
trainSchedules as never,
dataSource as never,
);
});
const flush = () => new Promise((r) => setImmediate(r));
it('maintenance reschedule quotes train, voyage and the staff reason', async () => {
service.maintenanceMoved(booking, departure, schedule, 'Locomotive maintenance.');
await flush();
expect(inbox[0]).toBe(
'Train 8001 (voyage V-117) for booking BK-2026-000928 was rescheduled — reason: Locomotive maintenance. ' +
'New departure date: 01/09/2026.',
);
});
it('maintenance reschedule falls back to "for maintenance" without a reason', async () => {
service.maintenanceMoved(booking, departure, schedule, ' ');
await flush();
expect(inbox[0]).toContain('was rescheduled for maintenance. New departure date');
});
it('plain reschedule carries the reason and the run label', async () => {
service.rescheduled(booking, departure, schedule, 'Crew change');
await flush();
expect(inbox[0]).toBe(
'Booking BK-2026-000928 on train 8001 (voyage V-117) has been rescheduled — reason: Crew change. ' +
'New departure date: 01/09/2026.',
);
});
it('resolves the run label from a schedule id when only the id is known', async () => {
service.scheduleCancelled(booking, 'sched-1');
await flush();
expect(inbox[0]).toMatch(/^Train 8001 \(voyage V-117\) for booking BK-2026-000928 has been cancelled/);
});
});