diff --git a/resources/static/pages/js/page_helpers.js b/resources/static/pages/js/page_helpers.js index 22df8dbbcc5ba89174aa34936d374531f38eafe0..9ec528c6b0103bdf4ebbfbb7bde50f75eb7cb139 100644 --- a/resources/static/pages/js/page_helpers.js +++ b/resources/static/pages/js/page_helpers.js @@ -73,26 +73,19 @@ BrowserID.PageHelpers = (function() { function replaceFormWithNotice(selector, onComplete) { $("form").hide(); - $(selector).fadeIn(ANIMATION_SPEED); - // If there is more than one .forminputs, the onComplete callback is called - // multiple times, we only want once. - onComplete && setTimeout(onComplete, ANIMATION_SPEED); + $(selector).fadeIn(ANIMATION_SPEED).promise().done(onComplete); } function replaceInputsWithNotice(selector, onComplete) { $('.forminputs').hide(); - $(selector).stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED); - // If there is more than one .forminputs, the onComplete callback is called - // multiple times, we only want once. - onComplete && setTimeout(onComplete, ANIMATION_SPEED); + $(selector).stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED) + .promise().done(onComplete); } function showInputs(onComplete) { $('.notification').hide(); - $('.forminputs').stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED); - // If there is more than one .forminputs, the onComplete callback is called - // multiple times, we only want once. - onComplete && setTimeout(onComplete, ANIMATION_SPEED); + $('.forminputs').stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED) + .promise().done(onComplete); } function emailSent(onComplete) { diff --git a/resources/static/pages/js/verify_secondary_address.js b/resources/static/pages/js/verify_secondary_address.js index 5b2f7f20051e8bd9c3ce71c181ac75c2cc6c4c69..ee9e2227c2bb35be670dd0962599f849208360b2 100644 --- a/resources/static/pages/js/verify_secondary_address.js +++ b/resources/static/pages/js/verify_secondary_address.js @@ -1,4 +1,4 @@ -/*globals BrowserID: true, $:true */ +/*globals BrowserID: true, $:true, URLParse: true */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -26,25 +26,36 @@ BrowserID.verifySecondaryAddress = (function() { secondsRemaining = REDIRECT_SECONDS, email, redirectTo, - redirectTimeout; // set in config if available, use REDIRECT_SECONDS otw. + redirectTimeout, // set in config if available, use REDIRECT_SECONDS otw. + uiTimeoutID; function showRegistrationInfo(info) { dom.setInner("#email", info.email); if (info.returnTo) { dom.setInner(".website", info.returnTo); + if (uiTimeoutID) uiTimeoutID = clearTimeout(uiTimeoutID); updateRedirectTimeout(); dom.show(".siteinfo"); } } function updateRedirectTimeout() { - if (secondsRemaining > 0) { - dom.setInner("#redirectTimeout", secondsRemaining); + dom.setInner("#redirectTimeout", secondsRemaining); + } - secondsRemaining--; - setTimeout(updateRedirectTimeout, 1000); + function countdownTimeout(onComplete) { + function checkTime() { + if (secondsRemaining > 0) { + updateRedirectTimeout(); + secondsRemaining--; + uiTimeoutID = setTimeout(checkTime, 1000); + } else { + complete(onComplete); + } } + + checkTime(); } function submit(oncomplete) { @@ -67,10 +78,10 @@ BrowserID.verifySecondaryAddress = (function() { // has had a chance to finish its business. storage.setLoggedIn(URLParse(redirectTo).originOnly(), email); - setTimeout(function() { + countdownTimeout(function() { doc.location.href = redirectTo; complete(oncomplete, verified); - }, redirectTimeout); + }); } else { complete(oncomplete, verified); @@ -96,13 +107,13 @@ BrowserID.verifySecondaryAddress = (function() { } function startVerification(oncomplete) { + /*jshint validthis: true*/ var self=this; user.tokenInfo(token, function(info) { if (info) { redirectTo = info.returnTo; email = info.email; showRegistrationInfo(info); - mustAuth = info.must_auth; if (mustAuth) { // These are users who are authenticating in a different browser or @@ -138,6 +149,8 @@ BrowserID.verifySecondaryAddress = (function() { if (typeof redirectTimeout === "undefined") { redirectTimeout = REDIRECT_SECONDS * 1000; } + secondsRemaining = redirectTimeout / 1000; + startVerification.call(self, options.ready); diff --git a/resources/static/test/cases/pages/js/verify_secondary_address.js b/resources/static/test/cases/pages/js/verify_secondary_address.js index fcbbe88392b2d1f792bc76d9e1f1a3ac5d7b74d1..8afe1e7f1030a16f0a3db3e181b2e3713e32038e 100644 --- a/resources/static/test/cases/pages/js/verify_secondary_address.js +++ b/resources/static/test/cases/pages/js/verify_secondary_address.js @@ -11,6 +11,7 @@ xhr = bid.Mocks.xhr, WindowMock = bid.Mocks.WindowMock, dom = bid.DOM, + pageHelpers = bid.PageHelpers, testHelpers = bid.TestHelpers, testHasClass = testHelpers.testHasClass, testVisible = testHelpers.testVisible, @@ -26,19 +27,24 @@ setup: function() { testHelpers.setup(); bid.Renderer.render("#page_head", "site/confirm", {}); + $(document.body).append($('<div id=redirectTimeout>')); $(".siteinfo,.password_entry").hide(); }, teardown: function() { + $('#redirectTimeout').remove(); testHelpers.teardown(); } }); function createController(options, callback) { controller = BrowserID.verifySecondaryAddress.create(); - options = options || {}; - options.document = doc = new WindowMock().document; - options.redirectTimeout = 0; - options.ready = callback; + // defaults, but options can override + options = _.extend({ + document: new WindowMock().document, + redirectTimeout: 0, + ready: callback + }, options || {}); + doc = options.document; controller.start(options); } @@ -156,4 +162,32 @@ }); }); + asyncTest("redirect: message shows with correct timeout", function() { + var returnTo = 'http://test.domain/path'; + storage.setReturnTo(returnTo); + var timeout = 2; + + //mock out helper so we can check progress of redirectTimeout el + var replaceFormWithNotice = pageHelpers.replaceFormWithNotice; + pageHelpers.replaceFormWithNotice = function(selector, cb) { + // mock out 2s network response + setTimeout(function mockedNetwork() { + replaceFormWithNotice.call(this, selector, function intercepted() { + equal(parseInt($('#redirectTimeout').html(), 10), timeout, + 'timeout should not have started countdown yet'); + + //at the end, finish with cb + cb && cb(); + }); + }, (timeout - 1) * 1000); + }; + + var options = _.extend({ redirectTimeout: timeout * 1000 }, config); + createController(options, function() { + // teardown + pageHelpers.replaceFormWithNotice = replaceFormWithNotice; + start(); + }); + }); + }());