collabSupport/tests/callReport.formatCallLine.test.js
jmcqueen a25fc08fe2 Rename /voicereport to /callreport with scoped user and phone targets.
Add store/email/phone filtering, richer call-line formatting, CDR feed pagination and queueing, and split Jira poller enrichment into testable modules.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 10:10:03 -04:00

122 lines
4.4 KiB
JavaScript

// tests/callReport.formatCallLine.test.js
import test from 'node:test';
import assert from 'node:assert/strict';
import { groupCdrIntoCalls } from '../services/callReport/groupCdrCalls.js';
import { formatCallBlock, formatDurationHuman, formatLocalTime, formatWanLine } from '../services/callReport/formatCallLine.js';
const SAMPLE_LEGS = [
{
'Answer time': '2026-07-23T13:06:24.325Z',
Answered: 'true',
Direction: 'TERMINATING',
'Calling line ID': 'WIRELESS CALLER',
'Start time': '2026-07-23T13:06:24.316Z',
'Call type': 'SIP_INBOUND',
'Correlation ID': '3c7f5c7c-6f48-40f2-925c-133f6a84dcdb',
Duration: 184,
'Report ID': 'fd1debbf-d2b4-331c-846a-2f2a79de9b08',
'Site main number': '+12122194600',
'User type': 'AutomatedAttendantVideo',
User: 'Store 2477',
'Called number': '+12122194600',
'Calling number': '+17189864017',
'Call outcome': 'Success',
'Call outcome reason': 'Normal',
'Answer indicator': 'Yes',
'Auto Attendant Key Pressed': '1',
'Release time': '2026-07-23T13:09:28.784Z',
},
{
'Start time': '2026-07-23T13:06:26.570Z',
'Call type': 'SIP_ENTERPRISE',
'Correlation ID': '3c7f5c7c-6f48-40f2-925c-133f6a84dcdb',
'Report ID': '9541d7ea-8ced-3d39-a8ef-c2fc5e341700',
'Called number': '52477',
'Calling number': '+17189864017',
Duration: 134,
},
{
'Start time': '2026-07-23T13:06:26.739Z',
'Call type': 'SIP_ENTERPRISE',
'Client type': 'WXC_DEVICE',
'Correlation ID': '3c7f5c7c-6f48-40f2-925c-133f6a84dcdb',
'Report ID': '829fcf5b-975c-3f5d-9150-af4743232bd3',
'User type': 'User',
User: 'Store 02477',
Model: 'DBS-210-3PC',
'Called number': '52477',
'Calling number': '+17189864017',
'Call outcome': 'Success',
'Call outcome reason': 'Normal',
'Answer indicator': 'Yes',
Answered: 'true',
Duration: 134,
'Release time': '2026-07-23T13:09:28.784Z',
},
];
test('formatDurationHuman', () => {
assert.equal(formatDurationHuman(45), '45s');
assert.equal(formatDurationHuman(184), '3m 4s');
});
test('formatLocalTime uses store timezone', () => {
const t = formatLocalTime('2026-07-23T13:06:24.316Z', 'America/New_York');
assert.match(t, /9:06am/);
});
test('formatCallBlock inbound with CLID arrow and final', () => {
const [call] = groupCdrIntoCalls(SAMPLE_LEGS);
call.wan = { mos: 4.1, jitter: 3.4, loss: 2.4 };
const { line1, line2 } = formatCallBlock(call, { timeZone: 'America/New_York', includeWan: true });
assert.match(line1, /9:06am \(3m 4s\):/);
assert.match(line1, /WIRELESS CALLER \(\+17189864017\)/);
assert.match(line1, /→ \+12122194600 \(final 52477, DBS-210-3PC\)/);
assert.match(line1, /^✅ /);
assert.doesNotMatch(line1, /Success$/);
assert.match(line2, /MOS: 4\.1/);
assert.match(line2, /Jitter: 3\.4ms/);
assert.match(line2, /Loss: 2\.4%/);
});
test('formatCallBlock abnormal shows warning icon and disposition', () => {
const [call] = groupCdrIntoCalls(SAMPLE_LEGS);
call.abnormal = true;
call.normalOutcome = false;
call.disposition = 'Failed / Busy';
call.wan = { mos: 4.1, jitter: 3.4, loss: 2.4 };
const { line1, line2 } = formatCallBlock(call, { timeZone: 'America/New_York', includeWan: false });
assert.match(line1, /^⚠️ /);
assert.match(line1, /Failed \/ Busy/);
assert.equal(line2, null);
});
test('formatCallBlock AA-only uses warning icon without Success', () => {
const call = {
direction: 'inbound',
start: '2026-07-23T13:59:00.000Z',
duration: 12,
callingLineId: 'PITTSBURGH PA',
callingNumber: '+14122020183',
storeMainNumber: '+14123694426',
calledNumber: '+14123694426',
reachedAttendant: true,
reachedPhone: false,
aaKeyPress: 'No Selection',
disposition: 'Success',
normalOutcome: true,
abnormal: false,
};
const { line1 } = formatCallBlock(call, { timeZone: 'America/New_York', includeWan: false });
assert.match(line1, /^⚠️ /);
assert.match(line1, /AA key No Selection/);
assert.doesNotMatch(line1, /Success/);
});
test('formatWanLine flags MOS and loss thresholds', () => {
assert.match(formatWanLine({ mos: 3.6, jitter: 0, loss: 9.8 }), /MOS: 3\.6 ⚠️/);
assert.match(formatWanLine({ mos: 3.4, jitter: 0, loss: 0 }), /MOS: 3\.4 ‼️/);
assert.match(formatWanLine({ mos: 4.4, jitter: 45, loss: 2 }), /Jitter: 45ms ⚠️/);
assert.match(formatWanLine({ mos: 4.4, jitter: 0, loss: 6 }), /Loss: 6% ⚠️/);
});