Groups cdr_feed legs by Correlation ID for call-level summaries, fixes report-column field parsing and Docker proxy routing, and adds /calltest post-call Twilio and CDR enrichment. Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.3 KiB
JavaScript
87 lines
2.3 KiB
JavaScript
// tests/voiceReport.join.test.js
|
|
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
joinCallQuality,
|
|
matchMediaQualityToCall,
|
|
worstPrismaBucketForCall,
|
|
} from '../services/voiceReport/joinCallQuality.js';
|
|
|
|
const window = {
|
|
startTime: '2026-07-23T13:00:00.000Z',
|
|
endTime: '2026-07-24T01:00:00.000Z',
|
|
};
|
|
|
|
test('matchMediaQualityToCall joins on correlation id', () => {
|
|
const call = {
|
|
start: '2026-07-23T14:00:00.000Z',
|
|
duration: 60,
|
|
callingNumber: '+15551234567',
|
|
calledNumber: '+17247795574',
|
|
correlationId: 'abc-123',
|
|
};
|
|
const mq = [{
|
|
'Correlation ID': 'abc-123',
|
|
'Start Time': '2026-07-23T14:00:01.000Z',
|
|
_norm: { correlationid: 'abc-123', starttime: '2026-07-23T14:00:01.000Z', mos: '4.2' },
|
|
}];
|
|
const hit = matchMediaQualityToCall(call, mq);
|
|
assert.ok(hit);
|
|
assert.equal(hit.mos, 4.2);
|
|
});
|
|
|
|
test('joinCallQuality groups legs into correlated calls', () => {
|
|
const joined = joinCallQuality({
|
|
cdrItems: [
|
|
{
|
|
direction: 'INBOUND',
|
|
startTime: '2026-07-23T14:00:00.000Z',
|
|
durationSeconds: 30,
|
|
status: 'SUCCESS',
|
|
callingNumber: '+1',
|
|
calledNumber: '+2',
|
|
'Correlation ID': 'corr-1',
|
|
'Report ID': 'r1',
|
|
'Call type': 'SIP_INBOUND',
|
|
'Call outcome': 'Success',
|
|
'Call outcome reason': 'Normal',
|
|
},
|
|
{
|
|
Direction: 'Outbound',
|
|
'Start time': '2026-07-23T15:00:00.000Z',
|
|
Duration: 10,
|
|
'Answer indicator': 'No',
|
|
'Report ID': 'r2',
|
|
'Call type': 'SIP_OUTBOUND',
|
|
'Call outcome': 'Failed',
|
|
'Call outcome reason': 'Busy',
|
|
},
|
|
],
|
|
mqRows: [],
|
|
appAudio: null,
|
|
window,
|
|
});
|
|
assert.equal(joined.summary.total, 2);
|
|
assert.equal(joined.calls.length, 2);
|
|
assert.equal(joined.summary.inbound, 1);
|
|
assert.equal(joined.summary.outbound, 1);
|
|
assert.equal(joined.summary.abnormal, 1);
|
|
});
|
|
|
|
test('worstPrismaBucketForCall picks low MOS bucket', () => {
|
|
const leg = {
|
|
start: '2026-07-23T13:05:00.000Z',
|
|
duration: 600,
|
|
};
|
|
const appAudio = {
|
|
mos: { values: [4.4, 4.4, 3.1, 4.4, 4.4] },
|
|
loss: { values: [0, 0, 2, 0, 0] },
|
|
jitter: { values: [5, 5, 5, 5, 5] },
|
|
};
|
|
const w = worstPrismaBucketForCall(leg, appAudio, window);
|
|
assert.ok(w);
|
|
assert.equal(w.mos, 3.1);
|
|
assert.equal(w.siteLevelApprox, true);
|
|
});
|