@babblevoice/babble-drachtio-callmanager 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +179 -0
- package/index.js +45 -0
- package/jsdoc.conf.json +18 -0
- package/lib/call.js +2431 -0
- package/lib/callmanager.js +114 -0
- package/lib/sdp.js +452 -0
- package/lib/store.js +146 -0
- package/package.json +37 -0
- package/test/interface/call.js +1044 -0
- package/test/interface/callmanager.js +125 -0
- package/test/interface/callsdp.js +53 -0
- package/test/interface/events.js +87 -0
- package/test/interface/hold.js +174 -0
- package/test/interface/latecall.js +132 -0
- package/test/interface/sdp.js +296 -0
- package/test/interface/xfer.js +169 -0
- package/test/mock/srf.js +387 -0
- package/test/unit/store.js +153 -0
package/test/mock/srf.js
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
|
|
2
|
+
const expect = require( "chai" ).expect
|
|
3
|
+
const { v4: uuidv4 } = require( "uuid" )
|
|
4
|
+
const crypto = require( "crypto" )
|
|
5
|
+
const events = require( "events" )
|
|
6
|
+
|
|
7
|
+
const call = require( "../../lib/call.js" )
|
|
8
|
+
const callmanager = require( "../../index.js" )
|
|
9
|
+
|
|
10
|
+
let possiblesdp = [
|
|
11
|
+
`v=0
|
|
12
|
+
o=Z 1610744131900 1 IN IP4 127.0.0.1
|
|
13
|
+
s=Z
|
|
14
|
+
c=IN IP4 192.168.0.200
|
|
15
|
+
t=0 0
|
|
16
|
+
m=audio 18540 RTP/AVP 106 9 98 101 0 8 18 3
|
|
17
|
+
a=rtpmap:106 opus/48000/2
|
|
18
|
+
a=fmtp:106 maxplaybackrate=16000; sprop-maxcapturerate=16000; minptime=20; cbr=1; maxaveragebitrate=20000; useinbandfec=1
|
|
19
|
+
a=rtpmap:98 telephone-event/48000
|
|
20
|
+
a=fmtp:98 0-16
|
|
21
|
+
a=rtpmap:101 telephone-event/8000
|
|
22
|
+
a=fmtp:101 0-16
|
|
23
|
+
a=rtpmap:18 G729/8000
|
|
24
|
+
a=fmtp:18 annexb=no
|
|
25
|
+
a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n"),
|
|
26
|
+
`v=0
|
|
27
|
+
o=- 1608235282228 0 IN IP4 127.0.0.1
|
|
28
|
+
s=
|
|
29
|
+
c=IN IP4 192.168.0.141
|
|
30
|
+
t=0 0
|
|
31
|
+
m=audio 20000 RTP/AVP 8 101
|
|
32
|
+
a=rtpmap:101 telephone-event/8000
|
|
33
|
+
a=fmtp:101 0-16
|
|
34
|
+
a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n"),
|
|
35
|
+
`v=0
|
|
36
|
+
o=- 1608235282228 0 IN IP4 127.0.0.1
|
|
37
|
+
s=
|
|
38
|
+
c=IN IP4 192.168.0.141
|
|
39
|
+
t=0 0
|
|
40
|
+
m=audio 20000 RTP/AVP 0 101
|
|
41
|
+
a=rtpmap:101 telephone-event/8000
|
|
42
|
+
a=fmtp:101 0-16
|
|
43
|
+
a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n"),
|
|
44
|
+
`v=0
|
|
45
|
+
o=- 1608235282228 0 IN IP4 127.0.0.1
|
|
46
|
+
s=
|
|
47
|
+
c=IN IP4 192.168.0.141
|
|
48
|
+
t=0 0
|
|
49
|
+
m=audio 20000 RTP/AVP 97 101
|
|
50
|
+
a=rtpmap:97 ilbc/8000
|
|
51
|
+
a=rtpmap:101 telephone-event/8000
|
|
52
|
+
a=fmtp:101 0-16
|
|
53
|
+
a=fmtp:97 mode=20
|
|
54
|
+
a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n"),
|
|
55
|
+
`v=0
|
|
56
|
+
o=Z 1610744131900 1 IN IP4 127.0.0.1
|
|
57
|
+
s=Z
|
|
58
|
+
c=IN IP4 192.168.0.200
|
|
59
|
+
t=0 0
|
|
60
|
+
m=audio 18540 RTP/AVP 106 98 101 0 8 18 3 9
|
|
61
|
+
a=rtpmap:106 opus/48000/2
|
|
62
|
+
a=fmtp:106 maxplaybackrate=16000; sprop-maxcapturerate=16000; minptime=20; cbr=1; maxaveragebitrate=20000; useinbandfec=1
|
|
63
|
+
a=rtpmap:98 telephone-event/48000
|
|
64
|
+
a=fmtp:98 0-16
|
|
65
|
+
a=rtpmap:101 telephone-event/8000
|
|
66
|
+
a=fmtp:101 0-16
|
|
67
|
+
a=rtpmap:18 G729/8000
|
|
68
|
+
a=fmtp:18 annexb=no
|
|
69
|
+
a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n"),
|
|
70
|
+
`v=0
|
|
71
|
+
o=Z 1610744131900 1 IN IP4 127.0.0.1
|
|
72
|
+
s=Z
|
|
73
|
+
c=IN IP4 192.168.0.200
|
|
74
|
+
t=0 0
|
|
75
|
+
m=audio 18540 RTP/AVP 106 98 101 0 8 97 18 3
|
|
76
|
+
a=rtpmap:106 opus/48000/2
|
|
77
|
+
a=fmtp:106 maxplaybackrate=16000; sprop-maxcapturerate=16000; minptime=20; cbr=1; maxaveragebitrate=20000; useinbandfec=1
|
|
78
|
+
a=rtpmap:98 telephone-event/48000
|
|
79
|
+
a=fmtp:98 0-16
|
|
80
|
+
a=rtpmap:97 ilbc/8000
|
|
81
|
+
a=rtpmap:101 telephone-event/8000
|
|
82
|
+
a=fmtp:101 0-16
|
|
83
|
+
a=rtpmap:18 G729/8000
|
|
84
|
+
a=fmtp:18 annexb=no
|
|
85
|
+
a=fmtp:97 mode=20
|
|
86
|
+
a=sendrecv`.replace(/(\r\n|\n|\r)/gm, "\r\n")
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
let sdpid = 0
|
|
90
|
+
|
|
91
|
+
/*
|
|
92
|
+
Mock req object
|
|
93
|
+
*/
|
|
94
|
+
class req {
|
|
95
|
+
constructor( options ) {
|
|
96
|
+
this.parsedheaders = {}
|
|
97
|
+
this.headers = {}
|
|
98
|
+
|
|
99
|
+
this.source = "network"
|
|
100
|
+
this.source_address = "127.0.0.1"
|
|
101
|
+
this.source_port = 5060
|
|
102
|
+
this.protocol = "udp"
|
|
103
|
+
this.receivedOn = "192.168.0.141:9997"
|
|
104
|
+
this.entity = {
|
|
105
|
+
"uri": "1000@domain"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.options = options
|
|
109
|
+
|
|
110
|
+
this.callbacks = {}
|
|
111
|
+
|
|
112
|
+
this.msg = {
|
|
113
|
+
"body": possiblesdp[ sdpid % possiblesdp.length ],
|
|
114
|
+
method: "INVITE"
|
|
115
|
+
}
|
|
116
|
+
sdpid++
|
|
117
|
+
|
|
118
|
+
this.set( "cseq", "1 INVITE" )
|
|
119
|
+
this.set( "max-forwards", "70" )
|
|
120
|
+
|
|
121
|
+
this.setparsedheader( "call-id", uuidv4() )
|
|
122
|
+
|
|
123
|
+
/* copied object structure from srf */
|
|
124
|
+
this.setparsedheader( "from", {
|
|
125
|
+
"uri": "sip:1000@dummy.com;transport=UDP",
|
|
126
|
+
"params": {
|
|
127
|
+
"tag": crypto.randomBytes( 5 ).toString( "hex" )
|
|
128
|
+
}
|
|
129
|
+
} )
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* case insensative */
|
|
133
|
+
getParsedHeader( header ) {
|
|
134
|
+
return this.parsedheaders[ header.toLowerCase() ]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
setparsedheader( header, value ) {
|
|
138
|
+
this.parsedheaders[ header.toLowerCase() ] = value
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
get( header ) {
|
|
142
|
+
return this.headers[ header.toLowerCase() ]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
set( header, value ) {
|
|
146
|
+
this.headers[ header.toLowerCase() ] = value
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
has( header ) {
|
|
150
|
+
return header.toLowerCase() in this.headers || header.toLowerCase() in this.parsedheaders
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
on( event, cb ) {
|
|
154
|
+
this.callbacks[ event ] = cb
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* returns undefined - checked https://drachtio.org/api#sip-request-cancel */
|
|
158
|
+
cancel() {
|
|
159
|
+
if( this.callbacks.cancel ) this.callbacks.cancel()
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
class res {
|
|
164
|
+
constructor() {
|
|
165
|
+
this.callbacks = {
|
|
166
|
+
"onsend": false
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* returns undefined - https://drachtio.org/api#sip-request */
|
|
171
|
+
send( sipcode, msg, o, cb ) {
|
|
172
|
+
if( this.callbacks.onsend ) {
|
|
173
|
+
this.callbacks.onsend( sipcode, msg )
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if( cb ) {
|
|
177
|
+
cb()
|
|
178
|
+
return this
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
onsend( cb ) {
|
|
183
|
+
this.callbacks.onsend = cb
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
class options {
|
|
188
|
+
constructor( method = "invite" ) {
|
|
189
|
+
this.method = method
|
|
190
|
+
this.uacsdp = possiblesdp[ 0 ]
|
|
191
|
+
this.uassdp = possiblesdp[ 1 ]
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
class dialog {
|
|
196
|
+
constructor( req ) {
|
|
197
|
+
|
|
198
|
+
let sdp = ""
|
|
199
|
+
if( req ) {
|
|
200
|
+
sdp = req.msg.body
|
|
201
|
+
}
|
|
202
|
+
this.remote = {
|
|
203
|
+
"sdp": sdp
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let fromtag = ""
|
|
207
|
+
if( req ) {
|
|
208
|
+
let from = req.getParsedHeader( "from" )
|
|
209
|
+
fromtag = from.params.tag
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
this.sip = {
|
|
213
|
+
"localTag": crypto.randomBytes( 5 ).toString( "hex" ),
|
|
214
|
+
"remoteTag": fromtag
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
this.callbacks = {}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
on( ev, cb ) {
|
|
221
|
+
this.callbacks[ ev ] = cb
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
ack() {
|
|
225
|
+
return this
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
destroy( cb ) {
|
|
229
|
+
if( this.callbacks.destroy ) this.callbacks.destroy()
|
|
230
|
+
|
|
231
|
+
if( cb ) {
|
|
232
|
+
cb()
|
|
233
|
+
return this
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return new Promise( ( resolve ) => {
|
|
237
|
+
resolve( this )
|
|
238
|
+
} )
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/*
|
|
242
|
+
Confirmed - srf.dialog.request returns a promise
|
|
243
|
+
https://drachtio.org/docs/api#Dialog+request (only if no call back is supplied though)
|
|
244
|
+
*/
|
|
245
|
+
request( options, cb ) {
|
|
246
|
+
|
|
247
|
+
if( this.callbacks.request ) this.callbacks.request( options )
|
|
248
|
+
|
|
249
|
+
if( cb ) {
|
|
250
|
+
cb()
|
|
251
|
+
return this
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return new Promise( ( resolve ) => {
|
|
255
|
+
resolve( this )
|
|
256
|
+
} )
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/*
|
|
260
|
+
Same as request - promise or not depending on callback supplied or not
|
|
261
|
+
https://drachtio.org/docs/api#Dialog+modify
|
|
262
|
+
*/
|
|
263
|
+
modify( options, cb ) {
|
|
264
|
+
if( cb ) {
|
|
265
|
+
cb()
|
|
266
|
+
return this
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return new Promise( ( resolve ) => {
|
|
270
|
+
resolve( this )
|
|
271
|
+
} )
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
class srf {
|
|
276
|
+
constructor() {
|
|
277
|
+
|
|
278
|
+
this.callbacks = {
|
|
279
|
+
"createuac": false,
|
|
280
|
+
"createuas": false
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
this.newuactimeout = 0
|
|
284
|
+
|
|
285
|
+
this._createuaccount = 0
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
use( method ) {
|
|
289
|
+
expect( method ).to.equal( "invite" )
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
async createUAC( contact, options, callbacks ) {
|
|
293
|
+
this._createuaccount++
|
|
294
|
+
let _req = new req()
|
|
295
|
+
|
|
296
|
+
/* create a default */
|
|
297
|
+
callbacks.cbRequest( {}, _req )
|
|
298
|
+
|
|
299
|
+
if( this.callbacks.createuac ) {
|
|
300
|
+
return this.callbacks.createuac( contact, options, callbacks )
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if( this.newuactimeout > 0 ) {
|
|
304
|
+
await new Promise( ( resolve ) => { setTimeout( () => resolve(), this.newuactimeout ) } )
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return new dialog( _req )
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async createUAS( req, res, options ) {
|
|
311
|
+
if( this.callbacks.createuas ) return this.callbacks.createuas( req, res, options )
|
|
312
|
+
|
|
313
|
+
/* create a default */
|
|
314
|
+
return new dialog()
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/*
|
|
319
|
+
1st attempt is bad becuase it is too difficult to see what the test is doing which
|
|
320
|
+
is bad testing.
|
|
321
|
+
Our setup of the test and our mock objects need to look simple and are easily explainable.
|
|
322
|
+
*/
|
|
323
|
+
class srfscenario {
|
|
324
|
+
constructor( options ) {
|
|
325
|
+
/* every scenario we restart spd */
|
|
326
|
+
sdpid = 0
|
|
327
|
+
|
|
328
|
+
this.callbacks = {
|
|
329
|
+
"trying": false,
|
|
330
|
+
"ringing": false,
|
|
331
|
+
"call": false
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
let defaultoptions = {
|
|
335
|
+
"method": "invite",
|
|
336
|
+
"uacsdp": possiblesdp[ 0 ],
|
|
337
|
+
"uassdp": possiblesdp[ 1 ]
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
this.options = { ...defaultoptions, ...options }
|
|
341
|
+
this.options.srf = new srf()
|
|
342
|
+
|
|
343
|
+
this.options.em = new events.EventEmitter()
|
|
344
|
+
|
|
345
|
+
callmanager.callmanager( this.options )
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
ontrying( cb ) {
|
|
349
|
+
this.callbacks.trying = cb
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
onringing( cb ) {
|
|
353
|
+
this.callbacks.ringing = cb
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
oncall( cb ) {
|
|
357
|
+
this.callbacks.call = cb
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
oncreateUAC( cb ) {
|
|
361
|
+
this.options.srf.callbacks.createuac = cb
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
oncreateUAS( cb ) {
|
|
365
|
+
this.options.srf.callbacks.createuas = cb
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/*
|
|
369
|
+
simulate a new inbound call
|
|
370
|
+
*/
|
|
371
|
+
inbound() {
|
|
372
|
+
if( this.callbacks.call ) {
|
|
373
|
+
this.req = new req( new options() )
|
|
374
|
+
this.res = new res()
|
|
375
|
+
|
|
376
|
+
let newcall = call.frominvite( this.req, this.res )
|
|
377
|
+
this.callbacks.call( newcall )
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
module.exports.req = req
|
|
384
|
+
module.exports.res = res
|
|
385
|
+
module.exports.dialog = dialog
|
|
386
|
+
module.exports.options = options
|
|
387
|
+
module.exports.srfscenario = srfscenario
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
const expect = require( "chai" ).expect
|
|
2
|
+
const callstore = require( "../../lib/store.js" )
|
|
3
|
+
|
|
4
|
+
describe( "callmanager - store", function() {
|
|
5
|
+
|
|
6
|
+
afterEach( function() {
|
|
7
|
+
callstore.clear()
|
|
8
|
+
} )
|
|
9
|
+
|
|
10
|
+
it( `simple store`, async function() {
|
|
11
|
+
let dummycall = {
|
|
12
|
+
"uuid": "1",
|
|
13
|
+
"_entity": {
|
|
14
|
+
"uri": "1234@domain"
|
|
15
|
+
},
|
|
16
|
+
"sip": {
|
|
17
|
+
"callid": "1234",
|
|
18
|
+
"tags": {
|
|
19
|
+
"local": "",
|
|
20
|
+
"remote": "1111"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
await callstore.set( dummycall )
|
|
25
|
+
expect( await callstore.stats() ).to.deep.include( {
|
|
26
|
+
"storebycallid": 1,
|
|
27
|
+
"storebyuuid": 1,
|
|
28
|
+
"storebyentity": 1
|
|
29
|
+
} )
|
|
30
|
+
} )
|
|
31
|
+
|
|
32
|
+
it( `simple store with update of local tag`, async function() {
|
|
33
|
+
let dummycall = {
|
|
34
|
+
"uuid": "1",
|
|
35
|
+
"_entity": {
|
|
36
|
+
"uri": "1234@domain"
|
|
37
|
+
},
|
|
38
|
+
"sip": {
|
|
39
|
+
"callid": "1234",
|
|
40
|
+
"tags": {
|
|
41
|
+
"local": "",
|
|
42
|
+
"remote": "1111"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
await callstore.set( dummycall )
|
|
47
|
+
expect( await callstore.stats() ).to.deep.include( {
|
|
48
|
+
"storebycallid": 1,
|
|
49
|
+
"storebyuuid": 1,
|
|
50
|
+
"storebyentity": 1
|
|
51
|
+
} )
|
|
52
|
+
|
|
53
|
+
dummycall.sip.tags.local = "4444"
|
|
54
|
+
|
|
55
|
+
await callstore.set( dummycall )
|
|
56
|
+
expect( await callstore.stats() ).to.deep.include( {
|
|
57
|
+
"storebycallid": 1,
|
|
58
|
+
"storebyuuid": 1,
|
|
59
|
+
"storebyentity": 1
|
|
60
|
+
} )
|
|
61
|
+
|
|
62
|
+
let searchfor = {
|
|
63
|
+
"callid": "1234",
|
|
64
|
+
"tags": {
|
|
65
|
+
"local": dummycall.sip.tags.local,
|
|
66
|
+
"remote": dummycall.sip.tags.remote
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
let call = await callstore.getbycallid( searchfor )
|
|
70
|
+
expect( call._entity.uri ).to.be.equal( "1234@domain" )
|
|
71
|
+
} )
|
|
72
|
+
|
|
73
|
+
it( `call set three calls add entity`, async function() {
|
|
74
|
+
|
|
75
|
+
let dummycall1 = {
|
|
76
|
+
"uuid": "1",
|
|
77
|
+
"sip": {
|
|
78
|
+
"callid": "1234",
|
|
79
|
+
"tags": {
|
|
80
|
+
"local": "",
|
|
81
|
+
"remote": "1111"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let dummycall2 = {
|
|
87
|
+
"uuid": "2",
|
|
88
|
+
"sip": {
|
|
89
|
+
"callid": "224435",
|
|
90
|
+
"tags": {
|
|
91
|
+
"local": "",
|
|
92
|
+
"remote": "1234"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let dummycall3 = {
|
|
98
|
+
"uuid": "3",
|
|
99
|
+
"sip": {
|
|
100
|
+
"callid": "555666",
|
|
101
|
+
"tags": {
|
|
102
|
+
"local": "",
|
|
103
|
+
"remote": "4321"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
await callstore.set( dummycall1 )
|
|
109
|
+
await callstore.set( dummycall2 )
|
|
110
|
+
|
|
111
|
+
expect( await callstore.stats() ).to.deep.include( {
|
|
112
|
+
"storebycallid": 2,
|
|
113
|
+
"storebyuuid": 2,
|
|
114
|
+
"storebyentity": 0
|
|
115
|
+
} )
|
|
116
|
+
|
|
117
|
+
dummycall1._entity = {
|
|
118
|
+
"uri": "1000@testdomain"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
await callstore.set( dummycall1 )
|
|
122
|
+
|
|
123
|
+
expect( await callstore.stats() ).to.deep.include( {
|
|
124
|
+
"storebycallid": 2,
|
|
125
|
+
"storebyuuid": 2,
|
|
126
|
+
"storebyentity": 1
|
|
127
|
+
} )
|
|
128
|
+
|
|
129
|
+
await callstore.set( dummycall3 )
|
|
130
|
+
|
|
131
|
+
expect( await callstore.stats() ).to.deep.include( {
|
|
132
|
+
"storebycallid": 3,
|
|
133
|
+
"storebyuuid": 3,
|
|
134
|
+
"storebyentity": 1
|
|
135
|
+
} )
|
|
136
|
+
|
|
137
|
+
let c = await callstore.getbycallid( dummycall1.sip )
|
|
138
|
+
expect( c.uuid ).to.equal( "1" )
|
|
139
|
+
|
|
140
|
+
let ce = await callstore.getbyentity( dummycall1._entity.uri ) // Map
|
|
141
|
+
expect( ce.get( dummycall1.uuid ).uuid ).to.equal( "1" )
|
|
142
|
+
|
|
143
|
+
callstore.delete( dummycall1 )
|
|
144
|
+
callstore.delete( dummycall2 )
|
|
145
|
+
callstore.delete( dummycall3 )
|
|
146
|
+
|
|
147
|
+
expect( await callstore.stats() ).to.deep.include( {
|
|
148
|
+
"storebycallid": 0,
|
|
149
|
+
"storebyuuid": 0,
|
|
150
|
+
"storebyentity": 0
|
|
151
|
+
} )
|
|
152
|
+
} )
|
|
153
|
+
} )
|