diff --git a/Gruntfile.js b/Gruntfile.js index a2fdde3..e54cf73 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -171,6 +171,8 @@ module.exports = function(grunt) { 'test/unit/devicestorage-dao-test.js', 'test/unit/dialog-ctrl-test.js', 'test/unit/add-account-ctrl-test.js', + 'test/unit/create-account-ctrl-test.js', + 'test/unit/validate-phone-ctrl-test.js', 'test/unit/account-ctrl-test.js', 'test/unit/set-passphrase-ctrl-test.js', 'test/unit/contacts-ctrl-test.js', diff --git a/src/js/controller/add-account.js b/src/js/controller/add-account.js index 8d08488..6b05a5d 100644 --- a/src/js/controller/add-account.js +++ b/src/js/controller/add-account.js @@ -36,10 +36,10 @@ var AddAccountCtrl = function($scope, $location, $routeParams, $http) { $scope.connectToGoogle(); } else if (config.imap.source === 'guess') { // use standard password login... show config details due to guess - setCredentials('custom'); + $scope.setCredentials('custom'); } else { // use standard password login... hide config details - setCredentials(); + $scope.setCredentials(); } }).catch(function() { @@ -61,44 +61,38 @@ var AddAccountCtrl = function($scope, $location, $routeParams, $http) { faqLink: 'https://github.com/whiteout-io/mail-html5/wiki/FAQ#how-does-sign-in-with-google-work', callback: function(granted) { if (granted) { + // query oauth token useOAuth(); } else { - setGmailPassword(); + // use normal user/password login + $scope.setCredentials('gmail'); $scope.$apply(); } } }); } else { // no oauth support - setGmailPassword(); + // use normal user/password login + $scope.setCredentials('gmail'); + } + + function useOAuth() { + // fetches the email address from the chrome identity api + appCtrl._auth.getOAuthToken(function(err) { + if (err) { + return $scope.onError(err); + } + $scope.setCredentials('gmail'); + $scope.$apply(); + }); } }; - // - // Helper functions - // - - function useOAuth() { - // fetches the email address from the chrome identity api - appCtrl._auth.getOAuthToken(function(err) { - if (err) { - return $scope.onError(err); - } - setCredentials('gmail'); - $scope.$apply(); - }); - } - - function setGmailPassword() { - // use normal user/password login - setCredentials('gmail'); - } - - function setCredentials(provider) { + $scope.setCredentials = function(provider) { $location.path('/login-set-credentials').search({ provider: provider }); - } + }; }; module.exports = AddAccountCtrl; \ No newline at end of file diff --git a/src/js/controller/login-set-credentials.js b/src/js/controller/login-set-credentials.js index a8c6d97..983c1f1 100644 --- a/src/js/controller/login-set-credentials.js +++ b/src/js/controller/login-set-credentials.js @@ -4,8 +4,7 @@ var ENCRYPTION_METHOD_NONE = 0; var ENCRYPTION_METHOD_STARTTLS = 1; var ENCRYPTION_METHOD_TLS = 2; -var appCtrl = require('../app-controller'), - config = require('../app-config').config; +var appCtrl = require('../app-controller'); var SetCredentialsCtrl = function($scope, $location, $routeParams) { if (!appCtrl._auth && !$routeParams.dev) { diff --git a/test/unit/add-account-ctrl-test.js b/test/unit/add-account-ctrl-test.js index baf3ed4..d860ff5 100644 --- a/test/unit/add-account-ctrl-test.js +++ b/test/unit/add-account-ctrl-test.js @@ -3,22 +3,22 @@ var mocks = angular.mock, AddAccountCtrl = require('../../src/js/controller/add-account'), Auth = require('../../src/js/bo/auth'), - AdminDao = require('../../src/js/dao/admin-dao'), - appController = require('../../src/js/app-controller'); + appController = require('../../src/js/app-controller'), + cfg = require('../../src/js/app-config').config; describe('Add Account Controller unit test', function() { - var scope, location, ctrl, authStub, origAuth, adminStub; + var scope, location, httpBackend, ctrl, authStub, origAuth; beforeEach(function() { // remember original module to restore later, then replace it origAuth = appController._auth; appController._auth = authStub = sinon.createStubInstance(Auth); - appController._adminDao = adminStub = sinon.createStubInstance(AdminDao); angular.module('addaccounttest', []); mocks.module('addaccounttest'); - mocks.inject(function($controller, $rootScope, $location) { + mocks.inject(function($controller, $rootScope, $location, $httpBackend) { location = $location; + httpBackend = $httpBackend; scope = $rootScope.$new(); scope.state = {}; scope.form = {}; @@ -45,122 +45,117 @@ describe('Add Account Controller unit test', function() { if (scope.$apply.restore) { scope.$apply.restore(); } + + httpBackend.verifyNoOutstandingExpectation(); + httpBackend.verifyNoOutstandingRequest(); }); - describe('createWhiteoutAccount', function() { - it('should return early for invalid form', function() { - scope.form.$invalid = true; - scope.createWhiteoutAccount(); - expect(adminStub.createUser.called).to.be.false; - }); + describe('getAccountSettings', function() { + var url, connectToGoogleStub, setCredentialsStub, mailConfig; - it('should fail to error creating user', function(done) { + beforeEach(function() { scope.form.$invalid = false; - scope.betaCode = 'asfd'; - scope.phone = '12345'; - adminStub.createUser.yieldsAsync(new Error('asdf')); - - scope.$apply = function() { - expect(scope.busy).to.be.false; - expect(scope.errMsg).to.equal('asdf'); - expect(adminStub.createUser.calledOnce).to.be.true; - done(); + scope.emailAddress = 'test@example.com'; + url = cfg.settingsUrl + 'example.com'; + mailConfig = { + imap: { + hostname: 'imap.example.com', + source: 'guess' + } }; - - scope.createWhiteoutAccount(); - expect(scope.busy).to.be.true; + connectToGoogleStub = sinon.stub(scope, 'connectToGoogle'); + setCredentialsStub = sinon.stub(scope, 'setCredentials'); }); - it('should work', function(done) { - scope.form.$invalid = false; - scope.betaCode = 'asfd'; - scope.phone = '12345'; - adminStub.createUser.yieldsAsync(); - - scope.$apply = function() { - expect(scope.busy).to.be.false; - expect(scope.errMsg).to.be.undefined; - expect(scope.step).to.equal(3); - expect(adminStub.createUser.calledOnce).to.be.true; - done(); - }; - - scope.createWhiteoutAccount(); - expect(scope.busy).to.be.true; - }); - }); - - describe('validateUser', function() { - it('should return early for invalid form', function() { - scope.formValidate.$invalid = true; - scope.validateUser(); - expect(adminStub.validateUser.called).to.be.false; + afterEach(function() { + connectToGoogleStub.restore(); + setCredentialsStub.restore(); }); - it('should fail to error creating user', function(done) { - scope.formValidate.$invalid = false; - scope.token = 'asfd'; - adminStub.validateUser.yieldsAsync(new Error('asdf')); + it('should work for gmail', function() { + mailConfig.imap.hostname = 'imap.gmail.com'; + httpBackend.expectGET(url).respond(mailConfig); - scope.$apply = function() { - expect(scope.busyValidate).to.be.false; - expect(scope.errMsgValidate).to.equal('asdf'); - expect(adminStub.validateUser.calledOnce).to.be.true; - done(); - }; + scope.getAccountSettings(); + httpBackend.flush(); - scope.validateUser(); - expect(scope.busyValidate).to.be.true; + expect(connectToGoogleStub.calledOnce).to.be.true; }); - it('should work', function(done) { - scope.formValidate.$invalid = false; - scope.token = 'asfd'; - adminStub.validateUser.yieldsAsync(); + it('should work for guessed domain', function() { + httpBackend.expectGET(url).respond(mailConfig); - scope.login = function() { - expect(scope.busyValidate).to.be.true; - expect(scope.errMsgValidate).to.be.undefined; - expect(adminStub.validateUser.calledOnce).to.be.true; - done(); - }; + scope.getAccountSettings(); + httpBackend.flush(); - scope.validateUser(); - expect(scope.busyValidate).to.be.true; + expect(setCredentialsStub.calledWith('custom')).to.be.true; }); - }); - describe('login', function() { - it('should work', function() { - scope.form.$invalid = false; - authStub.setCredentials.returns(); + it('should work for dns domain', function() { + mailConfig.imap.source = 'dns'; + httpBackend.expectGET(url).respond(mailConfig); - scope.login(); - expect(authStub.setCredentials.calledOnce).to.be.true; - expect(location.path.calledWith('/login')).to.be.true; + scope.getAccountSettings(); + httpBackend.flush(); + + expect(setCredentialsStub.calledWith(undefined)).to.be.true; + }); + + it('should fail with http 500', function() { + httpBackend.expectGET(url).respond(500, ''); + + scope.getAccountSettings(); + httpBackend.flush(); + + expect(scope.errMsg).to.exist; }); }); describe('connectToGoogle', function() { - it('should forward to login', function() { + var setCredentialsStub; + + beforeEach(function() { + setCredentialsStub = sinon.stub(scope, 'setCredentials'); + }); + + afterEach(function() { + setCredentialsStub.restore(); + }); + + it('should use oauth', function() { authStub._oauth = { isSupported: function() { return true; } }; - + scope.onError = function(options) { + options.callback(true); + }; authStub.getOAuthToken.yields(); scope.connectToGoogle(); - expect(location.path.calledWith('/login-set-credentials')).to.be.true; - expect(location.search.calledWith({ - provider: 'gmail' - })).to.be.true; + expect(setCredentialsStub.calledWith('gmail')).to.be.true; expect(authStub.getOAuthToken.calledOnce).to.be.true; }); - it('should not use oauth for gmail', function() { + it('should not use oauth', function() { + authStub._oauth = { + isSupported: function() { + return true; + } + }; + scope.onError = function(options) { + options.callback(false); + }; + + scope.connectToGoogle(); + + expect(setCredentialsStub.calledWith('gmail')).to.be.true; + expect(authStub.getOAuthToken.called).to.be.false; + }); + + it('should not use oauth if not supported', function() { authStub._oauth = { isSupported: function() { return false; @@ -169,10 +164,7 @@ describe('Add Account Controller unit test', function() { scope.connectToGoogle(); - expect(location.path.calledWith('/login-set-credentials')).to.be.true; - expect(location.search.calledWith({ - provider: 'gmail' - })).to.be.true; + expect(setCredentialsStub.calledWith('gmail')).to.be.true; expect(authStub.getOAuthToken.called).to.be.false; }); @@ -182,29 +174,28 @@ describe('Add Account Controller unit test', function() { return true; } }; + scope.onError = function(options) { + scope.onError = function(err) { + expect(err).to.exist; + expect(setCredentialsStub.called).to.be.false; + done(); + }; - authStub.getOAuthToken.yields(new Error()); - - scope.onError = function(err) { - expect(err).to.exist; - expect(location.path.called).to.be.false; - expect(location.search.called).to.be.false; - - done(); + options.callback(true); }; + authStub.getOAuthToken.yields(new Error()); scope.connectToGoogle(); }); }); - describe('connectTo', function() { - it('should forward to login', function() { - var provider = 'wmail'; - scope.connectTo(provider); + describe('setCredentials', function() { + it('should work', function() { + scope.setCredentials('gmail'); expect(location.path.calledWith('/login-set-credentials')).to.be.true; expect(location.search.calledWith({ - provider: provider + provider: 'gmail' })).to.be.true; }); }); diff --git a/test/unit/create-account-ctrl-test.js b/test/unit/create-account-ctrl-test.js new file mode 100644 index 0000000..8357ae4 --- /dev/null +++ b/test/unit/create-account-ctrl-test.js @@ -0,0 +1,91 @@ +'use strict'; + +var mocks = angular.mock, + CreateAccountCtrl = require('../../src/js/controller/create-account'), + AdminDao = require('../../src/js/dao/admin-dao'), + appController = require('../../src/js/app-controller'); + +describe('Create Account Controller unit test', function() { + var scope, location, ctrl, authStub, origAuth, adminStub; + + beforeEach(function() { + // remember original module to restore later, then replace it + origAuth = appController._auth; + appController._auth = authStub = {}; + appController._adminDao = adminStub = sinon.createStubInstance(AdminDao); + + angular.module('createaccounttest', []); + mocks.module('createaccounttest'); + mocks.inject(function($controller, $rootScope, $location) { + location = $location; + scope = $rootScope.$new(); + scope.state = {}; + scope.form = {}; + scope.formValidate = {}; + + sinon.stub(location, 'path').returns(location); + sinon.stub(location, 'search').returns(location); + sinon.stub(scope, '$apply', function() {}); + + ctrl = $controller(CreateAccountCtrl, { + $location: location, + $scope: scope, + $routeParams: {} + }); + }); + }); + + afterEach(function() { + // restore the app controller module + appController._auth = origAuth; + + location.path.restore(); + location.search.restore(); + if (scope.$apply.restore) { + scope.$apply.restore(); + } + }); + + describe('createWhiteoutAccount', function() { + it('should return early for invalid form', function() { + scope.form.$invalid = true; + scope.createWhiteoutAccount(); + expect(adminStub.createUser.called).to.be.false; + }); + + it('should fail to error creating user', function(done) { + scope.form.$invalid = false; + scope.betaCode = 'asfd'; + scope.phone = '12345'; + adminStub.createUser.yieldsAsync(new Error('asdf')); + + scope.$apply = function() { + expect(scope.busy).to.be.false; + expect(scope.errMsg).to.equal('asdf'); + expect(adminStub.createUser.calledOnce).to.be.true; + done(); + }; + + scope.createWhiteoutAccount(); + expect(scope.busy).to.be.true; + }); + + it('should work', function(done) { + scope.form.$invalid = false; + scope.betaCode = 'asfd'; + scope.phone = '12345'; + adminStub.createUser.yieldsAsync(); + + scope.$apply = function() { + expect(scope.busy).to.be.false; + expect(scope.errMsg).to.be.undefined; + expect(adminStub.createUser.calledOnce).to.be.true; + done(); + }; + + scope.createWhiteoutAccount(); + expect(scope.busy).to.be.true; + }); + }); + +}); \ No newline at end of file diff --git a/test/unit/validate-phone-ctrl-test.js b/test/unit/validate-phone-ctrl-test.js new file mode 100644 index 0000000..7884781 --- /dev/null +++ b/test/unit/validate-phone-ctrl-test.js @@ -0,0 +1,106 @@ +'use strict'; + +var mocks = angular.mock, + ValidatePhoneCtrl = require('../../src/js/controller/validate-phone'), + Auth = require('../../src/js/bo/auth'), + AdminDao = require('../../src/js/dao/admin-dao'), + appController = require('../../src/js/app-controller'); + +describe('Validate Phone Controller unit test', function() { + var scope, location, ctrl, authStub, origAuth, adminStub; + + beforeEach(function() { + // remember original module to restore later, then replace it + origAuth = appController._auth; + appController._auth = authStub = sinon.createStubInstance(Auth); + appController._adminDao = adminStub = sinon.createStubInstance(AdminDao); + + angular.module('validatephonetest', []); + mocks.module('validatephonetest'); + mocks.inject(function($controller, $rootScope, $location) { + location = $location; + scope = $rootScope.$new(); + scope.state = { + createAccount: { + emailAddress: 'test@example.com', + pass: 'asdf', + realname: 'Test User' + } + }; + scope.form = {}; + + sinon.stub(location, 'path').returns(location); + sinon.stub(location, 'search').returns(location); + sinon.stub(scope, '$apply', function() {}); + + ctrl = $controller(ValidatePhoneCtrl, { + $location: location, + $scope: scope, + $routeParams: {} + }); + }); + }); + + afterEach(function() { + // restore the app controller module + appController._auth = origAuth; + + location.path.restore(); + location.search.restore(); + if (scope.$apply.restore) { + scope.$apply.restore(); + } + }); + + describe('validateUser', function() { + it('should return early for invalid form', function() { + scope.form.$invalid = true; + scope.validateUser(); + expect(adminStub.validateUser.called).to.be.false; + }); + + it('should fail to error creating user', function(done) { + scope.form.$invalid = false; + scope.token = 'asfd'; + adminStub.validateUser.yieldsAsync(new Error('asdf')); + + scope.$apply = function() { + expect(scope.busy).to.be.false; + expect(scope.errMsg).to.equal('asdf'); + expect(adminStub.validateUser.calledOnce).to.be.true; + done(); + }; + + scope.validateUser(); + expect(scope.busy).to.be.true; + }); + + it('should work', function(done) { + scope.form.$invalid = false; + scope.token = 'asfd'; + adminStub.validateUser.yieldsAsync(); + + scope.login = function() { + expect(scope.busy).to.be.true; + expect(scope.errMsg).to.be.undefined; + expect(adminStub.validateUser.calledOnce).to.be.true; + done(); + }; + + scope.validateUser(); + expect(scope.busy).to.be.true; + }); + }); + + describe('login', function() { + it('should work', function() { + scope.form.$invalid = false; + authStub.setCredentials.returns(); + + scope.login(); + expect(authStub.setCredentials.calledOnce).to.be.true; + expect(location.path.calledWith('/login')).to.be.true; + }); + }); + +}); \ No newline at end of file