describe('NetworkStatusView', function() { describe('getNetworkStatus', function() { var networkStatusView; var socketStatus = WebSocket.OPEN; var oldGetSocketStatus; /* BEGIN stubbing globals */ before(function() { oldGetSocketStatus = window.getSocketStatus; window.getSocketStatus = function() { return socketStatus; }; }); after(function() { window.getSocketStatus = oldGetSocketStatus; // It turns out that continued calls to window.getSocketStatus happen // because we host NetworkStatusView in three mock interfaces, and the view // checks every N seconds. That results in infinite errors unless there is // something to call. window.getSocketStatus = function() { return WebSocket.OPEN; }; }); /* END stubbing globals */ beforeEach(function() { networkStatusView = new Whisper.NetworkStatusView(); $('.network-status-container').append(networkStatusView.el); }); afterEach(function() { // prevents huge number of errors on console after running tests clearInterval(networkStatusView.renderIntervalHandle); networkStatusView = null; }); describe('initialization', function() { it('should have an empty interval', function() { assert.equal( networkStatusView.socketReconnectWaitDuration.asSeconds(), 0 ); }); }); describe('network status with no connection', function() { beforeEach(function() { networkStatusView.navigatorOnLine = function() { return false; }; }); it('should be interrupted', function() { networkStatusView.update(); var status = networkStatusView.getNetworkStatus(); assert(status.hasInterruption); assert.equal(status.instructions, 'Check your network connection.'); }); it('should display an offline message', function() { networkStatusView.update(); assert.match(networkStatusView.$el.text(), /Offline/); }); it('should override socket status', function() { _([ WebSocket.CONNECTING, WebSocket.OPEN, WebSocket.CLOSING, WebSocket.CLOSED, ]).map(function(socketStatusVal) { socketStatus = socketStatusVal; networkStatusView.update(); assert.match(networkStatusView.$el.text(), /Offline/); }); }); it('should override registration status', function() { Whisper.Registration.remove(); networkStatusView.update(); assert.match(networkStatusView.$el.text(), /Offline/); }); }); describe('network status when registration is not done', function() { beforeEach(function() { Whisper.Registration.remove(); }); it('should display an unlinked message', function() { networkStatusView.update(); assert.match(networkStatusView.$el.text(), /Relink/); }); it('should override socket status', function() { _([ WebSocket.CONNECTING, WebSocket.OPEN, WebSocket.CLOSING, WebSocket.CLOSED, ]).map(function(socketStatusVal) { socketStatus = socketStatusVal; networkStatusView.update(); assert.match(networkStatusView.$el.text(), /Relink/); }); }); }); describe('network status when registration is done', function() { beforeEach(function() { networkStatusView.navigatorOnLine = function() { return true; }; Whisper.Registration.markDone(); networkStatusView.update(); }); it('should not display an unlinked message', function() { networkStatusView.update(); assert.notMatch(networkStatusView.$el.text(), /Relink/); }); }); describe('network status when socket is connecting', function() { beforeEach(function() { Whisper.Registration.markDone(); socketStatus = WebSocket.CONNECTING; networkStatusView.update(); }); it('it should display a connecting string if connecting and not in the connecting grace period', function() { networkStatusView.withinConnectingGracePeriod = false; var status = networkStatusView.getNetworkStatus(); assert.match(networkStatusView.$el.text(), /Connecting/); }); it('it should not be interrupted if in connecting grace period', function() { assert(networkStatusView.withinConnectingGracePeriod); var status = networkStatusView.getNetworkStatus(); assert.match(networkStatusView.$el.text(), /Connecting/); assert(!status.hasInterruption); }); it('it should be interrupted if connecting grace period is over', function() { networkStatusView.withinConnectingGracePeriod = false; var status = networkStatusView.getNetworkStatus(); assert(status.hasInterruption); }); }); describe('network status when socket is open', function() { before(function() { socketStatus = WebSocket.OPEN; }); it('should not be interrupted', function() { var status = networkStatusView.getNetworkStatus(); assert(!status.hasInterruption); assert.match( networkStatusView.$el .find('.network-status-message') .text() .trim(), /^$/ ); }); }); describe('network status when socket is closed or closing', function() { _([WebSocket.CLOSED, WebSocket.CLOSING]).map(function(socketStatusVal) { it('should be interrupted', function() { socketStatus = socketStatusVal; networkStatusView.update(); var status = networkStatusView.getNetworkStatus(); assert(status.hasInterruption); }); }); }); describe('the socket reconnect interval', function() { beforeEach(function() { socketStatus = WebSocket.CLOSED; networkStatusView.setSocketReconnectInterval(61000); networkStatusView.update(); }); it('should format the message based on the socketReconnectWaitDuration property', function() { assert.equal( networkStatusView.socketReconnectWaitDuration.asSeconds(), 61 ); assert.match( networkStatusView.$('.network-status-message:last').text(), /Attempting reconnect/ ); }); it('should be reset by changing the socketStatus to CONNECTING', function() {}); }); }); });