services/sync/tests/unit/test_service_login.js

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 Cu.import("resource://gre/modules/Log.jsm");
michael@0 5 Cu.import("resource://services-sync/constants.js");
michael@0 6 Cu.import("resource://services-sync/service.js");
michael@0 7 Cu.import("resource://services-sync/policies.js");
michael@0 8 Cu.import("resource://services-sync/util.js");
michael@0 9 Cu.import("resource://testing-common/services/sync/utils.js");
michael@0 10
michael@0 11 function login_handling(handler) {
michael@0 12 return function (request, response) {
michael@0 13 if (basic_auth_matches(request, "johndoe", "ilovejane") ||
michael@0 14 basic_auth_matches(request, "janedoe", "ilovejohn")) {
michael@0 15 handler(request, response);
michael@0 16 } else {
michael@0 17 let body = "Unauthorized";
michael@0 18 response.setStatusLine(request.httpVersion, 401, "Unauthorized");
michael@0 19 response.setHeader("Content-Type", "text/plain");
michael@0 20 response.bodyOutputStream.write(body, body.length);
michael@0 21 }
michael@0 22 };
michael@0 23 }
michael@0 24
michael@0 25 function run_test() {
michael@0 26 let logger = Log.repository.rootLogger;
michael@0 27 Log.repository.rootLogger.addAppender(new Log.DumpAppender());
michael@0 28
michael@0 29 run_next_test();
michael@0 30 }
michael@0 31
michael@0 32 add_test(function test_offline() {
michael@0 33 try {
michael@0 34 _("The right bits are set when we're offline.");
michael@0 35 Services.io.offline = true;
michael@0 36 do_check_false(!!Service.login());
michael@0 37 do_check_eq(Service.status.login, LOGIN_FAILED_NETWORK_ERROR);
michael@0 38 Services.io.offline = false;
michael@0 39 } finally {
michael@0 40 Svc.Prefs.resetBranch("");
michael@0 41 run_next_test();
michael@0 42 }
michael@0 43 });
michael@0 44
michael@0 45 function setup() {
michael@0 46 let janeHelper = track_collections_helper();
michael@0 47 let janeU = janeHelper.with_updated_collection;
michael@0 48 let janeColls = janeHelper.collections;
michael@0 49 let johnHelper = track_collections_helper();
michael@0 50 let johnU = johnHelper.with_updated_collection;
michael@0 51 let johnColls = johnHelper.collections;
michael@0 52
michael@0 53 let server = httpd_setup({
michael@0 54 "/1.1/johndoe/info/collections": login_handling(johnHelper.handler),
michael@0 55 "/1.1/janedoe/info/collections": login_handling(janeHelper.handler),
michael@0 56
michael@0 57 // We need these handlers because we test login, and login
michael@0 58 // is where keys are generated or fetched.
michael@0 59 // TODO: have Jane fetch her keys, not generate them...
michael@0 60 "/1.1/johndoe/storage/crypto/keys": johnU("crypto", new ServerWBO("keys").handler()),
michael@0 61 "/1.1/johndoe/storage/meta/global": johnU("meta", new ServerWBO("global").handler()),
michael@0 62 "/1.1/janedoe/storage/crypto/keys": janeU("crypto", new ServerWBO("keys").handler()),
michael@0 63 "/1.1/janedoe/storage/meta/global": janeU("meta", new ServerWBO("global").handler())
michael@0 64 });
michael@0 65
michael@0 66 Service.serverURL = server.baseURI;
michael@0 67 return server;
michael@0 68 }
michael@0 69
michael@0 70 add_test(function test_login_logout() {
michael@0 71 let server = setup();
michael@0 72
michael@0 73 try {
michael@0 74 _("Force the initial state.");
michael@0 75 ensureLegacyIdentityManager();
michael@0 76 Service.status.service = STATUS_OK;
michael@0 77 do_check_eq(Service.status.service, STATUS_OK);
michael@0 78
michael@0 79 _("Try logging in. It won't work because we're not configured yet.");
michael@0 80 Service.login();
michael@0 81 do_check_eq(Service.status.service, CLIENT_NOT_CONFIGURED);
michael@0 82 do_check_eq(Service.status.login, LOGIN_FAILED_NO_USERNAME);
michael@0 83 do_check_false(Service.isLoggedIn);
michael@0 84
michael@0 85 _("Try again with username and password set.");
michael@0 86 Service.identity.account = "johndoe";
michael@0 87 Service.identity.basicPassword = "ilovejane";
michael@0 88 Service.login();
michael@0 89 do_check_eq(Service.status.service, CLIENT_NOT_CONFIGURED);
michael@0 90 do_check_eq(Service.status.login, LOGIN_FAILED_NO_PASSPHRASE);
michael@0 91 do_check_false(Service.isLoggedIn);
michael@0 92
michael@0 93 _("Success if passphrase is set.");
michael@0 94 Service.identity.syncKey = "foo";
michael@0 95 Service.login();
michael@0 96 do_check_eq(Service.status.service, STATUS_OK);
michael@0 97 do_check_eq(Service.status.login, LOGIN_SUCCEEDED);
michael@0 98 do_check_true(Service.isLoggedIn);
michael@0 99
michael@0 100 _("We can also pass username, password and passphrase to login().");
michael@0 101 Service.login("janedoe", "incorrectpassword", "bar");
michael@0 102 setBasicCredentials("janedoe", "incorrectpassword", "bar");
michael@0 103 do_check_eq(Service.status.service, LOGIN_FAILED);
michael@0 104 do_check_eq(Service.status.login, LOGIN_FAILED_LOGIN_REJECTED);
michael@0 105 do_check_false(Service.isLoggedIn);
michael@0 106
michael@0 107 _("Try again with correct password.");
michael@0 108 Service.login("janedoe", "ilovejohn");
michael@0 109 do_check_eq(Service.status.service, STATUS_OK);
michael@0 110 do_check_eq(Service.status.login, LOGIN_SUCCEEDED);
michael@0 111 do_check_true(Service.isLoggedIn);
michael@0 112
michael@0 113 _("Calling login() with parameters when the client is unconfigured sends notification.");
michael@0 114 let notified = false;
michael@0 115 Svc.Obs.add("weave:service:setup-complete", function() {
michael@0 116 notified = true;
michael@0 117 });
michael@0 118 setBasicCredentials(null, null, null);
michael@0 119 Service.login("janedoe", "ilovejohn", "bar");
michael@0 120 do_check_true(notified);
michael@0 121 do_check_eq(Service.status.service, STATUS_OK);
michael@0 122 do_check_eq(Service.status.login, LOGIN_SUCCEEDED);
michael@0 123 do_check_true(Service.isLoggedIn);
michael@0 124
michael@0 125 _("Logout.");
michael@0 126 Service.logout();
michael@0 127 do_check_false(Service.isLoggedIn);
michael@0 128
michael@0 129 _("Logging out again won't do any harm.");
michael@0 130 Service.logout();
michael@0 131 do_check_false(Service.isLoggedIn);
michael@0 132
michael@0 133 } finally {
michael@0 134 Svc.Prefs.resetBranch("");
michael@0 135 server.stop(run_next_test);
michael@0 136 }
michael@0 137 });
michael@0 138
michael@0 139 add_test(function test_login_on_sync() {
michael@0 140 let server = setup();
michael@0 141 setBasicCredentials("johndoe", "ilovejane", "bar");
michael@0 142
michael@0 143 try {
michael@0 144 _("Sync calls login.");
michael@0 145 let oldLogin = Service.login;
michael@0 146 let loginCalled = false;
michael@0 147 Service.login = function() {
michael@0 148 loginCalled = true;
michael@0 149 Service.status.login = LOGIN_SUCCEEDED;
michael@0 150 this._loggedIn = false; // So that sync aborts.
michael@0 151 return true;
michael@0 152 };
michael@0 153
michael@0 154 Service.sync();
michael@0 155
michael@0 156 do_check_true(loginCalled);
michael@0 157 Service.login = oldLogin;
michael@0 158
michael@0 159 // Stub mpLocked.
michael@0 160 let mpLockedF = Utils.mpLocked;
michael@0 161 let mpLocked = true;
michael@0 162 Utils.mpLocked = function() mpLocked;
michael@0 163
michael@0 164 // Stub scheduleNextSync. This gets called within checkSyncStatus if we're
michael@0 165 // ready to sync, so use it as an indicator.
michael@0 166 let scheduleNextSyncF = Service.scheduler.scheduleNextSync;
michael@0 167 let scheduleCalled = false;
michael@0 168 Service.scheduler.scheduleNextSync = function(wait) {
michael@0 169 scheduleCalled = true;
michael@0 170 scheduleNextSyncF.call(this, wait);
michael@0 171 };
michael@0 172
michael@0 173 // Autoconnect still tries to connect in the background (useful behavior:
michael@0 174 // for non-MP users and unlocked MPs, this will detect version expiry
michael@0 175 // earlier).
michael@0 176 //
michael@0 177 // Consequently, non-MP users will be logged in as in the pre-Bug 543784 world,
michael@0 178 // and checkSyncStatus reflects that by waiting for login.
michael@0 179 //
michael@0 180 // This process doesn't apply if your MP is still locked, so we make
michael@0 181 // checkSyncStatus accept a locked MP in place of being logged in.
michael@0 182 //
michael@0 183 // This test exercises these two branches.
michael@0 184
michael@0 185 _("We're ready to sync if locked.");
michael@0 186 Service.enabled = true;
michael@0 187 Services.io.offline = false;
michael@0 188 Service.scheduler.checkSyncStatus();
michael@0 189 do_check_true(scheduleCalled);
michael@0 190
michael@0 191 _("... and also if we're not locked.");
michael@0 192 scheduleCalled = false;
michael@0 193 mpLocked = false;
michael@0 194 Service.scheduler.checkSyncStatus();
michael@0 195 do_check_true(scheduleCalled);
michael@0 196 Service.scheduler.scheduleNextSync = scheduleNextSyncF;
michael@0 197
michael@0 198 // TODO: need better tests around master password prompting. See Bug 620583.
michael@0 199
michael@0 200 mpLocked = true;
michael@0 201
michael@0 202 // Testing exception handling if master password dialog is canceled.
michael@0 203 // Do this by monkeypatching.
michael@0 204 let oldGetter = Service.identity.__lookupGetter__("syncKey");
michael@0 205 let oldSetter = Service.identity.__lookupSetter__("syncKey");
michael@0 206 _("Old passphrase function is " + oldGetter);
michael@0 207 Service.identity.__defineGetter__("syncKey",
michael@0 208 function() {
michael@0 209 throw "User canceled Master Password entry";
michael@0 210 });
michael@0 211
michael@0 212 let oldClearSyncTriggers = Service.scheduler.clearSyncTriggers;
michael@0 213 let oldLockedSync = Service._lockedSync;
michael@0 214
michael@0 215 let cSTCalled = false;
michael@0 216 let lockedSyncCalled = false;
michael@0 217
michael@0 218 Service.scheduler.clearSyncTriggers = function() { cSTCalled = true; };
michael@0 219 Service._lockedSync = function() { lockedSyncCalled = true; };
michael@0 220
michael@0 221 _("If master password is canceled, login fails and we report lockage.");
michael@0 222 do_check_false(!!Service.login());
michael@0 223 do_check_eq(Service.status.login, MASTER_PASSWORD_LOCKED);
michael@0 224 do_check_eq(Service.status.service, LOGIN_FAILED);
michael@0 225 _("Locked? " + Utils.mpLocked());
michael@0 226 _("checkSync reports the correct term.");
michael@0 227 do_check_eq(Service._checkSync(), kSyncMasterPasswordLocked);
michael@0 228
michael@0 229 _("Sync doesn't proceed and clears triggers if MP is still locked.");
michael@0 230 Service.sync();
michael@0 231
michael@0 232 do_check_true(cSTCalled);
michael@0 233 do_check_false(lockedSyncCalled);
michael@0 234
michael@0 235 Service.identity.__defineGetter__("syncKey", oldGetter);
michael@0 236 Service.identity.__defineSetter__("syncKey", oldSetter);
michael@0 237
michael@0 238 // N.B., a bunch of methods are stubbed at this point. Be careful putting
michael@0 239 // new tests after this point!
michael@0 240
michael@0 241 } finally {
michael@0 242 Svc.Prefs.resetBranch("");
michael@0 243 server.stop(run_next_test);
michael@0 244 }
michael@0 245 });

mercurial