diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index e45259d5d..4712a0e52 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -223,17 +223,24 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras key: privateKey.getIdKey() }; self.network.cleanUp(); + + // This is a hack to reconize if the connection was rejected or the peer wasn't there. + var connectedOnce = false; + self.network.on('connected', function(sender, data) { + connectedOnce = true; + }); + self.network.on('onlyYou', function(sender, data) { + return cb(connectedOnce ? 'walletFull' : 'joinError'); + }); + + self.network.on('serverError', function() { + console.log('[WalletFactory.js.236]'); //TODO + return cb('joinError'); + }); + self.network.start(opts, function() { self.network.connectTo(s.pubKey); - // This is a hack to reconize if the connection was rejected or the peer wasn't there. - var connectedOnce = false; - self.network.on('connected', function(sender, data) { - connectedOnce = true; - }); - self.network.on('onlyYou', function(sender, data) { - return cb(connectedOnce ? 'walletFull' : 'joinError'); - }); self.network.on('data', function(sender, data) { if (data.type === 'walletId') { if (data.networkName !== self.networkName) { diff --git a/js/models/network/WebRTC.js b/js/models/network/WebRTC.js index f2cb87e2d..91d4092d7 100644 --- a/js/models/network/WebRTC.js +++ b/js/models/network/WebRTC.js @@ -61,6 +61,7 @@ Network.prototype.cleanUp = function() { } this.closing = 0; this.tries = 0; + this.removeAllListeners(); }; Network.parent = EventEmitter; @@ -259,35 +260,38 @@ Network.prototype._setupConnectionHandlers = function(dataConn, toCopayerId) { }); }; -Network.prototype._setupPeerHandlers = function(openCallback) { - var self = this; - var p = this.peer; - - p.on('open', function() { - self.connectedPeers = [self.peerId]; - self.copayerForPeer[self.peerId] = self.copayerId; - return openCallback(); - }); - - p.on('error', function(err) { - console.log('RECV ERROR: ', err); //TODO - if (!err.message.match(/Could\snot\sconnect\sto peer/)) { - self.criticalError = err.message; - } - }); - - p.on('connection', function(dataConn) { - if (self.connectedPeers.length >= self.maxPeers) { - dataConn.on('open', function() { - dataConn.close(); - }); - } else { - self._setInboundPeerAuth(dataConn.peer, false); - self._setupConnectionHandlers(dataConn); - } - }); +Network.prototype._handlePeerOpen = function(openCallback) { + this.connectedPeers = [this.peerId]; + this.copayerForPeer[this.peerId] = this.copayerId; + return openCallback(); }; +Network.prototype._handlePeerError = function(err) { + console.log('RECV ERROR: ', err); + if (err.message.match(/Could\snot\sconnect\sto peer/)) { + this._checkAnyPeer(); + } else { + this.criticalError = err.message; + } +}; + +Network.prototype._handlePeerConnection = function(dataConn) { + if (this.connectedPeers.length >= self.maxPeers) { + dataConn.on('open', function() { + dataConn.close(); + }); + } else { + this._setInboundPeerAuth(dataConn.peer, false); + this._setupConnectionHandlers(dataConn); + } +}; + +Network.prototype._setupPeerHandlers = function(openCallback) { + var p = this.peer; + p.on('open', this._handlePeerOpen.bind(this, openCallback)); + p.on('error', this._handlePeerError.bind(this)); + p.on('connection', this._handlePeerConnection.bind(this)); +}; Network.prototype._addCopayerMap = function(peerId, copayerId) { if (!this.copayerForPeer[peerId]) { @@ -297,7 +301,6 @@ Network.prototype._addCopayerMap = function(peerId, copayerId) { } }; - Network.prototype._setInboundPeerAuth = function(peerId, isAuthenticated) { this.isInboundPeerAuth[peerId] = isAuthenticated; }; @@ -349,12 +352,14 @@ Network.prototype.start = function(opts, openCallback) { self.peer = new Peer(self.peerId, self.opts); self.started = true; self._setupPeerHandlers(openCallback); + setTimeout(setupPeer, 3000); // Schedule retry return; } if (self.criticalError && self.criticalError.match(/taken/)) { self.criticalError = ' Looks like you are already connected to this wallet please close all other Copay Wallets ' } + self.emit('serverError', self.criticalError); self.cleanUp(); } diff --git a/test/test.network.WebRTC.js b/test/test.network.WebRTC.js index 451773e37..1acbb32c5 100644 --- a/test/test.network.WebRTC.js +++ b/test/test.network.WebRTC.js @@ -28,7 +28,6 @@ describe('Network / WebRTC', function() { n.cleanUp.calledOnce.should.equal(true); WebRTC.prototype.cleanUp = save; }); - }); describe('#cleanUp', function() { @@ -44,8 +43,79 @@ describe('Network / WebRTC', function() { expect(n.privkey).to.equal(null); }); + it('should remove handlers', function() { + var n = new WebRTC(); + var save = WebRTC.prototype.removeAllListeners; + var spy = WebRTC.prototype.removeAllListeners = sinon.spy(); + n.cleanUp(); + spy.calledOnce.should.equal(true); + WebRTC.prototype.removeAllListeners = save; + }); }); + + describe('#_setupPeerHandlers', function() { + var n = new WebRTC(); + n.peer = {}; + var spy = n.peer.on = sinon.spy(); + it('should setup handlers', function() { + n._setupPeerHandlers(); + spy.calledWith('connection').should.equal(true); + spy.calledWith('open').should.equal(true); + spy.calledWith('error').should.equal(true); + }); + }); + + describe('#_handlePeerOpen', function() { + var n = new WebRTC(); + it('should call openCallback handler', function(done) { + n.peerId = 1; + n.copayerId = 2; + n._handlePeerOpen(function() { + n.connectedPeers.should.deep.equal([1]); + n.copayerForPeer.should.deep.equal({ + 1: 2 + }); + done(); + }); + }); + }); + + describe('#_handlePeerError', function() { + var log = console.log; + var n = new WebRTC(); + it('should call _checkAnyPeer on could not connect error', function() { + var save = n._checkAnyPeer; + var spy = n._checkAnyPeer = sinon.spy(); + var logSpy = console.log = sinon.spy(); + n._handlePeerError({ + message: 'Could not connect to peer xxx' + }); + console.log = log; + spy.called.should.equal(true); + logSpy.called.should.equal(true); + n._checkAnyPeer = save; + }); + + it('should call not call _checkAnyPeer other error', function() { + var save = n._checkAnyPeer; + var spy = n._checkAnyPeer = sinon.spy(); + var otherMessage = 'Could connect to peer xxx'; + var logSpy = console.log = sinon.spy(); + n._handlePeerError({ + message: otherMessage, + }); + console.log = log; + spy.called.should.equal(false); + n.criticalError.should.equal(otherMessage); + logSpy.called.should.equal(true); + n._checkAnyPeer = save; + }); + + }); + + + describe('#_encode', function() { it('should encode data successfully', function() {