mirror of
https://github.com/moparisthebest/mail
synced 2024-12-23 15:58:49 -05:00
416 lines
15 KiB
JavaScript
416 lines
15 KiB
JavaScript
'use strict';
|
|
|
|
var TCPSocket = require('tcp-socket'),
|
|
ImapClient = require('imap-client'),
|
|
SmtpClient = require('wo-smtpclient'),
|
|
ConnectionDoctor = require('../../src/js/util/connection-doctor'),
|
|
cfg = require('../../src/js/app-config').config;
|
|
|
|
describe('Connection Doctor', function() {
|
|
var doctor;
|
|
var socketStub, imapStub, smtpStub, credentials, workerPath;
|
|
|
|
beforeEach(function() {
|
|
//
|
|
// Stubs
|
|
//
|
|
|
|
// there is no socket shim for for this use case, use dummy object
|
|
socketStub = {
|
|
close: function() {
|
|
this.onclose();
|
|
}
|
|
};
|
|
|
|
workerPath = 'js/tcp-socket-tls-worker.min.js';
|
|
imapStub = sinon.createStubInstance(ImapClient);
|
|
smtpStub = sinon.createStubInstance(SmtpClient);
|
|
|
|
//
|
|
// Fixture
|
|
//
|
|
credentials = {
|
|
imap: {
|
|
host: 'asd',
|
|
port: 1234,
|
|
secure: true,
|
|
ca: 'cert'
|
|
},
|
|
smtp: {
|
|
host: 'qwe',
|
|
port: 5678,
|
|
secure: false,
|
|
ca: 'cert'
|
|
},
|
|
username: 'username',
|
|
password: 'password'
|
|
};
|
|
|
|
sinon.stub(TCPSocket, 'open').returns(socketStub); // convenience constructors suck
|
|
|
|
//
|
|
// Setup SUT
|
|
//
|
|
doctor = new ConnectionDoctor();
|
|
doctor.configure(credentials);
|
|
doctor._imap = imapStub;
|
|
doctor._smtp = smtpStub;
|
|
});
|
|
|
|
afterEach(function() {
|
|
TCPSocket.open.restore();
|
|
});
|
|
|
|
describe('#_checkOnline', function() {
|
|
it('should check if browser is online', function(done) {
|
|
doctor._checkOnline(function(error) {
|
|
if (navigator.onLine) {
|
|
expect(error).to.not.exist;
|
|
} else {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.OFFLINE);
|
|
}
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#_checkReachable', function() {
|
|
it('should be able to reach the host w/o cert', function(done) {
|
|
credentials.imap.ca = undefined;
|
|
|
|
doctor._checkReachable(credentials.imap, function(error) {
|
|
expect(error).to.not.exist;
|
|
expect(TCPSocket.open.calledOnce).to.be.true;
|
|
expect(TCPSocket.open.calledWith(credentials.imap.host, credentials.imap.port, {
|
|
binaryType: 'arraybuffer',
|
|
useSecureTransport: credentials.imap.secure,
|
|
ca: credentials.imap.ca,
|
|
tlsWorkerPath: workerPath
|
|
})).to.be.true;
|
|
|
|
done();
|
|
});
|
|
|
|
socketStub.oncert();
|
|
socketStub.onopen();
|
|
});
|
|
|
|
it('should catch Mozilla TCPSocket exception', function(done) {
|
|
// Mozilla forbids extensions to the TCPSocket object
|
|
Object.defineProperty(socketStub, 'oncert', {
|
|
set: function() {
|
|
throw 'Mozilla specific behavior';
|
|
}
|
|
});
|
|
|
|
doctor._checkReachable(credentials.imap, function(error) {
|
|
expect(error).to.not.exist;
|
|
expect(TCPSocket.open.calledOnce).to.be.true;
|
|
expect(TCPSocket.open.calledWith(credentials.imap.host, credentials.imap.port, {
|
|
binaryType: 'arraybuffer',
|
|
useSecureTransport: credentials.imap.secure,
|
|
ca: credentials.imap.ca,
|
|
tlsWorkerPath: workerPath
|
|
})).to.be.true;
|
|
|
|
done();
|
|
});
|
|
|
|
socketStub.onopen();
|
|
});
|
|
|
|
it('should fail w/ wrong cert', function(done) {
|
|
doctor._checkReachable(credentials.imap, function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.TLS_WRONG_CERT);
|
|
expect(TCPSocket.open.calledOnce).to.be.true;
|
|
expect(TCPSocket.open.calledWith(credentials.imap.host, credentials.imap.port, {
|
|
binaryType: 'arraybuffer',
|
|
useSecureTransport: credentials.imap.secure,
|
|
ca: credentials.imap.ca,
|
|
tlsWorkerPath: workerPath
|
|
})).to.be.true;
|
|
|
|
done();
|
|
});
|
|
|
|
socketStub.oncert();
|
|
socketStub.onerror();
|
|
socketStub.onclose();
|
|
});
|
|
|
|
it('should fail w/ host unreachable', function(done) {
|
|
doctor._checkReachable(credentials.imap, function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.HOST_UNREACHABLE);
|
|
expect(TCPSocket.open.calledOnce).to.be.true;
|
|
|
|
done();
|
|
});
|
|
|
|
socketStub.onerror({
|
|
data: new Error()
|
|
});
|
|
socketStub.onclose();
|
|
});
|
|
|
|
it('should fail w/ timeout', function(done) {
|
|
var origTimeout = cfg.connDocTimeout; // remember timeout from the config to reset it on done
|
|
cfg.connDocTimeout = 20; // set to 20ms for the test
|
|
|
|
doctor._checkReachable(credentials.imap, function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.HOST_TIMEOUT);
|
|
expect(TCPSocket.open.calledOnce).to.be.true;
|
|
cfg.connDocTimeout = origTimeout;
|
|
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#_checkImap', function() {
|
|
it('should perform IMAP login, list folders, logout', function(done) {
|
|
imapStub.login.yieldsAsync();
|
|
imapStub.listWellKnownFolders.yieldsAsync(null, {
|
|
Inbox: [{}]
|
|
});
|
|
imapStub.logout.yieldsAsync();
|
|
|
|
doctor._checkImap(function(error) {
|
|
expect(error).to.not.exist;
|
|
expect(imapStub.login.calledOnce).to.be.true;
|
|
expect(imapStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
expect(imapStub.logout.calledOnce).to.be.true;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail w/ generic error on logout', function(done) {
|
|
imapStub.login.yieldsAsync();
|
|
imapStub.listWellKnownFolders.yieldsAsync(null, {
|
|
Inbox: [{}]
|
|
});
|
|
|
|
doctor._checkImap(function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.GENERIC_ERROR);
|
|
expect(error.underlyingError).to.exist;
|
|
expect(imapStub.login.calledOnce).to.be.true;
|
|
expect(imapStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
expect(imapStub.logout.calledOnce).to.be.true;
|
|
|
|
done();
|
|
});
|
|
|
|
setTimeout(function() {
|
|
// this error is thrown while we're waiting for the logout
|
|
imapStub.onError(new Error());
|
|
}, 50);
|
|
});
|
|
|
|
it('should fail w/ generic error on inbox missing', function(done) {
|
|
imapStub.login.yieldsAsync();
|
|
imapStub.listWellKnownFolders.yieldsAsync(null, {
|
|
Inbox: []
|
|
});
|
|
|
|
doctor._checkImap(function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.NO_INBOX);
|
|
expect(imapStub.login.calledOnce).to.be.true;
|
|
expect(imapStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
expect(imapStub.logout.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail w/ generic error on listing folders fails', function(done) {
|
|
imapStub.login.yieldsAsync();
|
|
imapStub.listWellKnownFolders.yieldsAsync(new Error());
|
|
|
|
doctor._checkImap(function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.GENERIC_ERROR);
|
|
expect(error.underlyingError).to.exist;
|
|
expect(imapStub.login.calledOnce).to.be.true;
|
|
expect(imapStub.listWellKnownFolders.calledOnce).to.be.true;
|
|
expect(imapStub.logout.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail w/ auth rejected', function(done) {
|
|
doctor._checkImap(function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.AUTH_REJECTED);
|
|
expect(error.underlyingError).to.exist;
|
|
expect(imapStub.login.calledOnce).to.be.true;
|
|
expect(imapStub.listWellKnownFolders.called).to.be.false;
|
|
expect(imapStub.logout.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
|
|
setTimeout(function() {
|
|
// this error is thrown while we're waiting for the login
|
|
imapStub.onError(new Error());
|
|
}, 50);
|
|
});
|
|
});
|
|
|
|
describe('#_checkSmtp', function() {
|
|
it('should perform SMTP login, logout', function(done) {
|
|
doctor._checkSmtp(function(error) {
|
|
expect(error).to.not.exist;
|
|
expect(smtpStub.connect.calledOnce).to.be.true;
|
|
expect(smtpStub.quit.calledOnce).to.be.true;
|
|
|
|
done();
|
|
});
|
|
|
|
smtpStub.onidle();
|
|
smtpStub.onclose();
|
|
});
|
|
|
|
it('should fail w/ auth rejected', function(done) {
|
|
doctor._checkSmtp(function(error) {
|
|
expect(error).to.exist;
|
|
expect(error.code).to.equal(ConnectionDoctor.AUTH_REJECTED);
|
|
expect(error.underlyingError).to.exist;
|
|
expect(smtpStub.connect.calledOnce).to.be.true;
|
|
expect(smtpStub.quit.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
|
|
smtpStub.onerror(new Error());
|
|
});
|
|
});
|
|
|
|
describe('#check', function() {
|
|
beforeEach(function() {
|
|
sinon.stub(doctor, '_checkOnline');
|
|
sinon.stub(doctor, '_checkReachable');
|
|
sinon.stub(doctor, '_checkImap');
|
|
sinon.stub(doctor, '_checkSmtp');
|
|
});
|
|
|
|
it('should perform all tests', function(done) {
|
|
doctor._checkOnline.yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.imap).yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.smtp).yieldsAsync();
|
|
doctor._checkImap.yieldsAsync();
|
|
doctor._checkSmtp.yieldsAsync();
|
|
|
|
doctor.check(function(err) {
|
|
expect(err).to.not.exist;
|
|
expect(doctor._checkOnline.calledOnce).to.be.true;
|
|
expect(doctor._checkReachable.calledTwice).to.be.true;
|
|
expect(doctor._checkImap.calledOnce).to.be.true;
|
|
expect(doctor._checkSmtp.calledOnce).to.be.true;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail for smtp', function(done) {
|
|
doctor._checkOnline.yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.imap).yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.smtp).yieldsAsync();
|
|
doctor._checkImap.yieldsAsync();
|
|
doctor._checkSmtp.yieldsAsync(new Error());
|
|
|
|
doctor.check(function(err) {
|
|
expect(err).to.exist;
|
|
expect(doctor._checkOnline.calledOnce).to.be.true;
|
|
expect(doctor._checkReachable.calledTwice).to.be.true;
|
|
expect(doctor._checkImap.calledOnce).to.be.true;
|
|
expect(doctor._checkSmtp.calledOnce).to.be.true;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail for imap', function(done) {
|
|
doctor._checkOnline.yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.imap).yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.smtp).yieldsAsync();
|
|
doctor._checkImap.yieldsAsync(new Error());
|
|
|
|
doctor.check(function(err) {
|
|
expect(err).to.exist;
|
|
expect(doctor._checkOnline.calledOnce).to.be.true;
|
|
expect(doctor._checkReachable.calledTwice).to.be.true;
|
|
expect(doctor._checkImap.calledOnce).to.be.true;
|
|
expect(doctor._checkSmtp.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail for smtp reachability', function(done) {
|
|
doctor._checkOnline.yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.imap).yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.smtp).yieldsAsync(new Error());
|
|
|
|
doctor.check(function(err) {
|
|
expect(err).to.exist;
|
|
expect(doctor._checkOnline.calledOnce).to.be.true;
|
|
expect(doctor._checkReachable.calledTwice).to.be.true;
|
|
expect(doctor._checkImap.called).to.be.false;
|
|
expect(doctor._checkSmtp.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail for imap reachability', function(done) {
|
|
doctor._checkOnline.yieldsAsync();
|
|
doctor._checkReachable.withArgs(credentials.imap).yieldsAsync(new Error());
|
|
|
|
doctor.check(function(err) {
|
|
expect(err).to.exist;
|
|
expect(doctor._checkOnline.calledOnce).to.be.true;
|
|
expect(doctor._checkReachable.calledOnce).to.be.true;
|
|
expect(doctor._checkImap.called).to.be.false;
|
|
expect(doctor._checkSmtp.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail for offline', function(done) {
|
|
doctor._checkOnline.yieldsAsync(new Error());
|
|
|
|
doctor.check(function(err) {
|
|
expect(err).to.exist;
|
|
expect(doctor._checkOnline.calledOnce).to.be.true;
|
|
expect(doctor._checkReachable.called).to.be.false;
|
|
expect(doctor._checkImap.called).to.be.false;
|
|
expect(doctor._checkSmtp.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should fail w/o config', function(done) {
|
|
doctor.credentials = doctor._imap = doctor._smtp = undefined;
|
|
|
|
doctor.check(function(err) {
|
|
expect(err).to.exist;
|
|
expect(doctor._checkOnline.called).to.be.false;
|
|
expect(doctor._checkReachable.called).to.be.false;
|
|
expect(doctor._checkImap.called).to.be.false;
|
|
expect(doctor._checkSmtp.called).to.be.false;
|
|
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|