freightdesk/webapp/tests/unit/utils.test.js
FreightDesk 8ae3b403ab [OWL] Roadmap batch: CI/CD, observability, testing, UX polish
CI/CD:
- Add .github/workflows/deploy.yml (lint, test, build Docker, Coolify deploy)

Observability:
- Add Pino logger (services/logger.js) — structured JSON logging
- Add Prometheus metrics (services/metrics.js) — /metrics endpoint
- Replace console.error with pino in error handler
- Track http_request_duration, http_requests_total, active_loads, total_commission

Testing:
- Add Jest config to package.json
- Add integration tests (tests/integration/app.test.js) — health, metrics, auth, 404
- Add unit tests (tests/unit/utils.test.js) — formatINR, getStatusColor, calcCommission, WhatsApp parser
- Add devDeps: jest, supertest, eslint, prettier

UX:
- Debounced search (400ms) on Loads list page
- Cache-busting asset versioning (?v=timestamp) on CSS/JS includes
- ESLint + Prettier configs

Package updates:
- Add pino, pino-http, prom-client to dependencies
- Add jest, eslint, prettier, supertest, nodemon to devDependencies
2026-06-07 19:46:45 +00:00

105 lines
3.5 KiB
JavaScript

const { formatINR, getStatusColor, calcCommission, calcPendingFromShipper, calcPendingToDriver } = require('../../src/lib/india');
const { parseWhatsAppMessage } = require('../../src/services/parser');
describe('India Utils — formatINR', () => {
test('formats whole numbers', () => {
expect(formatINR(1000)).toBe('₹1,000');
expect(formatINR(100000)).toBe('₹1,00,000');
expect(formatINR(10000000)).toBe('₹1,00,00,000');
});
test('formats decimals', () => {
expect(formatINR(1999.50)).toBe('₹1,999.5');
});
test('handles zero', () => {
expect(formatINR(0)).toBe('₹0');
});
test('handles null/undefined', () => {
expect(formatINR(null)).toBe('—');
expect(formatINR(undefined)).toBe('—');
});
});
describe('India Utils — getStatusColor', () => {
test('returns correct badge colors', () => {
expect(getStatusColor('settled')).toBe('green');
expect(getStatusColor('completed')).toBe('green');
expect(getStatusColor('loaded / in transit')).toBe('blue');
expect(getStatusColor('pending collection')).toBe('orange');
expect(getStatusColor('cancelled')).toBe('red');
expect(getStatusColor('unknown')).toBe('gray');
});
});
describe('India Utils — calcCommission', () => {
test('calculates commission correctly', () => {
expect(calcCommission(19000, 15900)).toBe(3100);
expect(calcCommission(50000, 45000)).toBe(5000);
});
test('returns null for missing values', () => {
expect(calcCommission(null, 100)).toBeNull();
expect(calcCommission(100, null)).toBeNull();
});
});
describe('India Utils — calcPendingFromShipper', () => {
test('calculates pending correctly', () => {
expect(calcPendingFromShipper(19000, 5000)).toBe(14000);
});
test('returns null for missing values', () => {
expect(calcPendingFromShipper(null, 100)).toBeNull();
});
});
describe('India Utils — calcPendingToDriver', () => {
test('calculates pending correctly', () => {
expect(calcPendingToDriver(15900, 10000)).toBe(5900);
});
});
describe('WhatsApp Parser', () => {
test('parses a standard message', () => {
const msg = 'Agarwal Bangalore TN39DV8142 loaded 19000 freight driver advance 15900';
const result = parseWhatsAppMessage(msg);
expect(result.shipper).toBe('Agarwal Packers and Movers');
expect(result.to_city).toBe('Bangalore');
expect(result.vehicle).toBe('TN39DV8142');
expect(result.freight_charged).toBe(19000);
expect(result.paid_to_driver).toBe(15900);
expect(result.commission).toBe(3100);
expect(result.confidence).toBe('high');
});
test('parses message with Mumbai route', () => {
const msg = 'Kahn Transport Mumbai MH12AB1234 loaded 45000 freight advance 40000';
const result = parseWhatsAppMessage(msg);
expect(result.shipper).toBe('Kahn Transport');
expect(result.to_city).toBe('Mumbai');
expect(result.freight_charged).toBe(45000);
});
test('parses status keywords', () => {
const msg1 = 'Agarwal Chennai TN39DV8142 loaded 20000 freight';
expect(parseWhatsAppMessage(msg1).status).toBe('loaded / in transit');
const msg2 = 'Agarwal Chennai TN39DV8142 delivered 20000 freight';
expect(parseWhatsAppMessage(msg2).status).toBe('delivered / pending collection');
});
test('handles empty message', () => {
const result = parseWhatsAppMessage('');
expect(result.confidence).toBe('low');
});
test('extracts vehicle number', () => {
const msg = 'Some text KL01AB1234 more text';
const result = parseWhatsAppMessage(msg);
expect(result.vehicle).toBe('KL01AB1234');
});
});