services/sync/tests/unit/test_jpakeclient.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 Cu.import("resource://gre/modules/Log.jsm");
michael@0 2 Cu.import("resource://services-sync/identity.js");
michael@0 3 Cu.import("resource://services-sync/jpakeclient.js");
michael@0 4 Cu.import("resource://services-sync/constants.js");
michael@0 5 Cu.import("resource://services-sync/util.js");
michael@0 6 Cu.import("resource://testing-common/services/sync/utils.js");
michael@0 7
michael@0 8 const JPAKE_LENGTH_SECRET = 8;
michael@0 9 const JPAKE_LENGTH_CLIENTID = 256;
michael@0 10 const KEYEXCHANGE_VERSION = 3;
michael@0 11
michael@0 12 /*
michael@0 13 * Simple server.
michael@0 14 */
michael@0 15
michael@0 16 const SERVER_MAX_GETS = 6;
michael@0 17
michael@0 18 function check_headers(request) {
michael@0 19 let stack = Components.stack.caller;
michael@0 20
michael@0 21 // There shouldn't be any Basic auth
michael@0 22 do_check_false(request.hasHeader("Authorization"), stack);
michael@0 23
michael@0 24 // Ensure key exchange ID is set and the right length
michael@0 25 do_check_true(request.hasHeader("X-KeyExchange-Id"), stack);
michael@0 26 do_check_eq(request.getHeader("X-KeyExchange-Id").length,
michael@0 27 JPAKE_LENGTH_CLIENTID, stack);
michael@0 28 }
michael@0 29
michael@0 30 function new_channel() {
michael@0 31 // Create a new channel and register it with the server.
michael@0 32 let cid = Math.floor(Math.random() * 10000);
michael@0 33 while (channels[cid]) {
michael@0 34 cid = Math.floor(Math.random() * 10000);
michael@0 35 }
michael@0 36 let channel = channels[cid] = new ServerChannel();
michael@0 37 server.registerPathHandler("/" + cid, channel.handler());
michael@0 38 return cid;
michael@0 39 }
michael@0 40
michael@0 41 let server;
michael@0 42 let channels = {}; // Map channel -> ServerChannel object
michael@0 43 function server_new_channel(request, response) {
michael@0 44 check_headers(request);
michael@0 45 let cid = new_channel();
michael@0 46 let body = JSON.stringify("" + cid);
michael@0 47 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 48 response.bodyOutputStream.write(body, body.length);
michael@0 49 }
michael@0 50
michael@0 51 let error_report;
michael@0 52 function server_report(request, response) {
michael@0 53 check_headers(request);
michael@0 54
michael@0 55 if (request.hasHeader("X-KeyExchange-Log")) {
michael@0 56 error_report = request.getHeader("X-KeyExchange-Log");
michael@0 57 }
michael@0 58
michael@0 59 if (request.hasHeader("X-KeyExchange-Cid")) {
michael@0 60 let cid = request.getHeader("X-KeyExchange-Cid");
michael@0 61 let channel = channels[cid];
michael@0 62 if (channel) {
michael@0 63 channel.clear();
michael@0 64 }
michael@0 65 }
michael@0 66
michael@0 67 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 68 }
michael@0 69
michael@0 70 // Hook for test code.
michael@0 71 let hooks = {};
michael@0 72 function initHooks() {
michael@0 73 hooks.onGET = function onGET(request) {};
michael@0 74 }
michael@0 75 initHooks();
michael@0 76
michael@0 77 function ServerChannel() {
michael@0 78 this.data = "";
michael@0 79 this.etag = "";
michael@0 80 this.getCount = 0;
michael@0 81 }
michael@0 82 ServerChannel.prototype = {
michael@0 83
michael@0 84 GET: function GET(request, response) {
michael@0 85 if (!this.data) {
michael@0 86 response.setStatusLine(request.httpVersion, 404, "Not Found");
michael@0 87 return;
michael@0 88 }
michael@0 89
michael@0 90 if (request.hasHeader("If-None-Match")) {
michael@0 91 let etag = request.getHeader("If-None-Match");
michael@0 92 if (etag == this.etag) {
michael@0 93 response.setStatusLine(request.httpVersion, 304, "Not Modified");
michael@0 94 hooks.onGET(request);
michael@0 95 return;
michael@0 96 }
michael@0 97 }
michael@0 98 response.setHeader("ETag", this.etag);
michael@0 99 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 100 response.bodyOutputStream.write(this.data, this.data.length);
michael@0 101
michael@0 102 // Automatically clear the channel after 6 successful GETs.
michael@0 103 this.getCount += 1;
michael@0 104 if (this.getCount == SERVER_MAX_GETS) {
michael@0 105 this.clear();
michael@0 106 }
michael@0 107 hooks.onGET(request);
michael@0 108 },
michael@0 109
michael@0 110 PUT: function PUT(request, response) {
michael@0 111 if (this.data) {
michael@0 112 do_check_true(request.hasHeader("If-Match"));
michael@0 113 let etag = request.getHeader("If-Match");
michael@0 114 if (etag != this.etag) {
michael@0 115 response.setHeader("ETag", this.etag);
michael@0 116 response.setStatusLine(request.httpVersion, 412, "Precondition Failed");
michael@0 117 return;
michael@0 118 }
michael@0 119 } else {
michael@0 120 do_check_true(request.hasHeader("If-None-Match"));
michael@0 121 do_check_eq(request.getHeader("If-None-Match"), "*");
michael@0 122 }
michael@0 123
michael@0 124 this.data = readBytesFromInputStream(request.bodyInputStream);
michael@0 125 this.etag = '"' + Utils.sha1(this.data) + '"';
michael@0 126 response.setHeader("ETag", this.etag);
michael@0 127 response.setStatusLine(request.httpVersion, 200, "OK");
michael@0 128 },
michael@0 129
michael@0 130 clear: function clear() {
michael@0 131 delete this.data;
michael@0 132 },
michael@0 133
michael@0 134 handler: function handler() {
michael@0 135 let self = this;
michael@0 136 return function(request, response) {
michael@0 137 check_headers(request);
michael@0 138 let method = self[request.method];
michael@0 139 return method.apply(self, arguments);
michael@0 140 };
michael@0 141 }
michael@0 142
michael@0 143 };
michael@0 144
michael@0 145
michael@0 146 /**
michael@0 147 * Controller that throws for everything.
michael@0 148 */
michael@0 149 let BaseController = {
michael@0 150 displayPIN: function displayPIN() {
michael@0 151 do_throw("displayPIN() shouldn't have been called!");
michael@0 152 },
michael@0 153 onPairingStart: function onPairingStart() {
michael@0 154 do_throw("onPairingStart shouldn't have been called!");
michael@0 155 },
michael@0 156 onAbort: function onAbort(error) {
michael@0 157 do_throw("Shouldn't have aborted with " + error + "!");
michael@0 158 },
michael@0 159 onPaired: function onPaired() {
michael@0 160 do_throw("onPaired() shouldn't have been called!");
michael@0 161 },
michael@0 162 onComplete: function onComplete(data) {
michael@0 163 do_throw("Shouldn't have completed with " + data + "!");
michael@0 164 }
michael@0 165 };
michael@0 166
michael@0 167
michael@0 168 const DATA = {"msg": "eggstreamly sekrit"};
michael@0 169 const POLLINTERVAL = 50;
michael@0 170
michael@0 171 function run_test() {
michael@0 172 server = httpd_setup({"/new_channel": server_new_channel,
michael@0 173 "/report": server_report});
michael@0 174 Svc.Prefs.set("jpake.serverURL", server.baseURI + "/");
michael@0 175 Svc.Prefs.set("jpake.pollInterval", POLLINTERVAL);
michael@0 176 Svc.Prefs.set("jpake.maxTries", 2);
michael@0 177 Svc.Prefs.set("jpake.firstMsgMaxTries", 5);
michael@0 178 Svc.Prefs.set("jpake.lastMsgMaxTries", 5);
michael@0 179 // Ensure clean up
michael@0 180 Svc.Obs.add("profile-before-change", function() {
michael@0 181 Svc.Prefs.resetBranch("");
michael@0 182 });
michael@0 183
michael@0 184 // Ensure PSM is initialized.
michael@0 185 Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
michael@0 186
michael@0 187 // Simulate Sync setup with credentials in place. We want to make
michael@0 188 // sure the J-PAKE requests don't include those data.
michael@0 189 ensureLegacyIdentityManager();
michael@0 190 setBasicCredentials("johndoe", "ilovejane");
michael@0 191
michael@0 192 initTestLogging("Trace");
michael@0 193 Log.repository.getLogger("Sync.JPAKEClient").level = Log.Level.Trace;
michael@0 194 Log.repository.getLogger("Common.RESTRequest").level =
michael@0 195 Log.Level.Trace;
michael@0 196 run_next_test();
michael@0 197 }
michael@0 198
michael@0 199
michael@0 200 add_test(function test_success_receiveNoPIN() {
michael@0 201 _("Test a successful exchange started by receiveNoPIN().");
michael@0 202
michael@0 203 let snd = new JPAKEClient({
michael@0 204 __proto__: BaseController,
michael@0 205 onPaired: function onPaired() {
michael@0 206 _("Pairing successful, sending final payload.");
michael@0 207 do_check_true(pairingStartCalledOnReceiver);
michael@0 208 Utils.nextTick(function() { snd.sendAndComplete(DATA); });
michael@0 209 },
michael@0 210 onComplete: function onComplete() {}
michael@0 211 });
michael@0 212
michael@0 213 let pairingStartCalledOnReceiver = false;
michael@0 214 let rec = new JPAKEClient({
michael@0 215 __proto__: BaseController,
michael@0 216 displayPIN: function displayPIN(pin) {
michael@0 217 _("Received PIN " + pin + ". Entering it in the other computer...");
michael@0 218 this.cid = pin.slice(JPAKE_LENGTH_SECRET);
michael@0 219 Utils.nextTick(function() { snd.pairWithPIN(pin, false); });
michael@0 220 },
michael@0 221 onPairingStart: function onPairingStart() {
michael@0 222 pairingStartCalledOnReceiver = true;
michael@0 223 },
michael@0 224 onComplete: function onComplete(data) {
michael@0 225 do_check_true(Utils.deepEquals(DATA, data));
michael@0 226 // Ensure channel was cleared, no error report.
michael@0 227 do_check_eq(channels[this.cid].data, undefined);
michael@0 228 do_check_eq(error_report, undefined);
michael@0 229 run_next_test();
michael@0 230 }
michael@0 231 });
michael@0 232 rec.receiveNoPIN();
michael@0 233 });
michael@0 234
michael@0 235
michael@0 236 add_test(function test_firstMsgMaxTries_timeout() {
michael@0 237 _("Test abort when sender doesn't upload anything.");
michael@0 238
michael@0 239 let rec = new JPAKEClient({
michael@0 240 __proto__: BaseController,
michael@0 241 displayPIN: function displayPIN(pin) {
michael@0 242 _("Received PIN " + pin + ". Doing nothing...");
michael@0 243 this.cid = pin.slice(JPAKE_LENGTH_SECRET);
michael@0 244 },
michael@0 245 onAbort: function onAbort(error) {
michael@0 246 do_check_eq(error, JPAKE_ERROR_TIMEOUT);
michael@0 247 // Ensure channel was cleared, error report was sent.
michael@0 248 do_check_eq(channels[this.cid].data, undefined);
michael@0 249 do_check_eq(error_report, JPAKE_ERROR_TIMEOUT);
michael@0 250 error_report = undefined;
michael@0 251 run_next_test();
michael@0 252 }
michael@0 253 });
michael@0 254 rec.receiveNoPIN();
michael@0 255 });
michael@0 256
michael@0 257
michael@0 258 add_test(function test_firstMsgMaxTries() {
michael@0 259 _("Test that receiver can wait longer for the first message.");
michael@0 260
michael@0 261 let snd = new JPAKEClient({
michael@0 262 __proto__: BaseController,
michael@0 263 onPaired: function onPaired() {
michael@0 264 _("Pairing successful, sending final payload.");
michael@0 265 Utils.nextTick(function() { snd.sendAndComplete(DATA); });
michael@0 266 },
michael@0 267 onComplete: function onComplete() {}
michael@0 268 });
michael@0 269
michael@0 270 let rec = new JPAKEClient({
michael@0 271 __proto__: BaseController,
michael@0 272 displayPIN: function displayPIN(pin) {
michael@0 273 // For the purpose of the tests, the poll interval is 50ms and
michael@0 274 // we're polling up to 5 times for the first exchange (as
michael@0 275 // opposed to 2 times for most of the other exchanges). So let's
michael@0 276 // pretend it took 150ms to enter the PIN on the sender, which should
michael@0 277 // require 3 polls.
michael@0 278 // Rather than using an imprecise timer, we hook into the channel's
michael@0 279 // GET handler to know how long to wait.
michael@0 280 _("Received PIN " + pin + ". Waiting for three polls before entering it into sender...");
michael@0 281 this.cid = pin.slice(JPAKE_LENGTH_SECRET);
michael@0 282 let count = 0;
michael@0 283 hooks.onGET = function onGET(request) {
michael@0 284 if (++count == 3) {
michael@0 285 _("Third GET. Triggering pair.");
michael@0 286 Utils.nextTick(function() { snd.pairWithPIN(pin, false); });
michael@0 287 }
michael@0 288 };
michael@0 289 },
michael@0 290 onPairingStart: function onPairingStart(pin) {},
michael@0 291 onComplete: function onComplete(data) {
michael@0 292 do_check_true(Utils.deepEquals(DATA, data));
michael@0 293 // Ensure channel was cleared, no error report.
michael@0 294 do_check_eq(channels[this.cid].data, undefined);
michael@0 295 do_check_eq(error_report, undefined);
michael@0 296
michael@0 297 // Clean up.
michael@0 298 initHooks();
michael@0 299 run_next_test();
michael@0 300 }
michael@0 301 });
michael@0 302 rec.receiveNoPIN();
michael@0 303 });
michael@0 304
michael@0 305
michael@0 306 add_test(function test_lastMsgMaxTries() {
michael@0 307 _("Test that receiver can wait longer for the last message.");
michael@0 308
michael@0 309 let snd = new JPAKEClient({
michael@0 310 __proto__: BaseController,
michael@0 311 onPaired: function onPaired() {
michael@0 312 // For the purpose of the tests, the poll interval is 50ms and
michael@0 313 // we're polling up to 5 times for the last exchange (as opposed
michael@0 314 // to 2 times for other exchanges). So let's pretend it took
michael@0 315 // 150ms to come up with the final payload, which should require
michael@0 316 // 3 polls.
michael@0 317 // Rather than using an imprecise timer, we hook into the channel's
michael@0 318 // GET handler to know how long to wait.
michael@0 319 let count = 0;
michael@0 320 hooks.onGET = function onGET(request) {
michael@0 321 if (++count == 3) {
michael@0 322 _("Third GET. Triggering send.");
michael@0 323 Utils.nextTick(function() { snd.sendAndComplete(DATA); });
michael@0 324 }
michael@0 325 };
michael@0 326 },
michael@0 327 onComplete: function onComplete() {}
michael@0 328 });
michael@0 329
michael@0 330 let rec = new JPAKEClient({
michael@0 331 __proto__: BaseController,
michael@0 332 displayPIN: function displayPIN(pin) {
michael@0 333 _("Received PIN " + pin + ". Entering it in the other computer...");
michael@0 334 this.cid = pin.slice(JPAKE_LENGTH_SECRET);
michael@0 335 Utils.nextTick(function() { snd.pairWithPIN(pin, false); });
michael@0 336 },
michael@0 337 onPairingStart: function onPairingStart(pin) {},
michael@0 338 onComplete: function onComplete(data) {
michael@0 339 do_check_true(Utils.deepEquals(DATA, data));
michael@0 340 // Ensure channel was cleared, no error report.
michael@0 341 do_check_eq(channels[this.cid].data, undefined);
michael@0 342 do_check_eq(error_report, undefined);
michael@0 343
michael@0 344 // Clean up.
michael@0 345 initHooks();
michael@0 346 run_next_test();
michael@0 347 }
michael@0 348 });
michael@0 349
michael@0 350 rec.receiveNoPIN();
michael@0 351 });
michael@0 352
michael@0 353
michael@0 354 add_test(function test_wrongPIN() {
michael@0 355 _("Test abort when PINs don't match.");
michael@0 356
michael@0 357 let snd = new JPAKEClient({
michael@0 358 __proto__: BaseController,
michael@0 359 onAbort: function onAbort(error) {
michael@0 360 do_check_eq(error, JPAKE_ERROR_KEYMISMATCH);
michael@0 361 do_check_eq(error_report, JPAKE_ERROR_KEYMISMATCH);
michael@0 362 error_report = undefined;
michael@0 363 }
michael@0 364 });
michael@0 365
michael@0 366 let pairingStartCalledOnReceiver = false;
michael@0 367 let rec = new JPAKEClient({
michael@0 368 __proto__: BaseController,
michael@0 369 displayPIN: function displayPIN(pin) {
michael@0 370 this.cid = pin.slice(JPAKE_LENGTH_SECRET);
michael@0 371 let secret = pin.slice(0, JPAKE_LENGTH_SECRET);
michael@0 372 secret = [char for each (char in secret)].reverse().join("");
michael@0 373 let new_pin = secret + this.cid;
michael@0 374 _("Received PIN " + pin + ", but I'm entering " + new_pin);
michael@0 375
michael@0 376 Utils.nextTick(function() { snd.pairWithPIN(new_pin, false); });
michael@0 377 },
michael@0 378 onPairingStart: function onPairingStart() {
michael@0 379 pairingStartCalledOnReceiver = true;
michael@0 380 },
michael@0 381 onAbort: function onAbort(error) {
michael@0 382 do_check_true(pairingStartCalledOnReceiver);
michael@0 383 do_check_eq(error, JPAKE_ERROR_NODATA);
michael@0 384 // Ensure channel was cleared.
michael@0 385 do_check_eq(channels[this.cid].data, undefined);
michael@0 386 run_next_test();
michael@0 387 }
michael@0 388 });
michael@0 389 rec.receiveNoPIN();
michael@0 390 });
michael@0 391
michael@0 392
michael@0 393 add_test(function test_abort_receiver() {
michael@0 394 _("Test user abort on receiving side.");
michael@0 395
michael@0 396 let rec = new JPAKEClient({
michael@0 397 __proto__: BaseController,
michael@0 398 onAbort: function onAbort(error) {
michael@0 399 // Manual abort = userabort.
michael@0 400 do_check_eq(error, JPAKE_ERROR_USERABORT);
michael@0 401 // Ensure channel was cleared.
michael@0 402 do_check_eq(channels[this.cid].data, undefined);
michael@0 403 do_check_eq(error_report, JPAKE_ERROR_USERABORT);
michael@0 404 error_report = undefined;
michael@0 405 run_next_test();
michael@0 406 },
michael@0 407 displayPIN: function displayPIN(pin) {
michael@0 408 this.cid = pin.slice(JPAKE_LENGTH_SECRET);
michael@0 409 Utils.nextTick(function() { rec.abort(); });
michael@0 410 }
michael@0 411 });
michael@0 412 rec.receiveNoPIN();
michael@0 413 });
michael@0 414
michael@0 415
michael@0 416 add_test(function test_abort_sender() {
michael@0 417 _("Test user abort on sending side.");
michael@0 418
michael@0 419 let snd = new JPAKEClient({
michael@0 420 __proto__: BaseController,
michael@0 421 onAbort: function onAbort(error) {
michael@0 422 // Manual abort == userabort.
michael@0 423 do_check_eq(error, JPAKE_ERROR_USERABORT);
michael@0 424 do_check_eq(error_report, JPAKE_ERROR_USERABORT);
michael@0 425 error_report = undefined;
michael@0 426 }
michael@0 427 });
michael@0 428
michael@0 429 let rec = new JPAKEClient({
michael@0 430 __proto__: BaseController,
michael@0 431 onAbort: function onAbort(error) {
michael@0 432 do_check_eq(error, JPAKE_ERROR_NODATA);
michael@0 433 // Ensure channel was cleared, no error report.
michael@0 434 do_check_eq(channels[this.cid].data, undefined);
michael@0 435 do_check_eq(error_report, undefined);
michael@0 436 initHooks();
michael@0 437 run_next_test();
michael@0 438 },
michael@0 439 displayPIN: function displayPIN(pin) {
michael@0 440 _("Received PIN " + pin + ". Entering it in the other computer...");
michael@0 441 this.cid = pin.slice(JPAKE_LENGTH_SECRET);
michael@0 442 Utils.nextTick(function() { snd.pairWithPIN(pin, false); });
michael@0 443
michael@0 444 // Abort after the first poll.
michael@0 445 let count = 0;
michael@0 446 hooks.onGET = function onGET(request) {
michael@0 447 if (++count >= 1) {
michael@0 448 _("First GET. Aborting.");
michael@0 449 Utils.nextTick(function() { snd.abort(); });
michael@0 450 }
michael@0 451 };
michael@0 452 },
michael@0 453 onPairingStart: function onPairingStart(pin) {}
michael@0 454 });
michael@0 455 rec.receiveNoPIN();
michael@0 456 });
michael@0 457
michael@0 458
michael@0 459 add_test(function test_wrongmessage() {
michael@0 460 let cid = new_channel();
michael@0 461 let channel = channels[cid];
michael@0 462 channel.data = JSON.stringify({type: "receiver2",
michael@0 463 version: KEYEXCHANGE_VERSION,
michael@0 464 payload: {}});
michael@0 465 channel.etag = '"fake-etag"';
michael@0 466 let snd = new JPAKEClient({
michael@0 467 __proto__: BaseController,
michael@0 468 onComplete: function onComplete(data) {
michael@0 469 do_throw("onComplete shouldn't be called.");
michael@0 470 },
michael@0 471 onAbort: function onAbort(error) {
michael@0 472 do_check_eq(error, JPAKE_ERROR_WRONGMESSAGE);
michael@0 473 run_next_test();
michael@0 474 }
michael@0 475 });
michael@0 476 snd.pairWithPIN("01234567" + cid, false);
michael@0 477 });
michael@0 478
michael@0 479
michael@0 480 add_test(function test_error_channel() {
michael@0 481 let serverURL = Svc.Prefs.get("jpake.serverURL");
michael@0 482 Svc.Prefs.set("jpake.serverURL", "http://localhost:12345/");
michael@0 483
michael@0 484 let rec = new JPAKEClient({
michael@0 485 __proto__: BaseController,
michael@0 486 onAbort: function onAbort(error) {
michael@0 487 do_check_eq(error, JPAKE_ERROR_CHANNEL);
michael@0 488 Svc.Prefs.set("jpake.serverURL", serverURL);
michael@0 489 run_next_test();
michael@0 490 },
michael@0 491 onPairingStart: function onPairingStart(pin) {},
michael@0 492 displayPIN: function displayPIN(pin) {}
michael@0 493 });
michael@0 494 rec.receiveNoPIN();
michael@0 495 });
michael@0 496
michael@0 497
michael@0 498 add_test(function test_error_network() {
michael@0 499 let serverURL = Svc.Prefs.get("jpake.serverURL");
michael@0 500 Svc.Prefs.set("jpake.serverURL", "http://localhost:12345/");
michael@0 501
michael@0 502 let snd = new JPAKEClient({
michael@0 503 __proto__: BaseController,
michael@0 504 onAbort: function onAbort(error) {
michael@0 505 do_check_eq(error, JPAKE_ERROR_NETWORK);
michael@0 506 Svc.Prefs.set("jpake.serverURL", serverURL);
michael@0 507 run_next_test();
michael@0 508 }
michael@0 509 });
michael@0 510 snd.pairWithPIN("0123456789ab", false);
michael@0 511 });
michael@0 512
michael@0 513
michael@0 514 add_test(function test_error_server_noETag() {
michael@0 515 let cid = new_channel();
michael@0 516 let channel = channels[cid];
michael@0 517 channel.data = JSON.stringify({type: "receiver1",
michael@0 518 version: KEYEXCHANGE_VERSION,
michael@0 519 payload: {}});
michael@0 520 // This naughty server doesn't supply ETag (well, it supplies empty one).
michael@0 521 channel.etag = "";
michael@0 522 let snd = new JPAKEClient({
michael@0 523 __proto__: BaseController,
michael@0 524 onAbort: function onAbort(error) {
michael@0 525 do_check_eq(error, JPAKE_ERROR_SERVER);
michael@0 526 run_next_test();
michael@0 527 }
michael@0 528 });
michael@0 529 snd.pairWithPIN("01234567" + cid, false);
michael@0 530 });
michael@0 531
michael@0 532
michael@0 533 add_test(function test_error_delayNotSupported() {
michael@0 534 let cid = new_channel();
michael@0 535 let channel = channels[cid];
michael@0 536 channel.data = JSON.stringify({type: "receiver1",
michael@0 537 version: 2,
michael@0 538 payload: {}});
michael@0 539 channel.etag = '"fake-etag"';
michael@0 540 let snd = new JPAKEClient({
michael@0 541 __proto__: BaseController,
michael@0 542 onAbort: function onAbort(error) {
michael@0 543 do_check_eq(error, JPAKE_ERROR_DELAYUNSUPPORTED);
michael@0 544 run_next_test();
michael@0 545 }
michael@0 546 });
michael@0 547 snd.pairWithPIN("01234567" + cid, true);
michael@0 548 });
michael@0 549
michael@0 550
michael@0 551 add_test(function test_sendAndComplete_notPaired() {
michael@0 552 let snd = new JPAKEClient({__proto__: BaseController});
michael@0 553 do_check_throws(function () {
michael@0 554 snd.sendAndComplete(DATA);
michael@0 555 });
michael@0 556 run_next_test();
michael@0 557 });
michael@0 558
michael@0 559
michael@0 560 add_test(function tearDown() {
michael@0 561 server.stop(run_next_test);
michael@0 562 });

mercurial