diff --git a/resources/static/dialog/controllers/pick_email.js b/resources/static/dialog/controllers/pick_email.js index e68d404a3a7ff1a6941c6c1a1e5ef978c5bf364c..4cdd0a1d376b41637dcb0341e911ab9166774b39 100644 --- a/resources/static/dialog/controllers/pick_email.js +++ b/resources/static/dialog/controllers/pick_email.js @@ -64,10 +64,22 @@ BrowserID.Modules.PickEmail = (function() { return identities; } - function selectEmail(event) { - var target = dom.getAttr(event.currentTarget, "for"); - if(target) { - dom.setAttr("#" + target, "checked", "checked"); + function proxyEventToInput(event) { + // iOS will not select a radio/checkbox button if the user clicks on the + // corresponding label. Because of this, if the user clicks on the label, + // an even is manually fired on the the radio button. This only applies + // if the user clicks on the actual label, not on any input elements + // contained within the label. This restriction is necessary or else we + // would be in a never ending loop that would continually toggle the state + // of any check boxes. + if(dom.is(event.target, "label")) { + // Must prevent standard acting browsers from taking care of the click or + // else it acts like two consecutive clicks. For radio buttons this will + // just toggle state. + event.preventDefault(); + + var target = dom.getAttr(event.target, "for"); + dom.fireEvent("#" + target, event.type); } } @@ -100,7 +112,7 @@ BrowserID.Modules.PickEmail = (function() { // The click function does not pass the event to the function. The event // is needed for the label handler so that the correct radio button is // selected. - self.bind("#selectEmail label", "click", selectEmail); + self.bind("#selectEmail label", "click", proxyEventToInput); sc.start.call(self, options); diff --git a/resources/static/lib/dom-jquery.js b/resources/static/lib/dom-jquery.js index 889d165bf42ce1080d6326e6559431ba148a0d18..860c033277fa2579044a22216426b7ac88bbd8eb 100644 --- a/resources/static/lib/dom-jquery.js +++ b/resources/static/lib/dom-jquery.js @@ -296,6 +296,20 @@ BrowserID.DOM = ( function() { */ focus: function( elementToFocus ) { jQuery( elementToFocus ).focus(); + }, + + /** + * Check the current matched set of elements against + * a selector or element and return true if at least + * one of these elements matches the given arguments. + * @method is + * @param {selector || element} elementToCheck + * @param {string} type + * @returns {boolean} true if elementToCheck matches the specified + * type, false otw. + */ + is: function( elementToCheck, type ) { + return jQuery( elementToCheck ).is( type ); } diff --git a/resources/static/test/cases/controllers/authenticate.js.bak b/resources/static/test/cases/controllers/authenticate.js.bak deleted file mode 100644 index a77ba9c3d829b753c1bcce1feff8aa6e5801f5e5..0000000000000000000000000000000000000000 --- a/resources/static/test/cases/controllers/authenticate.js.bak +++ /dev/null @@ -1,257 +0,0 @@ -/*jshint browsers:true, forin: true, laxbreak: true */ -/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserID: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/. */ -(function() { - "use strict"; - - var controller, - el = $("body"), - bid = BrowserID, - storage = bid.Storage, - network = bid.Network, - xhr = bid.Mocks.xhr, - emailRegistered = false, - userCreated = true, - mediator = bid.Mediator, - registrations = [], - testHelpers = bid.TestHelpers, - register = testHelpers.register, - provisioning = bid.Mocks.Provisioning; - - function reset() { - emailRegistered = false; - userCreated = true; - } - - function createController(options) { - options = options || {}; - controller = bid.Modules.Authenticate.create(); - controller.start(options); - } - - module("controllers/authenticate", { - setup: function() { - reset(); - testHelpers.setup(); - }, - - teardown: function() { - if (controller) { - try { - controller.destroy(); - } catch(e) { - // may already be destroyed from close inside of the controller. - } - } - reset(); - testHelpers.teardown(); - } - }); - - asyncTest("providing primary email address - only show email address", function() { - $("#email").val(""); - createController({ - email: "registered@testuser.com", - type: "primary", - ready: function() { - equal($("#email").val(), "registered@testuser.com", "email prefilled"); - equal(false, "need a test"); - start(); - } - }); - }); - - asyncTest("providing known secondary - show password", function() { - $("#email").val(""); - createController({ - email: "registered@testuser.com", - type: "secondary", - known: true, - ready: function() { - equal($("#email").val(), "registered@testuser.com", "email prefilled"); - equal(false, "need a test"); - start(); - } - }); - }); - - asyncTest("providing unknown secondary address - show email address, nothing more", function() { - $("#email").val(""); - createController({ - email: "unregistered@testuser.com", - type: "secondary", - known: false, - ready: function() { - equal($("#email").val(), "unregistered@testuser.com", "email prefilled"); - equal(false, "need a test"); - start(); - } - }); - }); - - function testUserUnregistered() { - register("create_user", function() { - ok(true, "email was valid, user not registered"); - start(); - }); - - controller.checkEmail(); - } - - function testUserUnregistered() { - var createUserCalled = false; - register("create_user", function() { - createUserCalled = true; - }); - - controller.checkEmail(function() { - equal(createUserCalled, true, "create_user was triggered"); - start(); - }); - } - - asyncTest("checkEmail with unknown secondary email, expect 'create_user' message", function() { - createController(); - $("#email").val("unregistered@testuser.com"); - xhr.useResult("unknown_secondary"); - - testUserUnregistered(); - }); - - asyncTest("checkEmail with email with leading/trailing whitespace, user not registered, expect 'create_user' message", function() { - createController(); - $("#email").val(" unregistered@testuser.com "); - xhr.useResult("unknown_secondary"); - - testUserUnregistered(); - }); - - asyncTest("checkEmail with normal email, user registered, expect 'enter_password' message", function() { - createController(); - $("#email").val("registered@testuser.com"); - xhr.useResult("known_secondary"); - - register("enter_password", function() { - ok(true, "email was valid, user registered"); - start(); - }); - - controller.checkEmail(); - }); - - asyncTest("checkEmail with email that has IdP support, expect 'primary_user' message", function() { - createController(); - $("#email").val("unregistered@testuser.com"); - xhr.useResult("primary"); - - register("primary_user", function(msg, info) { - equal(info.email, "unregistered@testuser.com", "email correctly passed"); - equal(info.auth, "https://auth_url", "IdP authentication URL passed"); - equal(info.prov, "https://prov_url", "IdP provisioning URL passed"); - start(); - }); - - controller.checkEmail(); - }); - - function testAuthenticated() { - register("authenticated", function() { - ok(true, "user authenticated as expected"); - start(); - }); - controller.authenticate(); - } - - asyncTest("normal authentication is kosher", function() { - createController(); - $("#email").val("registered@testuser.com"); - $("#password").val("password"); - - testAuthenticated(); - }); - - asyncTest("leading/trailing whitespace on the username is stripped for authentication", function() { - createController(); - $("#email").val(" registered@testuser.com "); - $("#password").val("password"); - - testAuthenticated(); - }); - - asyncTest("forgotPassword triggers forgot_password message", function() { - createController(); - $("#email").val("registered@testuser.com"); - - register("forgot_password", function(msg, info) { - equal(info.email, "registered@testuser.com", "forgot_password with correct email triggered"); - start(); - }); - - controller.forgotPassword(); - }); - - asyncTest("createUser with valid email", function() { - createController(); - $("#email").val("unregistered@testuser.com"); - xhr.useResult("unknown_secondary"); - - register("user_staged", function(msg, info) { - equal(info.email, "unregistered@testuser.com", "user_staged with correct email triggered"); - start(); - }); - - controller.createUser(); - }); - - asyncTest("createUser with invalid email", function() { - createController(); - $("#email").val("unregistered"); - - var handlerCalled = false; - register("user_staged", function(msg, info) { - handlerCalled = true; - }); - - controller.createUser(function() { - equal(handlerCalled, false, "bad jiji, user_staged should not have been called with invalid email"); - start(); - }); - }); - - asyncTest("createUser with valid email but throttling", function() { - createController(); - $("#email").val("unregistered@testuser.com"); - - var handlerCalled = false; - register("user_staged", function(msg, info) { - handlerCalled = true; - }); - - xhr.useResult("throttle"); - controller.createUser(function() { - equal(handlerCalled, false, "bad jiji, user_staged should not have been called with throttling"); - equal(bid.Tooltip.shown, true, "tooltip is shown"); - start(); - }); - }); - - asyncTest("createUser with valid email, XHR error", function() { - createController(); - $("#email").val("unregistered@testuser.com"); - - var handlerCalled = false; - register("user_staged", function(msg, info) { - handlerCalled = true; - }); - - xhr.useResult("ajaxError"); - controller.createUser(function() { - equal(handlerCalled, false, "bad jiji, user_staged should not have been called with XHR error"); - start(); - }); - }); - -}()); - diff --git a/resources/static/test/cases/controllers/pick_email.js b/resources/static/test/cases/controllers/pick_email.js index 749047ca42b1ceb76c71422acc2d38d58f529235..8a1309a3762046461dfcca4eae65132bcd713947 100644 --- a/resources/static/test/cases/controllers/pick_email.js +++ b/resources/static/test/cases/controllers/pick_email.js @@ -64,7 +64,7 @@ var radioButton = $("input[type=radio]").eq(0); ok(radioButton.is(":checked"), "the email address we specified is checked"); - var label = radioButton.parent(); + var label = $("label[for=" + radioButton.attr("id") + "]"); ok(label.hasClass("preselected"), "the label has the preselected class"); }); @@ -155,16 +155,46 @@ controller.addEmail(); }); - test("click on an email label - select corresponding radio button", function() { + test("click on an email label and radio button - select corresponding radio button", function() { storage.addEmail("testuser@testuser.com", {}); storage.addEmail("testuser2@testuser.com", {}); createController(false); equal($("#testuser_testuser_com").is(":checked"), false, "radio button is not selected before click."); - $("label[for=testuser_testuser_com]").trigger("click"); + // selects testuser@testuser.com + $("label[for=testuser_testuser_com]").trigger("click"); equal($("#testuser_testuser_com").is(":checked"), true, "radio button is correctly selected"); + + // selects testuser2@testuser.com + $("#testuser2_testuser_com").trigger("click"); + equal($("#testuser2_testuser_com").is(":checked"), true, "radio button is correctly selected"); + }); + + test("click on the 'Always sign in...' label and checkbox - correct toggling", function() { + createController(true); + + var label = $("label[for=remember]"), + checkbox = $("#remember").removeAttr("checked"); + + equal(checkbox.is(":checked"), false, "checkbox is not yet checked"); + + // toggle checkbox to on clicking on label + label.trigger("click"); + equal(checkbox.is(":checked"), true, "checkbox is correctly checked"); + + // toggle checkbox to off clicking on label + label.trigger("click"); + equal(checkbox.is(":checked"), false, "checkbox is correctly unchecked"); + + // toggle checkbox to on clicking on checkbox + checkbox.trigger("click"); + equal(checkbox.is(":checked"), true, "checkbox is correctly checked"); + + // toggle checkbox to off clicking on checkbox + checkbox.trigger("click"); + equal(checkbox.is(":checked"), false, "checkbox is correctly unchecked"); }); }());