Comparing version 0.7.1 to 0.7.2
{ | ||
"name": "sip.js", | ||
"version": "0.7.1", | ||
"version": "0.7.2", | ||
"authors": [ | ||
@@ -5,0 +5,0 @@ "Will Mitchell <will@onsip.com>", |
@@ -5,3 +5,3 @@ { | ||
"description": "A simple, intuitive, and powerful JavaScript signaling library", | ||
"version": "0.7.1", | ||
"version": "0.7.2", | ||
"main": "src/index.js", | ||
@@ -8,0 +8,0 @@ "browser": { |
@@ -13,19 +13,66 @@ # How To version release SIP.js | ||
1. On your own github, checkout last tagged release on a new branch | ||
2. remove all dist files | ||
3. cherry pick commits you want using -x flag (for "hot patch" releases) | ||
4. once ready, test. | ||
5. update version number on master | ||
6. cherry pick version number commit to new branch | ||
7. build and test. | ||
8. test again | ||
9. add new dist files (git add -f if it complains) | ||
10. test npm and bower (bower might require push to local github) | ||
11. push to local github | ||
12. merge | ||
13. git tag (your version number) | ||
14. git push --tags | ||
15. get a clean release | ||
16. npm publish | ||
17. do release notes on github and release! | ||
18. update website | ||
* On your own github, checkout last tagged release on a new branch | ||
* remove all dist files | ||
* cherry pick commits you want using -x flag (for "hot patch" releases) | ||
* once ready, test. | ||
* update version number on master | ||
* cherry pick version number commit to new branch | ||
* build and test. | ||
* test again | ||
* add new dist files (git add -f if it complains) | ||
* test npm: | ||
```shell | ||
#!/usr/bin/env bash | ||
set -e | ||
SIPJS_DIR=`pwd` | ||
cd /tmp | ||
rm -rf node_modules | ||
npm install $SIPJS_DIR | ||
node -e "var SIP = require('sip.js'); new SIP.UA({traceSip: true}); setTimeout(process.exit, 2000)" | ||
cd node_modules/sip.js && npm install && npm test | ||
SIPJS_TEST="var SIP = require('sip.js'); var session = new SIP.UA({traceSip: true}).invite('welcome@onsip.com', new Audio());" | ||
SIPJS_TEST+="session.on('accepted', setTimeout.bind(null, window.close, 5000))" | ||
npm install -g browserify smokestack | ||
browserify -r sip.js | cat - <(echo $SIPJS_TEST) | smokestack | ||
# more tests | ||
cd $SIPJS_DIR | ||
set +e | ||
``` | ||
* test bower: | ||
```shell | ||
#!/usr/bin/env bash | ||
set -e | ||
SIPJS_DIR=`pwd` | ||
SIPJS_HASH=`git rev-parse HEAD` | ||
cd /tmp | ||
rm -rf bower_components | ||
bower install "$SIPJS_DIR/.git#$SIPJS_HASH" | ||
SIPJS_TEST="var session = new SIP.UA({traceSip: true}).invite('welcome@onsip.com', new Audio());" | ||
SIPJS_TEST+="session.on('accepted', setTimeout.bind(null, window.close, 5000))" | ||
npm install -g smokestack | ||
cat ./bower_components/sip.js/dist/sip.min.js <(echo $SIPJS_TEST) | smokestack | ||
# more tests | ||
cd $SIPJS_DIR | ||
set +e | ||
``` | ||
* push to local github | ||
* merge | ||
* git tag (your version number) | ||
* git push --tags | ||
* get a clean release | ||
* npm publish | ||
* do release notes on github and release! | ||
* update website |
@@ -159,4 +159,43 @@ "use strict"; | ||
606: 'Not Acceptable' | ||
}, | ||
/* SIP Option Tags | ||
* DOC: http://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml#sip-parameters-4 | ||
*/ | ||
OPTION_TAGS: { | ||
'100rel': true, // RFC 3262 | ||
199: true, // RFC 6228 | ||
answermode: true, // RFC 5373 | ||
'early-session': true, // RFC 3959 | ||
eventlist: true, // RFC 4662 | ||
explicitsub: true, // RFC-ietf-sipcore-refer-explicit-subscription-03 | ||
'from-change': true, // RFC 4916 | ||
'geolocation-http': true, // RFC 6442 | ||
'geolocation-sip': true, // RFC 6442 | ||
gin: true, // RFC 6140 | ||
gruu: true, // RFC 5627 | ||
histinfo: true, // RFC 7044 | ||
ice: true, // RFC 5768 | ||
join: true, // RFC 3911 | ||
'multiple-refer': true, // RFC 5368 | ||
norefersub: true, // RFC 4488 | ||
nosub: true, // RFC-ietf-sipcore-refer-explicit-subscription-03 | ||
outbound: true, // RFC 5626 | ||
path: true, // RFC 3327 | ||
policy: true, // RFC 6794 | ||
precondition: true, // RFC 3312 | ||
pref: true, // RFC 3840 | ||
privacy: true, // RFC 3323 | ||
'recipient-list-invite': true, // RFC 5366 | ||
'recipient-list-message': true, // RFC 5365 | ||
'recipient-list-subscribe': true, // RFC 5367 | ||
replaces: true, // RFC 3891 | ||
'resource-priority': true, // RFC 4412 | ||
'sdp-anat': true, // RFC 4092 | ||
'sec-agree': true, // RFC 3329 | ||
tdialog: true, // RFC 4538 | ||
timer: true, // RFC 4028 | ||
uui: true // RFC 7433 | ||
} | ||
}; | ||
}; |
@@ -10,2 +10,4 @@ { | ||
"Subscription_State", | ||
"Supported", | ||
"Require", | ||
"Via", | ||
@@ -23,2 +25,3 @@ "absoluteURI", | ||
"Max_Forwards", | ||
"Min_SE", | ||
"Proxy_Authenticate", | ||
@@ -28,2 +31,3 @@ "quoted_string", | ||
"Replaces", | ||
"Session_Expires", | ||
"stun_URI", | ||
@@ -30,0 +34,0 @@ "To", |
@@ -210,3 +210,5 @@ "use strict"; | ||
if(!this.registered) { | ||
options = options || {}; | ||
if(!this.registered && !options.all) { | ||
this.logger.warn('already unregistered'); | ||
@@ -216,3 +218,2 @@ return; | ||
options = options || {}; | ||
extraHeaders = (options.extraHeaders || []).slice(); | ||
@@ -219,0 +220,0 @@ |
@@ -7,3 +7,2 @@ /** | ||
var SIP = {}; | ||
module.exports = function (environment) { | ||
@@ -13,3 +12,3 @@ | ||
Object.defineProperties(SIP, { | ||
var SIP = Object.defineProperties({}, { | ||
version: { | ||
@@ -16,0 +15,0 @@ get: function(){ return pkg.version; } |
@@ -13,2 +13,35 @@ "use strict"; | ||
function getSupportedHeader (request) { | ||
var allowUnregistered = request.ua.configuration.hackAllowUnregisteredOptionTags; | ||
var optionTags = []; | ||
var optionTagSet = {}; | ||
if (request.method === SIP.C.REGISTER) { | ||
optionTags.push('path', 'gruu'); | ||
} else if (request.method === SIP.C.INVITE && | ||
(request.ua.contact.pub_gruu || request.ua.contact.temp_gruu)) { | ||
optionTags.push('gruu'); | ||
} | ||
if (request.ua.configuration.rel100 === SIP.C.supported.SUPPORTED) { | ||
optionTags.push('100rel'); | ||
} | ||
if (request.ua.configuration.replaces === SIP.C.supported.SUPPORTED) { | ||
optionTags.push('replaces'); | ||
} | ||
optionTags.push('outbound'); | ||
optionTags = optionTags.concat(request.ua.configuration.extraSupported); | ||
optionTags = optionTags.filter(function(optionTag) { | ||
var registered = SIP.C.OPTION_TAGS[optionTag]; | ||
var unique = !optionTagSet[optionTag]; | ||
optionTagSet[optionTag] = true; | ||
return (registered || allowUnregistered) && unique; | ||
}); | ||
return 'Supported: ' + optionTags.join(', ') + '\r\n'; | ||
} | ||
/** | ||
@@ -31,3 +64,5 @@ * @augments SIP | ||
call_id, | ||
cseq; | ||
cseq, | ||
to_uri, | ||
from_uri; | ||
@@ -68,4 +103,5 @@ params = params || {}; | ||
// To | ||
to_uri = params.to_uri || ruri; | ||
to = (params.to_displayName || params.to_displayName === 0) ? '"' + params.to_displayName + '" ' : ''; | ||
to += '<' + (params.to_uri || ruri) + '>'; | ||
to += '<' + (to_uri && to_uri.toRaw ? to_uri.toRaw() : to_uri) + '>'; | ||
to += params.to_tag ? ';tag=' + params.to_tag : ''; | ||
@@ -76,2 +112,3 @@ this.to = new SIP.NameAddrHeader.parse(to); | ||
// From | ||
from_uri = params.from_uri || ua.configuration.uri; | ||
if (params.from_displayName || params.from_displayName === 0) { | ||
@@ -84,3 +121,3 @@ from = '"' + params.from_displayName + '" '; | ||
} | ||
from += '<' + (params.from_uri || ua.configuration.uri) + '>;tag='; | ||
from += '<' + (from_uri && from_uri.toRaw ? from_uri.toRaw() : from_uri) + '>;tag='; | ||
from += params.from_tag || SIP.Utils.newTag(); | ||
@@ -191,5 +228,5 @@ this.from = new SIP.NameAddrHeader.parse(from); | ||
toString: function() { | ||
var msg = '', header, length, idx, supported = []; | ||
var msg = '', header, length, idx; | ||
msg += this.method + ' ' + this.ruri + ' SIP/2.0\r\n'; | ||
msg += this.method + ' ' + (this.ruri.toRaw ? this.ruri.toRaw() : this.ruri) + ' SIP/2.0\r\n'; | ||
@@ -208,20 +245,3 @@ for (header in this.headers) { | ||
//Supported | ||
if (this.method === SIP.C.REGISTER) { | ||
supported.push('path', 'gruu'); | ||
} else if (this.method === SIP.C.INVITE && | ||
(this.ua.contact.pub_gruu || this.ua.contact.temp_gruu)) { | ||
supported.push('gruu'); | ||
} | ||
if (this.ua.configuration.rel100 === SIP.C.supported.SUPPORTED) { | ||
supported.push('100rel'); | ||
} | ||
if (this.ua.configuration.replaces === SIP.C.supported.SUPPORTED) { | ||
supported.push('replaces'); | ||
} | ||
supported.push('outbound'); | ||
msg += 'Supported: ' + supported +'\r\n'; | ||
msg += getSupportedHeader(this); | ||
msg += 'User-Agent: ' + this.ua.configuration.userAgentString +'\r\n'; | ||
@@ -421,3 +441,2 @@ | ||
var rr, vias, length, idx, response, | ||
supported = [], | ||
to = this.getHeader('To'), | ||
@@ -462,18 +481,3 @@ r = 0, | ||
//Supported | ||
if (this.method === SIP.C.INVITE && | ||
(this.ua.contact.pub_gruu || this.ua.contact.temp_gruu)) { | ||
supported.push('gruu'); | ||
} | ||
if (this.ua.configuration.rel100 === SIP.C.supported.SUPPORTED) { | ||
supported.push('100rel'); | ||
} | ||
if (this.ua.configuration.replaces === SIP.C.supported.SUPPORTED) { | ||
supported.push('replaces'); | ||
} | ||
supported.push('outbound'); | ||
response += 'Supported: ' + supported + '\r\n'; | ||
response += getSupportedHeader(this); | ||
response += 'User-Agent: ' + this.ua.configuration.userAgentString +'\r\n'; | ||
@@ -480,0 +484,0 @@ |
@@ -99,2 +99,4 @@ "use strict"; | ||
if (expires && expires <= this.expires) { | ||
// Preserve new expires value for subsequent requests | ||
this.expires = expires; | ||
this.timers.sub_duration = SIP.Timers.setTimeout(sub.refresh.bind(sub), expires * 900); | ||
@@ -203,2 +205,3 @@ } else { | ||
if (sub_state.expires) { | ||
SIP.Timers.clearTimeout(sub.timers.sub_duration); | ||
sub_state.expires = Math.min(sub.expires, | ||
@@ -221,3 +224,2 @@ Math.max(sub_state.expires, 0)); | ||
SIP.Timers.clearTimeout(this.timers.N); | ||
SIP.Timers.clearTimeout(this.timers.sub_duration); | ||
@@ -238,2 +240,3 @@ this.emit('notify', {request: request}); | ||
case 'terminated': | ||
SIP.Timers.clearTimeout(this.timers.sub_duration); | ||
if (sub_state.reason) { | ||
@@ -240,0 +243,0 @@ this.logger.log('terminating subscription with reason '+ sub_state.reason); |
@@ -238,2 +238,3 @@ "use strict"; | ||
this.ack += 'Call-ID: ' + this.request.headers['Call-ID'].toString() + '\r\n'; | ||
this.ack += 'Content-Length: 0\r\n'; | ||
this.ack += 'CSeq: ' + this.request.headers['CSeq'].toString().split(' ')[0]; | ||
@@ -240,0 +241,0 @@ this.ack += ' ACK\r\n\r\n'; |
@@ -34,2 +34,3 @@ "use strict"; | ||
this.keepAliveInterval = ua.configuration.keepAliveInterval; | ||
this.keepAliveTimeout = null; | ||
this.keepAliveTimer = null; | ||
@@ -70,2 +71,8 @@ | ||
sendKeepAlive: function() { | ||
if(this.keepAliveTimeout) { return; } | ||
this.keepAliveTimeout = SIP.Timers.setTimeout(function() { | ||
this.ua.emit('keepAliveTimeout'); | ||
}.bind(this), 10000); | ||
return this.send('\r\n\r\n'); | ||
@@ -94,3 +101,5 @@ }, | ||
SIP.Timers.clearTimeout(this.keepAliveTimer); | ||
SIP.Timers.clearTimeout(this.keepAliveTimeout); | ||
this.keepAliveTimer = null; | ||
this.keepAliveTimeout = null; | ||
}, | ||
@@ -247,5 +256,9 @@ | ||
if(data === '\r\n') { | ||
SIP.Timers.clearTimeout(this.keepAliveTimeout); | ||
this.keepAliveTimeout = null; | ||
if (this.ua.configuration.traceSip === true) { | ||
this.logger.log('received WebSocket message with CRLF Keep Alive response'); | ||
} | ||
return; | ||
@@ -252,0 +265,0 @@ } |
@@ -211,4 +211,6 @@ "use strict"; | ||
this.configuration.register = false; | ||
this.registerContext.unregister(options); | ||
var context = this.registerContext; | ||
this.afterConnected(context.unregister.bind(context, options)); | ||
return this; | ||
@@ -890,2 +892,4 @@ }; | ||
extraSupported: [], | ||
usePreloadedRoute: false, | ||
@@ -909,2 +913,3 @@ | ||
hackWssInTransport: false, | ||
hackAllowUnregisteredOptionTags: false, | ||
@@ -1021,3 +1026,3 @@ contactTransport: 'ws', | ||
hostportParams.user = null; | ||
settings.hostportParams = hostportParams.toString().replace(/^sip:/i, ''); | ||
settings.hostportParams = hostportParams.toRaw().replace(/^sip:/i, ''); | ||
@@ -1137,2 +1142,3 @@ /* Check whether authorizationUser is explicitly defined. | ||
"keepAliveInterval", | ||
"extraSupported", | ||
"displayName", | ||
@@ -1142,2 +1148,3 @@ "hackViaTcp", // false. | ||
"hackWssInTransport", //false | ||
"hackAllowUnregisteredOptionTags", //false | ||
"contactTransport", // 'ws' | ||
@@ -1327,6 +1334,3 @@ "forceRport", // false | ||
if(SIP.Utils.isDecimal(iceCheckingTimeout)) { | ||
if (iceCheckingTimeout < 500) { | ||
return 5000; | ||
} | ||
return iceCheckingTimeout; | ||
return Math.max(500, iceCheckingTimeout); | ||
} | ||
@@ -1341,2 +1345,8 @@ }, | ||
hackAllowUnregisteredOptionTags: function(hackAllowUnregisteredOptionTags) { | ||
if (typeof hackAllowUnregisteredOptionTags === 'boolean') { | ||
return hackAllowUnregisteredOptionTags; | ||
} | ||
}, | ||
contactTransport: function(contactTransport) { | ||
@@ -1380,2 +1390,19 @@ if (typeof contactTransport === 'string') { | ||
extraSupported: function(optionTags) { | ||
var idx, length; | ||
if (!(optionTags instanceof Array)) { | ||
return; | ||
} | ||
length = optionTags.length; | ||
for (idx = 0; idx < length; idx++) { | ||
if (typeof optionTags[idx] !== 'string') { | ||
return; | ||
} | ||
} | ||
return optionTags; | ||
}, | ||
noAnswerTimeout: function(noAnswerTimeout) { | ||
@@ -1382,0 +1409,0 @@ var value; |
100
src/URI.js
@@ -22,3 +22,3 @@ "use strict"; | ||
URI = function(scheme, user, host, port, parameters, headers) { | ||
var param, header; | ||
var param, header, raw, normal; | ||
@@ -43,7 +43,32 @@ // Checks | ||
// Raw URI | ||
raw = { | ||
scheme: scheme, | ||
user: user, | ||
host: host, | ||
port: port | ||
}; | ||
// Normalized URI | ||
normal = { | ||
scheme: scheme.toLowerCase(), | ||
user: user, | ||
host: host.toLowerCase(), | ||
port: port | ||
}; | ||
Object.defineProperties(this, { | ||
_normal: { | ||
get: function() { return normal; } | ||
}, | ||
_raw: { | ||
get: function() { return raw; } | ||
}, | ||
scheme: { | ||
get: function(){ return scheme; }, | ||
set: function(value){ | ||
scheme = value.toLowerCase(); | ||
get: function() { return normal.scheme; }, | ||
set: function(value) { | ||
raw.scheme = value; | ||
normal.scheme = value.toLowerCase(); | ||
} | ||
@@ -53,5 +78,5 @@ }, | ||
user: { | ||
get: function(){ return user; }, | ||
set: function(value){ | ||
user = value; | ||
get: function() { return normal.user; }, | ||
set: function(value) { | ||
normal.user = raw.user = value; | ||
} | ||
@@ -61,5 +86,6 @@ }, | ||
host: { | ||
get: function(){ return host; }, | ||
set: function(value){ | ||
host = value.toLowerCase(); | ||
get: function() { return normal.host; }, | ||
set: function(value) { | ||
raw.host = value; | ||
normal.host = value.toLowerCase(); | ||
} | ||
@@ -69,9 +95,9 @@ }, | ||
aor: { | ||
get: function(){ return user + '@' + host; } | ||
get: function() { return normal.user + '@' + normal.host; } | ||
}, | ||
port: { | ||
get: function(){ return port; }, | ||
set: function(value){ | ||
port = value === 0 ? value : (parseInt(value,10) || null); | ||
get: function() { return normal.port; }, | ||
set: function(value) { | ||
normal.port = raw.port = value === 0 ? value : (parseInt(value,10) || null); | ||
} | ||
@@ -81,2 +107,3 @@ } | ||
}; | ||
URI.prototype = { | ||
@@ -147,6 +174,6 @@ setParam: function(key, value) { | ||
return new URI( | ||
this.scheme, | ||
this.user, | ||
this.host, | ||
this.port, | ||
this._raw.scheme, | ||
this._raw.user, | ||
this._raw.host, | ||
this._raw.port, | ||
JSON.parse(JSON.stringify(this.parameters)), | ||
@@ -156,24 +183,31 @@ JSON.parse(JSON.stringify(this.headers))); | ||
toString: function(){ | ||
var header, parameter, idx, uri, | ||
headers = []; | ||
toRaw: function() { | ||
return this._toString(this._raw); | ||
}, | ||
uri = this.scheme + ':'; | ||
toString: function() { | ||
return this._toString(this._normal); | ||
}, | ||
_toString: function(uri) { | ||
var header, parameter, idx, uriString, headers = []; | ||
uriString = uri.scheme + ':'; | ||
// add slashes if it's not a sip(s) URI | ||
if (!this.scheme.match("^sips?$")) { | ||
uri += "//"; | ||
if (!uri.scheme.toLowerCase().match("^sips?$")) { | ||
uriString += "//"; | ||
} | ||
if (this.user) { | ||
uri += SIP.Utils.escapeUser(this.user) + '@'; | ||
if (uri.user) { | ||
uriString += SIP.Utils.escapeUser(uri.user) + '@'; | ||
} | ||
uri += this.host; | ||
if (this.port || this.port === 0) { | ||
uri += ':' + this.port; | ||
uriString += uri.host; | ||
if (uri.port || uri.port === 0) { | ||
uriString += ':' + uri.port; | ||
} | ||
for (parameter in this.parameters) { | ||
uri += ';' + parameter; | ||
uriString += ';' + parameter; | ||
if (this.parameters[parameter] !== null) { | ||
uri += '='+ this.parameters[parameter]; | ||
uriString += '='+ this.parameters[parameter]; | ||
} | ||
@@ -189,6 +223,6 @@ } | ||
if (headers.length > 0) { | ||
uri += '?' + headers.join('&'); | ||
uriString += '?' + headers.join('&'); | ||
} | ||
return uri; | ||
return uriString; | ||
} | ||
@@ -195,0 +229,0 @@ }; |
@@ -207,2 +207,3 @@ "use strict"; | ||
'Cseq': 'CSeq', | ||
'Min-Se': 'Min-SE', | ||
'Rack': 'RAck', | ||
@@ -209,0 +210,0 @@ 'Rseq': 'RSeq', |
@@ -90,2 +90,11 @@ "use strict"; | ||
this.startIceCheckingTimer = function () { | ||
if (!self.iceCheckingTimer) { | ||
self.iceCheckingTimer = SIP.Timers.setTimeout(function() { | ||
self.logger.log('RTCIceChecking Timeout Triggered after '+config.iceCheckingTimeout+' milliseconds'); | ||
self.onIceCompleted.resolve(this); | ||
}.bind(this.peerConnection), config.iceCheckingTimeout); | ||
} | ||
}; | ||
this.peerConnection.onicecandidate = function(e) { | ||
@@ -95,8 +104,3 @@ self.emit('iceCandidate', e); | ||
self.logger.log('ICE candidate received: '+ (e.candidate.candidate === null ? null : e.candidate.candidate.trim())); | ||
if (!self.iceCheckingTimer) { | ||
self.iceCheckingTimer = SIP.Timers.setTimeout(function() { | ||
self.logger.log('RTCIceChecking Timeout Triggered after '+config.iceCheckingTimeout+' milliseconds'); | ||
self.onIceCompleted.resolve(this); | ||
}.bind(this), config.iceCheckingTimeout); | ||
} | ||
self.startIceCheckingTimer(); | ||
} else { | ||
@@ -120,7 +124,4 @@ self.onIceCompleted.resolve(this); | ||
if (this.iceConnectionState === 'checking' && !self.iceCheckingTimer) { | ||
self.iceCheckingTimer = SIP.Timers.setTimeout(function() { | ||
self.logger.log('RTCIceChecking Timeout Triggered after '+config.iceCheckingTimeout+' milliseconds'); | ||
self.onIceCompleted.resolve(this); | ||
}.bind(this), config.iceCheckingTimeout); | ||
if (this.iceConnectionState === 'checking') { | ||
self.startIceCheckingTimer(); | ||
} | ||
@@ -127,0 +128,0 @@ |
@@ -150,3 +150,5 @@ "use strict"; | ||
if (this.acquisitions[streamId] === false) { | ||
stream.stop(); | ||
stream.getTracks().forEach(function (track) { | ||
track.stop(); | ||
}); | ||
} | ||
@@ -153,0 +155,0 @@ delete this.acquisitions[streamId]; |
@@ -49,10 +49,17 @@ (function () { | ||
getUserMedia.fakeStream = function () { | ||
var audioTracks = [{ | ||
id: Math.random().toString(), | ||
stop: jasmine.createSpy('stop'), | ||
}]; | ||
var videoTracks = []; | ||
return { | ||
getAudioTracks: function(id){ | ||
return [{ | ||
id: id | ||
}]; | ||
}.bind(null, Math.random().toString()), | ||
getVideoTracks: function(){return [];}, | ||
stop: jasmine.createSpy('stop') | ||
getAudioTracks: function () { | ||
return audioTracks; | ||
}, | ||
getTracks: function () { | ||
return audioTracks.concat(videoTracks); | ||
}, | ||
getVideoTracks: function () { | ||
return videoTracks; | ||
}, | ||
}; | ||
@@ -59,0 +66,0 @@ }; |
@@ -132,5 +132,7 @@ describe('MediaStreamManager', function () { | ||
it('calls stop() on the MediaStream it was passed', function () { | ||
it('calls stop() on the tracks of the MediaStream it was passed', function () { | ||
expect(acquiredStream).not.toBeNull(); | ||
expect(acquiredStream.stop).toHaveBeenCalled(); | ||
acquiredStream.getTracks().forEach(function (track) { | ||
expect(track.stop).toHaveBeenCalled(); | ||
}); | ||
}); | ||
@@ -173,7 +175,9 @@ }); | ||
it('.release does not stop the stream', function (done) { | ||
it('.release does not stop the stream\'s tracks', function (done) { | ||
mediaStreamManager.acquire(mediaHint).then(onSuccess, onFailure) | ||
.then(function () { | ||
mediaStreamManager.release(stream); | ||
expect(stream.stop).not.toHaveBeenCalled(); | ||
stream.getTracks().forEach(function (track) { | ||
expect(track.stop).not.toHaveBeenCalled(); | ||
}); | ||
done(); | ||
@@ -180,0 +184,0 @@ }); |
@@ -77,2 +77,30 @@ describe('RegisterContext', function() { | ||
it('retries with the min-expires header on 423', function() { | ||
RegisterContext.register(options); | ||
var response = new SIP.IncomingResponse(ua); | ||
response.status_code = 423; | ||
response.cseq = RegisterContext.cseq; | ||
response.setHeader('min-expires', 555555); | ||
RegisterContext.receiveResponse(response); | ||
expect(RegisterContext.expires >= 555555).toBeTruthy(); | ||
}); | ||
it('fails registration on 423 with no min-expires header', function() { | ||
RegisterContext.register(options); | ||
spyOn(RegisterContext, 'registrationFailure').and.returnValue('registrationFailure'); | ||
var response = new SIP.IncomingResponse(ua); | ||
response.status_code = 423; | ||
response.cseq = RegisterContext.cseq; | ||
response.headers['min-expires'] = undefined; | ||
RegisterContext.receiveResponse(response); | ||
expect(RegisterContext.registrationFailure).toHaveBeenCalled(); | ||
}); | ||
it('sets its closeHeaders property if options.closeWithHeaders flag is true', function() { | ||
@@ -218,4 +246,12 @@ RegisterContext.register({ | ||
expect(RegisterContext.request.extraHeaders).toEqual([ 'Contact: *', 'Expires: 0' ]); | ||
}); | ||
it('even when unregistered, pushes extra headers Contact: *, Expires: 0 if options.all is truthy', function() { | ||
var options = { all : true }; | ||
RegisterContext.registered = false; | ||
expect(RegisterContext.send).not.toHaveBeenCalled(); | ||
RegisterContext.unregister(options); | ||
expect(RegisterContext.send).toHaveBeenCalledWith(); | ||
expect(RegisterContext.request.extraHeaders).toEqual([ 'Contact: *', 'Expires: 0' ]); | ||
}); | ||
@@ -222,0 +258,0 @@ it('pushes extra headers Contact: <contact>, Expires: 0 if options.all is falsy', function() { |
@@ -279,2 +279,7 @@ describe("URI", function() { | ||
expect(clonedURI.headers).toEqual(URI.headers); | ||
expect(clonedURI._raw.scheme).toEqual(URI._raw.scheme); | ||
expect(clonedURI._raw.user).toEqual(URI._raw.user); | ||
expect(clonedURI._raw.host).toEqual(URI._raw.host); | ||
expect(clonedURI._raw.port).toEqual(URI._raw.port); | ||
}); | ||
@@ -352,2 +357,3 @@ | ||
itsMethod('correctly toString()s itself', 'toString', undefined, 'sip:aliCE@versatica.com:6060;transport=tcp;foo=abc;baz?X-Header-1=AaA1&X-Header-1=AAA2&X-Header-2=BbB'); | ||
itsMethod('correctly toRaw()s itself', 'toRaw', undefined, 'SIP:aliCE@versaTICA.Com:6060;transport=tcp;foo=abc;baz?X-Header-1=AaA1&X-Header-1=AAA2&X-Header-2=BbB'); | ||
@@ -354,0 +360,0 @@ var newUser = 'Iñaki:PASSWD'; |
@@ -15,2 +15,6 @@ THANKS | ||
* [Destreyf](https://github.com/Destreyf) | ||
* [Mark Roberts](https://github.com/markandrus) | ||
* [Ryan Rowland](https://github.com/ryan-rowland) | ||
* [Ben Langfeld](https://github.com/benlangfeld) | ||
* [Gerik Bonaert](https://github.com/adaxi) | ||
@@ -17,0 +21,0 @@ Much credit goes to the original authors of the JsSIP project. Thank you to all. |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
791641
18457