New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

sip.js

Package Overview
Dependencies
Maintainers
2
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sip.js - npm Package Compare versions

Comparing version 0.7.2 to 0.7.3

2

bower.json
{
"name": "sip.js",
"version": "0.7.2",
"version": "0.7.3",
"authors": [

@@ -5,0 +5,0 @@ "Will Mitchell <will@onsip.com>",

@@ -55,3 +55,3 @@ /*jshint multistr:true, devel:true*/

options: {
bundleOptions: {
browserifyOptions: {
standalone: 'SIP'

@@ -58,0 +58,0 @@ },

@@ -5,3 +5,3 @@ {

"description": "A simple, intuitive, and powerful JavaScript signaling library",
"version": "0.7.2",
"version": "0.7.3",
"main": "src/index.js",

@@ -33,3 +33,3 @@ "browser": {

"grunt": "~0.4.0",
"grunt-browserify": "^2.1.0",
"grunt-browserify": "^4.0.1",
"grunt-cli": "~0.1.6",

@@ -50,2 +50,3 @@ "grunt-contrib-copy": "^0.5.0",

"repl": "beefy test/repl.js --open",
"build": "grunt build",
"prepublish": "cd src/Grammar && mkdir -p dist && pegjs --extra-options-file peg.json src/Grammar.pegjs dist/Grammar.js",

@@ -52,0 +53,0 @@ "test": "grunt travis --verbose"

@@ -22,2 +22,3 @@ # How To version release SIP.js

* add new dist files (git add -f if it complains)
* commit
* test npm:

@@ -24,0 +25,0 @@

@@ -11,2 +11,6 @@ "use strict";

module.exports = function (SIP) {
//keep to quiet jshint, and remain consistent with other files
SIP = SIP;
var Hacks = {

@@ -84,15 +88,2 @@ AllBrowsers: {

},
hasIncompatibleCLineWithSomeSIPEndpoints: function(sdp) {
/*
* Firefox appears to be following https://tools.ietf.org/html/rfc5245#section-9.1.1.1
* and using a c line IP address of 0.0.0.0. This is completely valid, however it is
* causing some endpoints (such as FreeSWITCH) to interpret the SDP as being on hold
* https://freeswitch.org/jira/browse/FS-6955. To get around this issue we pull the
* replace the c line with 1.1.1.1 which SIP clients do not interpret as hold.
* This makes the other endpoint believe that the call is not on hold and audio flows
* because ICE determines the media pathway (not the c line).
*/
return sdp.replace(/(0\.0\.0\.0)/gmi, SIP.Utils.getRandomTestNetIP());
}
},

@@ -99,0 +90,0 @@

@@ -29,2 +29,3 @@ "use strict";

params.to_uri = this.to_uri;
params.to_displayName = ua.configuration.displayName;
params.call_id = this.call_id;

@@ -53,3 +54,3 @@ params.cseq = this.cseq;

extraHeaders.push('Contact: ' + this.contact + ';expires=' + this.expires);
extraHeaders.push('Allow: ' + SIP.Utils.getAllowedMethods(this.ua));
extraHeaders.push('Allow: ' + SIP.UA.C.ALLOWED_METHODS.toString());

@@ -56,0 +57,0 @@ // Save original extraHeaders to be used in .close

@@ -23,2 +23,29 @@ "use strict";

// Reply
function reply(status_code) {
var to,
response = SIP.Utils.buildStatusLine(status_code),
vias = message.getHeaders('via'),
length = vias.length,
idx = 0;
for(idx; idx < length; idx++) {
response += "Via: " + vias[idx] + "\r\n";
}
to = message.getHeader('To');
if(!message.to_tag) {
to += ';tag=' + SIP.Utils.newTag();
}
response += "To: " + to + "\r\n";
response += "From: " + message.getHeader('From') + "\r\n";
response += "Call-ID: " + message.call_id + "\r\n";
response += "CSeq: " + message.cseq + " " + message.method + "\r\n";
response += "\r\n";
transport.send(response);
}
/*

@@ -149,29 +176,2 @@ * Sanity Check for incoming Messages

// Reply
function reply(status_code) {
var to,
response = SIP.Utils.buildStatusLine(status_code),
vias = message.getHeaders('via'),
length = vias.length,
idx = 0;
for(idx; idx < length; idx++) {
response += "Via: " + vias[idx] + "\r\n";
}
to = message.getHeader('To');
if(!message.to_tag) {
to += ';tag=' + SIP.Utils.newTag();
}
response += "To: " + to + "\r\n";
response += "From: " + message.getHeader('From') + "\r\n";
response += "Call-ID: " + message.call_id + "\r\n";
response += "CSeq: " + message.cseq + " " + message.method + "\r\n";
response += "\r\n";
transport.send(response);
}
requests.push(rfc3261_8_2_2_1);

@@ -178,0 +178,0 @@ requests.push(rfc3261_16_3_4);

@@ -44,3 +44,3 @@ "use strict";

options.extraHeaders.push('Contact: '+ this.contact);
options.extraHeaders.push('Allow: '+ SIP.Utils.getAllowedMethods(ua));
options.extraHeaders.push('Allow: '+ SIP.UA.C.ALLOWED_METHODS.toString());

@@ -60,2 +60,10 @@ SIP.Utils.augment(this, SIP.ClientContext, [ua, SIP.C.SUBSCRIBE, target, options]);

//these states point to an existing subscription, no subscribe is necessary
if (this.state === 'active') {
this.refresh();
return this;
} else if (this.state === 'notify_wait') {
return this;
}
SIP.Timers.clearTimeout(this.timers.sub_duration);

@@ -87,3 +95,4 @@ SIP.Timers.clearTimeout(this.timers.N);

if (this.errorCodes.indexOf(response.status_code) !== -1) {
if ((this.state === 'notify_wait' && response.status_code >= 300) ||
(this.state !== 'notify_wait' && this.errorCodes.indexOf(response.status_code) !== -1)) {
this.failed(response, null);

@@ -126,14 +135,15 @@ } else if (/^2[0-9]{2}$/.test(response.status_code)){

extraHeaders.push('Contact: '+ this.contact);
extraHeaders.push('Allow: '+ SIP.Utils.getAllowedMethods(this.ua));
extraHeaders.push('Allow: '+ SIP.UA.C.ALLOWED_METHODS.toString());
this.request = new SIP.OutgoingRequest(this.method, this.request.to.uri.toString(), this.ua, null, extraHeaders);
//MAYBE, may want to see state
//makes sure expires isn't set, and other typical resubscribe behavior
this.receiveResponse = function(){};
this.dialog.sendRequest(this, this.method, {
extraHeaders: extraHeaders,
body: this.body
});
SIP.Timers.clearTimeout(this.timers.sub_duration);
SIP.Timers.clearTimeout(this.timers.N);
this.timers.N = SIP.Timers.setTimeout(sub.timer_fire.bind(sub), SIP.Timers.TIMER_N);
this.send();
},

@@ -146,5 +156,8 @@

if (this.state === 'terminated') {
this.close();
this.terminateDialog();
SIP.Timers.clearTimeout(this.timers.N);
SIP.Timers.clearTimeout(this.timers.sub_duration);
delete this.ua.subscriptions[this.id];
} else if (this.state === 'pending' || this.state === 'notify_wait') {
this.state = 'terminated';
this.close();

@@ -160,11 +173,5 @@ } else {

close: function() {
if(this.state !== 'terminated') {
if(this.state !== 'notify_wait' && this.state !== 'terminated') {
this.unsubscribe();
}
this.terminateDialog();
SIP.Timers.clearTimeout(this.timers.N);
SIP.Timers.clearTimeout(this.timers.sub_duration);
delete this.ua.subscriptions[this.id];
},

@@ -231,2 +238,15 @@

// if we've set state to terminated, no further processing should take place
// and we are only interested in cleaning up after the appropriate NOTIFY
if (this.state === 'terminated') {
if (sub_state.state === 'terminated') {
this.terminateDialog();
SIP.Timers.clearTimeout(this.timers.N);
SIP.Timers.clearTimeout(this.timers.sub_duration);
delete this.ua.subscriptions[this.id];
}
return;
}
switch (sub_state.state) {

@@ -277,2 +297,6 @@ case 'active':

onDialogError: function(response) {
this.failed(response, SIP.C.causes.DIALOG_ERROR);
},
/**

@@ -279,0 +303,0 @@ * @private

@@ -21,2 +21,12 @@ "use strict";

/**
* Compute an amount of time in seconds to wait before sending another
* keep-alive.
* @returns {Number}
*/
function computeKeepAliveTimeout(upperBound) {
var lowerBound = upperBound * 0.8;
return 1000 * (Math.random() * (upperBound - lowerBound) + lowerBound);
}
Transport = function(ua, server) {

@@ -360,14 +370,4 @@

/**
* Compute an amount of time in seconds to wait before sending another
* keep-alive.
* @returns {Number}
*/
function computeKeepAliveTimeout(upperBound) {
var lowerBound = upperBound * 0.8;
return 1000 * (Math.random() * (upperBound - lowerBound) + lowerBound);
}
Transport.C = C;
return Transport;
};

@@ -25,14 +25,7 @@ "use strict";

/* UA events and corresponding SIP Methods.
* Dynamically added to 'Allow' header field if the
* corresponding event handler is set.
*/
EVENT_METHODS: {
'invite': 'INVITE',
'message': 'MESSAGE'
},
ALLOWED_METHODS: [
'ACK',
'CANCEL',
'INVITE',
'MESSAGE',
'BYE',

@@ -586,3 +579,2 @@ 'OPTIONS',

replacedDialog,
methodLower = request.method.toLowerCase(),
self = this;

@@ -625,12 +617,6 @@

request.reply(200, null, [
'Allow: '+ SIP.Utils.getAllowedMethods(this),
'Allow: '+ SIP.UA.C.ALLOWED_METHODS.toString(),
'Accept: '+ C.ACCEPTED_BODY_TYPES
]);
} else if (method === SIP.C.MESSAGE) {
if (!this.listeners(methodLower).length) {
// UA is not listening for this. Reject immediately.
new SIP.Transactions.NonInviteServerTransaction(request, this);
request.reply(405, null, ['Allow: '+ SIP.Utils.getAllowedMethods(this)]);
return;
}
message = new SIP.ServerContext(this, request);

@@ -637,0 +623,0 @@ message.body = request.body;

@@ -284,15 +284,2 @@ "use strict";

getAllowedMethods: function(ua) {
var event,
allowed = SIP.UA.C.ALLOWED_METHODS.toString();
for (event in SIP.UA.C.EVENT_METHODS) {
if (ua.listeners(event).length) {
allowed += ','+ SIP.UA.C.EVENT_METHODS[event];
}
}
return allowed;
},
// MD5 (Message-Digest Algorithm) http://www.webtoolkit.info

@@ -299,0 +286,0 @@ calculateMD5: function(string) {

@@ -28,146 +28,7 @@ "use strict";

// old init() from here on
var idx, jdx, length, server,
self = this,
servers = [],
stunServers = options.stunServers || null,
turnServers = options.turnServers || null,
config = this.session.ua.configuration;
var servers = this.prepareIceServers(options.stunServers, options.turnServers);
this.RTCConstraints = options.RTCConstraints || {};
if (!stunServers) {
stunServers = config.stunServers;
}
this.initPeerConnection(servers, this.RTCConstraints);
if(!turnServers) {
turnServers = config.turnServers;
}
/* Change 'url' to 'urls' whenever this issue is solved:
* https://code.google.com/p/webrtc/issues/detail?id=2096
*/
[].concat(stunServers).forEach(function (server) {
servers.push({'url': server});
});
length = turnServers.length;
for (idx = 0; idx < length; idx++) {
server = turnServers[idx];
for (jdx = 0; jdx < server.urls.length; jdx++) {
servers.push({
'url': server.urls[jdx],
'username': server.username,
'credential': server.password
});
}
}
this.onIceCompleted = SIP.Utils.defer();
this.onIceCompleted.promise.then(function(pc) {
self.emit('iceGatheringComplete', pc);
if (self.iceCheckingTimer) {
SIP.Timers.clearTimeout(self.iceCheckingTimer);
self.iceCheckingTimer = null;
}
});
this.peerConnection = new SIP.WebRTC.RTCPeerConnection({'iceServers': servers}, this.RTCConstraints);
// Firefox (35.0.1) sometimes throws on calls to peerConnection.getRemoteStreams
// even if peerConnection.onaddstream was just called. In order to make
// MediaHandler.prototype.getRemoteStreams work, keep track of them manually
this._remoteStreams = [];
this.peerConnection.onaddstream = function(e) {
self.logger.log('stream added: '+ e.stream.id);
self._remoteStreams.push(e.stream);
self.render();
self.emit('addStream', e);
};
this.peerConnection.onremovestream = function(e) {
self.logger.log('stream removed: '+ e.stream.id);
};
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) {
self.emit('iceCandidate', e);
if (e.candidate) {
self.logger.log('ICE candidate received: '+ (e.candidate.candidate === null ? null : e.candidate.candidate.trim()));
self.startIceCheckingTimer();
} else {
self.onIceCompleted.resolve(this);
}
};
this.peerConnection.onicegatheringstatechange = function () {
self.logger.log('RTCIceGatheringState changed: ' + this.iceGatheringState);
if (this.iceGatheringState === 'gathering') {
self.emit('iceGathering', this);
}
if (this.iceGatheringState === 'complete') {
self.onIceCompleted.resolve(this);
}
};
this.peerConnection.oniceconnectionstatechange = function() { //need e for commented out case
var stateEvent;
if (this.iceConnectionState === 'checking') {
self.startIceCheckingTimer();
}
switch (this.iceConnectionState) {
case 'new':
stateEvent = 'iceConnection';
break;
case 'checking':
stateEvent = 'iceConnectionChecking';
break;
case 'connected':
stateEvent = 'iceConnectionConnected';
break;
case 'completed':
stateEvent = 'iceConnectionCompleted';
break;
case 'failed':
stateEvent = 'iceConnectionFailed';
break;
case 'disconnected':
stateEvent = 'iceConnectionDisconnected';
break;
case 'closed':
stateEvent = 'iceConnectionClosed';
break;
default:
self.logger.warn('Unknown iceConnection state:', this.iceConnectionState);
return;
}
self.emit(stateEvent, this);
//Bria state changes are always connected -> disconnected -> connected on accept, so session gets terminated
//normal calls switch from failed to connected in some cases, so checking for failed and terminated
/*if (this.iceConnectionState === 'failed') {
self.session.terminate({
cause: SIP.C.causes.RTP_TIMEOUT,
status_code: 200,
reason_phrase: SIP.C.causes.RTP_TIMEOUT
});
} else if (e.currentTarget.iceGatheringState === 'complete' && this.iceConnectionState !== 'closed') {
self.onIceCompleted(this);
}*/
};
this.peerConnection.onstatechange = function() {
self.logger.log('PeerConnection state changed to "'+ this.readyState +'"');
};
function selfEmit(mh, event) {

@@ -320,2 +181,18 @@ if (mh.mediaStreamManager.on) {

updateIceServers: {writeable:true, value: function (options) {
var servers = this.prepareIceServers(options.stunServers, options.turnServers);
this.RTCConstraints = options.RTCConstraints || this.RTCConstraints;
this.initPeerConnection(servers, this.RTCConstraints);
/* once updateIce is implemented correctly, this is better than above
//no op if browser does not support this
if (!this.peerConnection.updateIce) {
return;
}
this.peerConnection.updateIce({'iceServers': servers}, this.RTCConstraints);
*/
}},
// Functions the session can use, but only because it's convenient for the application

@@ -464,2 +341,157 @@ isMuted: {writable: true, value: function isMuted () {

prepareIceServers: {writable: true, value: function prepareIceServers (stunServers, turnServers) {
var idx, jdx, length, server,
servers = [],
config = this.session.ua.configuration;
stunServers = stunServers || null;
turnServers = turnServers || null;
if (!stunServers) {
stunServers = config.stunServers;
}
if(!turnServers) {
turnServers = config.turnServers;
}
/* Change 'url' to 'urls' whenever this issue is solved:
* https://code.google.com/p/webrtc/issues/detail?id=2096
*/
[].concat(stunServers).forEach(function (server) {
servers.push({'url': server});
});
length = turnServers.length;
for (idx = 0; idx < length; idx++) {
server = turnServers[idx];
for (jdx = 0; jdx < server.urls.length; jdx++) {
servers.push({
'url': server.urls[jdx],
'username': server.username,
'credential': server.password
});
}
}
return servers;
}},
initPeerConnection: {writable: true, value: function initPeerConnection(servers, RTCConstraints) {
var self = this,
config = this.session.ua.configuration;
this.onIceCompleted = SIP.Utils.defer();
this.onIceCompleted.promise.then(function(pc) {
self.emit('iceGatheringComplete', pc);
if (self.iceCheckingTimer) {
SIP.Timers.clearTimeout(self.iceCheckingTimer);
self.iceCheckingTimer = null;
}
});
if (this.peerConnection) {
this.peerConnection.close();
}
this.peerConnection = new SIP.WebRTC.RTCPeerConnection({'iceServers': servers}, RTCConstraints);
// Firefox (35.0.1) sometimes throws on calls to peerConnection.getRemoteStreams
// even if peerConnection.onaddstream was just called. In order to make
// MediaHandler.prototype.getRemoteStreams work, keep track of them manually
this._remoteStreams = [];
this.peerConnection.onaddstream = function(e) {
self.logger.log('stream added: '+ e.stream.id);
self._remoteStreams.push(e.stream);
self.render();
self.emit('addStream', e);
};
this.peerConnection.onremovestream = function(e) {
self.logger.log('stream removed: '+ e.stream.id);
};
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) {
self.emit('iceCandidate', e);
if (e.candidate) {
self.logger.log('ICE candidate received: '+ (e.candidate.candidate === null ? null : e.candidate.candidate.trim()));
self.startIceCheckingTimer();
} else {
self.onIceCompleted.resolve(this);
}
};
this.peerConnection.onicegatheringstatechange = function () {
self.logger.log('RTCIceGatheringState changed: ' + this.iceGatheringState);
if (this.iceGatheringState === 'gathering') {
self.emit('iceGathering', this);
}
if (this.iceGatheringState === 'complete') {
self.onIceCompleted.resolve(this);
}
};
this.peerConnection.oniceconnectionstatechange = function() { //need e for commented out case
var stateEvent;
if (this.iceConnectionState === 'checking') {
self.startIceCheckingTimer();
}
switch (this.iceConnectionState) {
case 'new':
stateEvent = 'iceConnection';
break;
case 'checking':
stateEvent = 'iceConnectionChecking';
break;
case 'connected':
stateEvent = 'iceConnectionConnected';
break;
case 'completed':
stateEvent = 'iceConnectionCompleted';
break;
case 'failed':
stateEvent = 'iceConnectionFailed';
break;
case 'disconnected':
stateEvent = 'iceConnectionDisconnected';
break;
case 'closed':
stateEvent = 'iceConnectionClosed';
break;
default:
self.logger.warn('Unknown iceConnection state:', this.iceConnectionState);
return;
}
self.emit(stateEvent, this);
//Bria state changes are always connected -> disconnected -> connected on accept, so session gets terminated
//normal calls switch from failed to connected in some cases, so checking for failed and terminated
/*if (this.iceConnectionState === 'failed') {
self.session.terminate({
cause: SIP.C.causes.RTP_TIMEOUT,
status_code: 200,
reason_phrase: SIP.C.causes.RTP_TIMEOUT
});
} else if (e.currentTarget.iceGatheringState === 'complete' && this.iceConnectionState !== 'closed') {
self.onIceCompleted(this);
}*/
};
this.peerConnection.onstatechange = function() {
self.logger.log('PeerConnection state changed to "'+ this.readyState +'"');
};
}},
createOfferOrAnswer: {writable: true, value: function createOfferOrAnswer (constraints) {

@@ -489,3 +521,2 @@ var self = this;

sdp = SIP.Hacks.AllBrowsers.unmaskDtls(sdp);
sdp = SIP.Hacks.Firefox.hasIncompatibleCLineWithSomeSIPEndpoints(sdp);

@@ -492,0 +523,0 @@ var sdpWrapper = {

@@ -52,11 +52,2 @@ "use strict";

function attachAndPlay (elements, stream, index) {
if (typeof elements === 'function') {
elements = elements();
}
var element = elements[index % elements.length];
(environment.attachMediaStream || attachMediaStream)(element, stream);
ensureMediaPlaying(element);
}
function attachMediaStream(element, stream) {

@@ -87,2 +78,11 @@ if (typeof element.src !== 'undefined') {

function attachAndPlay (elements, stream, index) {
if (typeof elements === 'function') {
elements = elements();
}
var element = elements[index % elements.length];
(environment.attachMediaStream || attachMediaStream)(element, stream);
ensureMediaPlaying(element);
}
// [].concat "casts" `elements` into an array

@@ -134,9 +134,14 @@ // so forEach works even if `elements` was a single element

deferred.resolve(
SIP.WebRTC.getUserMedia(constraints)
.then(
emitThenCall.bind(this, 'userMedia', saveSuccess.bind(null, false)),
emitThenCall.bind(this, 'userMediaFailed', function(e){throw e;})
)
);
if (constraints.audio || constraints.video) {
deferred.resolve(
SIP.WebRTC.getUserMedia(constraints)
.then(
emitThenCall.bind(this, 'userMedia', saveSuccess.bind(null, false)),
emitThenCall.bind(this, 'userMediaFailed', function(e){throw e;})
)
);
} else {
// Local streams were explicitly excluded.
deferred.resolve([]);
}
}.bind(this), 0);

@@ -143,0 +148,0 @@

@@ -112,2 +112,28 @@ describe('MediaStreamManager', function () {

});
it('does not require local streams', function(done) {
var success, failure, onUM, onUMF;
success = jasmine.createSpy('success');
failure = jasmine.createSpy('failure');
onUM = jasmine.createSpy('userMediaFailed');
onUMF = jasmine.createSpy('userMediaFailed');
mediaStreamManager.on('userMedia', onUM);
mediaStreamManager.on('userMediaFailed', onUMF);
mediaStreamManager.acquire({
constraints: {
audio: false,
video: false
}
}).then(success, failure)
.then(function () {
expect(onUM).not.toHaveBeenCalled();
expect(onUMF).not.toHaveBeenCalled();
expect(success).toHaveBeenCalledWith([]);
expect(failure).not.toHaveBeenCalled();
done();
});
});
});

@@ -114,0 +140,0 @@

@@ -242,3 +242,3 @@ describe('Dialogs', function() {

beforeEach(function() {
request = new SIP.OutgoingRequest('INVITE', 'bob@example.com', owner.ua, {from: 'abcdefg'}, ['Contact: ' + owner.contact, 'Allow: ' + SIP.Utils.getAllowedMethods(owner.ua)]);
request = new SIP.OutgoingRequest('INVITE', 'bob@example.com', owner.ua, {from: 'abcdefg'}, ['Contact: ' + owner.contact, 'Allow: ' + SIP.UA.C.ALLOWED_METHODS.toString()]);

@@ -348,3 +348,3 @@ request.server_transaction = {on: jasmine.createSpy('on')};

beforeEach(function() {
request = new SIP.OutgoingRequest('INVITE', 'bob@example.com', owner.ua, {from: 'abcdefg'}, ['Contact: ' + owner.contact, 'Allow: ' + SIP.Utils.getAllowedMethods(owner.ua)]);
request = new SIP.OutgoingRequest('INVITE', 'bob@example.com', owner.ua, {from: 'abcdefg'}, ['Contact: ' + owner.contact, 'Allow: ' + SIP.UA.C.ALLOWED_METHODS.toString()]);

@@ -351,0 +351,0 @@ spyOn(owner, 'receiveRequest');

@@ -239,2 +239,8 @@ describe('Subscription', function() {

describe('.unsubscribe', function() {
beforeEach(function() {
Subscription.dialog = {
sendRequest: function() {}
};
});
it('sets the state to terminated', function() {

@@ -246,6 +252,7 @@ Subscription.unsubscribe();

it('creates a new request with an Expires header of 0', function() {
it('sends a request using the same dialog as the subscription', function() {
spyOn(Subscription.dialog, 'sendRequest');
Subscription.unsubscribe();
expect(Subscription.request.getHeader('Expires')).toBe('0');
expect(Subscription.dialog.sendRequest).toHaveBeenCalled();
});

@@ -271,15 +278,16 @@

});
});
it('calls send', function() {
spyOn(Subscription, 'send');
describe('.timer_fire', function() {
it('calls terminateDialog if state is terminated', function() {
spyOn(Subscription, 'terminateDialog');
Subscription.state = 'terminated';
Subscription.unsubscribe();
Subscription.timer_fire();
expect(Subscription.send).toHaveBeenCalled();
expect(Subscription.terminateDialog).toHaveBeenCalled();
});
});
describe('.timer_fire', function() {
it('calls close if state is terminated', function() {
spyOn(Subscription, 'close');
it('calls clearTimeout on both timers if state is terminated', function() {
spyOn(SIP.Timers, 'clearTimeout');
Subscription.state = 'terminated';

@@ -289,6 +297,17 @@

expect(Subscription.close).toHaveBeenCalled();
expect(SIP.Timers.clearTimeout.calls.count()).toBe(2);
});
it('switches the state to terminated and calls close if the state is pending or notify_wait', function() {
it('deletes the subscription from the UA if state is terminated', function() {
Subscription.id = 'fake';
ua.subscriptions[Subscription.id] = Subscription;
Subscription.state = 'terminated';
Subscription.timer_fire();
expect(ua.subscriptions[Subscription.id]).toBeUndefined();
});
it('calls close if the state is pending or notify_wait', function() {
spyOn(Subscription, 'close');

@@ -300,3 +319,2 @@ Subscription.state = 'pending';

expect(Subscription.close).toHaveBeenCalled();
expect(Subscription.state).toBe('terminated');

@@ -309,3 +327,2 @@ Subscription.close.calls.reset();

expect(Subscription.close).toHaveBeenCalled();
expect(Subscription.state).toBe('terminated');
});

@@ -331,10 +348,12 @@

describe('.close', function() {
it('calls unsubscribe if the state is not terminated', function() {
Subscription.state = 'terminated';
it('calls unsubscribe if the state is not terminated or notify_wait', function() {
spyOn(Subscription, 'unsubscribe');
Subscription.state = 'terminated';
Subscription.close();
Subscription.state = 'notify_wait';
Subscription.close();
Subscription.state = 'pending';
Subscription.close();

@@ -344,28 +363,2 @@

});
it('calls terminateDialog', function() {
spyOn(Subscription, 'terminateDialog');
Subscription.close();
expect(Subscription.terminateDialog).toHaveBeenCalled();
});
it('calls clearTimeout on both timers', function() {
spyOn(SIP.Timers, 'clearTimeout');
Subscription.state = 'terminated'; //to ensure number of calls to clearTimeout
Subscription.close();
expect(SIP.Timers.clearTimeout.calls.count()).toBe(2);
});
it('deletes the subscription from ua.subscriptions', function() {
Subscription.id = 'fake';
ua.subscriptions[Subscription.id] = Subscription;
Subscription.close();
expect(ua.subscriptions[Subscription.id]).toBeUndefined();
});
});

@@ -563,3 +556,3 @@

it('if sub_state.state is terminated with reason deactivated or timeout, subscribe will be called without close (always a log)', function() {
it('if sub_state.state is terminated with reason deactivated or timeout and state is not terminated, subscribe will be called without close (always a log)', function() {
request.setHeader('Subscription-State', 'terminated;expires=3600;reason=deactivated');

@@ -570,2 +563,4 @@ spyOn(Subscription, 'subscribe');

Subscription.state = 'pending';
Subscription.receiveRequest(request);

@@ -585,2 +580,17 @@

it('if sub_state.state is terminated with reason deactivated or timeout and state is not terminated, the Subscription will be gracefully shut down', function() {
spyOn(Subscription, 'terminateDialog');
spyOn(SIP.Timers, 'clearTimeout');
Subscription.id = 'fake';
ua.subscriptions[Subscription.id] = Subscription;
Subscription.state = 'terminated';
Subscription.timer_fire();
expect(SIP.Timers.clearTimeout.calls.count()).toBe(2);
expect(Subscription.terminateDialog).toHaveBeenCalled();
expect(ua.subscriptions[Subscription.id]).toBeUndefined();
});
it('if sub_state.state is terminated with reason probation or giveup, subscribe will be called or the sub_duration timer will be set if retry-after is present, both without close', function() {

@@ -632,2 +642,16 @@ request.setHeader('Subscription-State', 'terminated;retry-after=3600;reason=probation');

describe('.onDialogError', function() {
it('does not throw an exception', function() {
Subscription.dialog = {
sendRequest: function() {}
};
function errant () {
Subscription.onDialogError();
}
expect(errant).not.toThrow();
});
});
describe('.matchEvent', function() {

@@ -634,0 +658,0 @@ var request;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc