// tests/callReport.join.test.js import test from 'node:test'; import assert from 'node:assert/strict'; import { buildScopedCallFilter } from '../services/callReport/filterCallsByTarget.js'; import { joinCallQuality, worstPrismaBucketForCall } from '../services/callReport/joinCallQuality.js'; import { CALL_BUCKETS } from '../services/callReport/groupCdrCalls.js'; const window = { startTime: '2026-07-23T13:00:00.000Z', endTime: '2026-07-24T01:00:00.000Z', }; const INBOUND_PHONE_LEGS = [ { 'Start time': '2026-07-23T13:00:00.000Z', 'Release time': '2026-07-23T13:05:00.000Z', 'Call type': 'SIP_INBOUND', 'Correlation ID': 'corr-1', 'Report ID': 'r1', 'Calling number': '+15551234567', 'Called number': '+12122194600', 'Site main number': '+12122194600', 'Call outcome': 'Success', 'Call outcome reason': 'Normal', 'Answer indicator': 'Yes', Answered: 'true', Duration: 300, }, { 'Start time': '2026-07-23T13:00:30.000Z', 'Call type': 'SIP_ENTERPRISE', 'Correlation ID': 'corr-1', 'Report ID': 'r2', 'User type': 'User', User: 'Store 02477', Model: 'DBS-210-3PC', 'Called number': '52477', 'Calling number': '+15551234567', 'Call outcome': 'Success', 'Call outcome reason': 'Normal', 'Answer indicator': 'Yes', Answered: 'true', Duration: 270, }, ]; test('joinCallQuality groups legs into correlated calls', () => { const joined = joinCallQuality({ cdrItems: [ ...INBOUND_PHONE_LEGS, { Direction: 'Outbound', 'Start time': '2026-07-23T15:00:00.000Z', Duration: 10, 'Answer indicator': 'No', 'Report ID': 'r3', 'Call type': 'SIP_OUTBOUND', 'Call outcome': 'Failed', 'Call outcome reason': 'Busy', }, ], appAudio: null, window, }); assert.equal(joined.summary.total, 2); assert.equal(joined.summary.inbound, 1); assert.equal(joined.summary.outbound, 1); assert.equal(joined.summary.abnormal, 1); assert.equal(joined.abnormalCalls.length, 1); assert.equal(joined.buckets[CALL_BUCKETS.inboundReachedPhone].length, 1); }); test('joinCallQuality attaches WAN only for answered inbound', () => { 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 joined = joinCallQuality({ cdrItems: INBOUND_PHONE_LEGS, appAudio, window, }); assert.ok(joined.calls[0].wan); assert.equal(joined.calls[0].wan.mos, 4.4); }); test('joinCallQuality skips WAN for unanswered outbound', () => { const appAudio = { mos: { values: [4.0, 4.0, 4.0] }, loss: { values: [0, 0, 0] }, jitter: { values: [5, 5, 5] }, }; const joined = joinCallQuality({ cdrItems: [{ 'Start time': '2026-07-23T15:00:00.000Z', 'Report ID': 'r4', 'Call type': 'SIP_OUTBOUND', 'Call outcome': 'Failed', 'Call outcome reason': 'Busy', 'Answer indicator': 'No', }], appAudio, window, }); assert.equal(joined.calls[0].wan, null); }); test('worstPrismaBucketForCall picks low MOS bucket', () => { const call = { 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(call, appAudio, window); assert.ok(w); assert.equal(w.mos, 3.1); }); test('worstPrismaBucketForCall matches Prisma datapoint timestamps', () => { const call = { start: '2026-07-23T15:18:00.000Z', duration: 455, }; const appAudio = { mos: { interval: '5min', values: [4.4, 4.3, 3.1], timedPoints: [ { time: '2026-07-23T13:00:00.000Z', value: 4.4 }, { time: '2026-07-23T13:05:00.000Z', value: null }, { time: '2026-07-23T15:15:00.000Z', value: 4.3 }, { time: '2026-07-23T15:20:00.000Z', value: 3.1 }, ], }, loss: { timedPoints: [ { time: '2026-07-23T15:15:00.000Z', value: 0 }, { time: '2026-07-23T15:20:00.000Z', value: 2 }, ], }, jitter: { timedPoints: [ { time: '2026-07-23T15:15:00.000Z', value: 1.2 }, { time: '2026-07-23T15:20:00.000Z', value: 3.4 }, ], }, }; const w = worstPrismaBucketForCall(call, appAudio, window); assert.ok(w); assert.equal(w.mos, 3.1); assert.equal(w.loss, 2); assert.equal(w.jitter, 3.4); }); test('joinCallQuality filters scoped calls when filter provided', () => { const joined = joinCallQuality({ cdrItems: [ ...INBOUND_PHONE_LEGS, { Direction: 'Outbound', 'Start time': '2026-07-23T15:00:00.000Z', Duration: 10, 'Answer indicator': 'No', 'Report ID': 'r3', 'Call type': 'SIP_OUTBOUND', 'Call outcome': 'Failed', 'Call outcome reason': 'Busy', }, ], appAudio: null, window, filter: buildScopedCallFilter({ kind: 'number', extension: '52477' }), }); assert.equal(joined.summary.total, 1); assert.equal(joined.summary.inbound, 1); assert.equal(joined.summary.outbound, 0); });