update on the agents and registry side
This commit is contained in:
67
tests/lib/skills/CashExposureSkill.test.js
Normal file
67
tests/lib/skills/CashExposureSkill.test.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import { CashExposureSkill } from '@/lib/assistant/skills/definitions/CashExposureSkill';
|
||||
|
||||
describe('CashExposureSkill', () => {
|
||||
const NOW = '2026-08-31 14:00:00';
|
||||
|
||||
it('flags riders carrying total COD cash above max threshold', () => {
|
||||
const rows = [
|
||||
// Rider 1: 12000 total (Critical)
|
||||
{ bookingid: 1, userid: 101, ridername: 'Rider A', orderstatus: 'picked', paymenttype: 'cod', cod_amount: '5000' },
|
||||
{ bookingid: 2, userid: 101, ridername: 'Rider A', orderstatus: 'accepted', paymenttype: 'cod', cod_amount: '7000' },
|
||||
|
||||
// Rider 2: 8000 total (Warning)
|
||||
{ bookingid: 3, userid: 102, ridername: 'Rider B', orderstatus: 'picked', paymenttype: 'cod', cod_amount: '8000' },
|
||||
|
||||
// Rider 3: 4000 total (Safe)
|
||||
{ bookingid: 4, userid: 103, ridername: 'Rider C', orderstatus: 'picked', paymenttype: 'cod', cod_amount: '4000' },
|
||||
|
||||
// Non-COD order for Rider 1 (Ignored)
|
||||
{ bookingid: 5, userid: 101, ridername: 'Rider A', orderstatus: 'picked', paymenttype: 'prepaid', cod_amount: '0' }
|
||||
];
|
||||
|
||||
const findings = CashExposureSkill.evaluate(rows, NOW, { maxCashPerRider: 10000, warningCashPercent: 75 });
|
||||
|
||||
const critical = findings.find((f) => f.id === 'cash_exposure_critical');
|
||||
const warning = findings.find((f) => f.id === 'cash_exposure_warning');
|
||||
|
||||
expect(critical).toBeDefined();
|
||||
expect(critical.count).toBe(1); // Only Rider 1
|
||||
expect(critical.rows.length).toBe(2); // Rider 1 has 2 COD orders
|
||||
expect(critical.detail[0]).toContain('12,000');
|
||||
|
||||
expect(warning).toBeDefined();
|
||||
expect(warning.count).toBe(1); // Only Rider 2
|
||||
expect(warning.detail[0]).toContain('8,000');
|
||||
});
|
||||
|
||||
it('returns no findings when all riders are under warning threshold', () => {
|
||||
const rows = [
|
||||
{ bookingid: 1, userid: 101, orderstatus: 'picked', paymenttype: 'cod', cod_amount: '5000' }
|
||||
];
|
||||
const findings = CashExposureSkill.evaluate(rows, NOW, { maxCashPerRider: 10000, warningCashPercent: 75 });
|
||||
expect(findings.length).toBe(0);
|
||||
});
|
||||
|
||||
it('executes enforce_cash_handoff tool handler', async () => {
|
||||
const tool = CashExposureSkill.tools.find((t) => t.name === 'enforce_cash_handoff');
|
||||
expect(tool).toBeDefined();
|
||||
const result = await tool.handler({ milerId: 101, totalCash: 12000, hubId: 'HUB-1' });
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.proposal.action).toBe('cash_handoff');
|
||||
expect(result.proposal.milerId).toBe(101);
|
||||
expect(result.proposal.totalCash).toBe(12000);
|
||||
expect(result.proposal.hubId).toBe('HUB-1');
|
||||
});
|
||||
|
||||
it('handles orders with non-numeric or missing amounts gracefully', () => {
|
||||
const rows = [
|
||||
{ bookingid: 1, userid: 101, orderstatus: 'picked', paymenttype: 'cod' }, // missing amount
|
||||
{ bookingid: 2, userid: 101, orderstatus: 'picked', paymenttype: 'cod', cod_amount: 'invalid' }, // invalid amount
|
||||
{ bookingid: 3, userid: 101, orderstatus: 'picked', paymenttype: 'cod', cod_amount: '12000' } // valid amount
|
||||
];
|
||||
const findings = CashExposureSkill.evaluate(rows, NOW, { maxCashPerRider: 10000, warningCashPercent: 75 });
|
||||
const critical = findings.find((f) => f.id === 'cash_exposure_critical');
|
||||
expect(critical).toBeDefined();
|
||||
expect(critical.detail[0]).toContain('12,000');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user