From 0c31f5c9b59511e4224d4c03e0dd638eae23df45 Mon Sep 17 00:00:00 2001 From: Vicamo Yang Date: Wed, 9 Apr 2014 13:16:04 +0800 Subject: [PATCH] Bug 979134: convert test_mobile_networks.js to Promise. r=hsinyi --- dom/mobileconnection/tests/marionette/head.js | 88 +++++ .../tests/marionette/manifest.ini | 1 - .../tests/marionette/test_mobile_networks.js | 302 ++++++++---------- 3 files changed, 227 insertions(+), 164 deletions(-) diff --git a/dom/mobileconnection/tests/marionette/head.js b/dom/mobileconnection/tests/marionette/head.js index 981086721fd..1ad0debfe52 100644 --- a/dom/mobileconnection/tests/marionette/head.js +++ b/dom/mobileconnection/tests/marionette/head.js @@ -285,6 +285,94 @@ function waitForManagerEvent(aEventName) { return deferred.promise; } +/** + * Get available networks. + * + * Fulfill params: + * An array of nsIDOMMozMobileNetworkInfo. + * Reject params: + * A DOMEvent. + * + * @return A deferred promise. + */ +function getNetworks() { + let request = mobileConnection.getNetworks(); + return wrapDomRequestAsPromise(request) + .then(() => request.result); +} + +/** + * Manually select a network. + * + * Fulfill params: (none) + * Reject params: + * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' + * + * @param aNetwork + * A nsIDOMMozMobileNetworkInfo. + * + * @return A deferred promise. + */ +function selectNetwork(aNetwork) { + let request = mobileConnection.selectNetwork(aNetwork); + return wrapDomRequestAsPromise(request) + .then(null, () => { throw request.error }); +} + +/** + * Manually select a network and wait for a 'voicechange' event. + * + * Fulfill params: (none) + * Reject params: + * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' + * + * @param aNetwork + * A nsIDOMMozMobileNetworkInfo. + * + * @return A deferred promise. + */ +function selectNetworkAndWait(aNetwork) { + let promises = []; + + promises.push(waitForManagerEvent("voicechange")); + promises.push(selectNetwork(aNetwork)); + + return Promise.all(promises); +} + +/** + * Automatically select a network. + * + * Fulfill params: (none) + * Reject params: + * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' + * + * @return A deferred promise. + */ +function selectNetworkAutomatically() { + let request = mobileConnection.selectNetworkAutomatically(); + return wrapDomRequestAsPromise(request) + .then(null, () => { throw request.error }); +} + +/** + * Automatically select a network and wait for a 'voicechange' event. + * + * Fulfill params: (none) + * Reject params: + * 'RadioNotAvailable', 'RequestNotSupported', or 'GenericFailure' + * + * @return A deferred promise. + */ +function selectNetworkAutomaticallyAndWait() { + let promises = []; + + promises.push(waitForManagerEvent("voicechange")); + promises.push(selectNetworkAutomatically()); + + return Promise.all(promises); +} + /** * Set data connection enabling state and wait for "datachange" event. * diff --git a/dom/mobileconnection/tests/marionette/manifest.ini b/dom/mobileconnection/tests/marionette/manifest.ini index 80245848a7f..fb0a64160e9 100644 --- a/dom/mobileconnection/tests/marionette/manifest.ini +++ b/dom/mobileconnection/tests/marionette/manifest.ini @@ -4,7 +4,6 @@ browser = false qemu = true [test_mobile_networks.js] -disabled = Bug 808783 [test_mobile_voice_state.js] [test_mobile_voice_location.js] [test_mobile_operator_names.js] diff --git a/dom/mobileconnection/tests/marionette/test_mobile_networks.js b/dom/mobileconnection/tests/marionette/test_mobile_networks.js index 159c650d660..f1793b7a077 100644 --- a/dom/mobileconnection/tests/marionette/test_mobile_networks.js +++ b/dom/mobileconnection/tests/marionette/test_mobile_networks.js @@ -3,26 +3,16 @@ // getNetworks() can take some time.. MARIONETTE_TIMEOUT = 60000; - -SpecialPowers.addPermission("mobileconnection", true, document); +MARIONETTE_HEAD_JS = "head.js"; -let connection = navigator.mozMobileConnections[0]; -ok(connection instanceof MozMobileConnection, - "connection is instanceof " + connection.constructor); - -is(connection.networkSelectionMode, "automatic"); - -let androidNetwork = null; -let telkilaNetwork = null; - -function isAndroidNetwork(network) { +function isHomeNetwork(network) { is(network.longName, "Android"); is(network.shortName, "Android"); is(network.mcc, "310"); is(network.mnc, "260"); } -function isTelkilaNetwork(network) { +function isRoamingNetwork(network) { is(network.longName, "TelKila"); is(network.shortName, "TelKila"); is(network.mcc, "310"); @@ -30,100 +20,74 @@ function isTelkilaNetwork(network) { } function testConnectionInfo() { - let voice = connection.voice; + log("Validate initial states"); + let voice = mobileConnection.voice; is(voice.connected, true); is(voice.state, "registered"); is(voice.emergencyCallsOnly, false); is(voice.roaming, false); - isAndroidNetwork(voice.network); + isHomeNetwork(voice.network); - let data = connection.data; + let data = mobileConnection.data; // data.connected = true means there's an active data call which we // can't predict here. is(data.state, "registered"); is(data.emergencyCallsOnly, false); is(data.roaming, false); - isAndroidNetwork(data.network); - - testGetNetworks(); + isHomeNetwork(data.network); } function testGetNetworks() { - let request = connection.getNetworks(); - ok(request instanceof DOMRequest, - "request is instanceof " + request.constructor); + log("Enumerating available networks"); + return getNetworks() + .then(function resolve(aNetworks) { + // The emulator RIL server should always return 2 networks: + // {"longName":"Android","shortName":"Android","mcc":310,"mnc":260,"state":"available"} + // {"longName":"TelKila","shortName":"TelKila","mcc":310,"mnc":295,"state":"available"} + is(aNetworks.length, 2); - request.onerror = function() { - ok(false, request.error); - setTimeout(testSelectNetwork, 0); - }; + let network1 = aNetworks[0]; + isHomeNetwork(network1); + is(network1.state, "available"); - request.onsuccess = function() { - ok('result' in request, "Request did not contain a result"); - let networks = request.result; + let network2 = aNetworks[1]; + isRoamingNetwork(network2); + is(network2.state, "available"); - // The emulator RIL server should always return 2 networks: - // {"longName":"Android","shortName":"Android","mcc":310,"mnc":260,"state":"available"} - // {"longName":"TelKila","shortName":"TelKila","mcc":310,"mnc":295,"state":"available"} - is(networks.length, 2); - - let network1 = androidNetwork = networks[0]; - isAndroidNetwork(network1); - is(network1.state, "available"); - - let network2 = telkilaNetwork = networks[1]; - isTelkilaNetwork(network2); - is(network2.state, "available"); - - setTimeout(testSelectNetwork, 0); - }; + return aNetworks; + }); } -function testSelectNetwork() { - let request = connection.selectNetwork(telkilaNetwork); - ok(request instanceof DOMRequest, - "request instanceof " + request.constructor); +function testSelectNetwork(aNetwork, aValidator) { + log("Selecting network '" + aNetwork.longName + "' manually"); + isnot(aNetwork.longName, mobileConnection.voice.network.longName, + "aNetwork.longName"); - connection.addEventListener("voicechange", function voiceChange() { - connection.removeEventListener("voicechange", voiceChange); + return selectNetworkAndWait(aNetwork) + .then(function() { + is(mobileConnection.networkSelectionMode, "manual", + "mobileConnection.networkSelectionMode"); + is(mobileConnection.voice.network.longName, aNetwork.longName, + "mobileConnection.voice.network.longName"); - isTelkilaNetwork(connection.voice.network); - setTimeout(testSelectNetworkAutomatically, 0); - }); - - request.onsuccess = function() { - is(connection.networkSelectionMode, "manual", - "selectNetwork sets mode to: " + connection.networkSelectionMode); - }; - - request.onerror = function() { - ok(false, request.error); - setTimeout(testSelectNetworkAutomatically, 0); - }; + aValidator(mobileConnection.voice.network); + }); } -function testSelectNetworkAutomatically() { - let request = connection.selectNetworkAutomatically(); - ok(request instanceof DOMRequest, - "request instanceof " + request.constructor); +function testSelectNetworkAutomatically(aHomeNetwork, aValidator) { + log("Selecting network '" + aHomeNetwork.longName + "' automatically"); + isnot(aHomeNetwork.longName, mobileConnection.voice.network.longName, + "aHomeNetwork.longName"); - connection.addEventListener("voicechange", function voiceChange() { - connection.removeEventListener("voicechange", voiceChange); + return selectNetworkAutomaticallyAndWait() + .then(function() { + is(mobileConnection.networkSelectionMode, "automatic", + "mobileConnection.networkSelectionMode"); + is(mobileConnection.voice.network.longName, aHomeNetwork.longName, + "mobileConnection.voice.network.longName"); - isAndroidNetwork(connection.voice.network); - setTimeout(testSelectNetworkErrors, 0); - }); - - request.onsuccess = function() { - is(connection.networkSelectionMode, "automatic", - "selectNetworkAutomatically sets mode to: " + - connection.networkSelectionMode); - }; - - request.onerror = function() { - ok(false, request.error); - setTimeout(testSelectNetworkErrors, 0); - }; + aValidator(mobileConnection.voice.network); + }); } function throwsException(fn) { @@ -135,104 +99,116 @@ function throwsException(fn) { } } -function testSelectNetworkErrors() { - throwsException(function() { - connection.selectNetwork(null); - }); +function testSelectNetworkErrors(aNetworkToSelect, aAnotherNetwork) { + throwsException(() => mobileConnection.selectNetwork(null)); + throwsException(() => mobileConnection.selectNetwork({})); - throwsException(function() { - connection.selectNetwork({}); - }); - - connection.addEventListener("voicechange", function voiceChange() { - connection.removeEventListener("voicechange", voiceChange); - setTimeout(testSelectExistingNetworkManual, 0); - }); - - let request1 = connection.selectNetwork(telkilaNetwork); - request1.onerror = function() { - ok(false, request.error); - setTimeout(testSelectExistingNetworkManual, 0); - }; + isnot(aNetworkToSelect.longName, mobileConnection.voice.network.longName, + "aNetworkToSelect.longName"); + let promise = selectNetworkAndWait(aNetworkToSelect); // attempt to selectNetwork while one request has already been sent - throwsException(function() { - connection.selectNetwork(androidNetwork); - }); + throwsException(() => mobileConnection.selectNetwork(aAnotherNetwork)); + + return promise; } -function testSelectExistingNetworkManual() { +function testSelectExistingNetworkManual(aNetwork) { // When the current network is selected again, the DOMRequest's onsuccess // should be called, but the network shouldn't actually change - // Telkila should be the currently selected network - log("Selecting TelKila (should already be selected"); - let request = connection.selectNetwork(telkilaNetwork); + log("Selecting '" + aNetwork.longName + "' manually (should already be selected)"); + is(aNetwork.longName, mobileConnection.voice.network.longName, + "aNetwork.longName"); - let voiceChanged = false; - connection.addEventListener("voicechange", function voiceChange() { - connection.removeEventListener("voicechange", voiceChange); - voiceChanged = true; - }); - - function nextTest() { - // Switch back to automatic selection to setup the next test - let autoRequest = connection.selectNetworkAutomatically(); - autoRequest.onsuccess = function() { - setTimeout(testSelectExistingNetworkAuto, 0); - }; - autoRequest.onerror = function() { - ok(false, autoRequest.error); - cleanUp(); - }; + function voiceChange() { + let network = mobileConnection.voice.network; + if (network.longName !== aNetwork.longName) { + ok(false, "voicechange event emitted while selecting existing '" + + aNetwork.longName + "' manually"); + } } - request.onsuccess = function() { - // Give the voicechange event another opportunity to fire - setTimeout(function() { - is(voiceChanged, false, - "voiceNetwork changed while manually selecting Telkila network? " + - voiceChanged); - nextTest(); - }, 0); - }; + mobileConnection.addEventListener("voicechange", voiceChange); - request.onerror = function() { - ok(false, request.error); - nextTest(); - }; + return selectNetwork(aNetwork) + .then(function resolve() { + let deferred = Promise.defer(); + + // Give the voicechange event another opportunity to fire + setTimeout(function() { + mobileConnection.removeEventListener("voicechange", voiceChange); + deferred.resolve(); + }, 3000); + + return deferred.promise; + }, function reject() { + mobileConnection.removeEventListener("voicechange", voiceChange); + ok(false, "selectNetwork fails"); + }); } -function testSelectExistingNetworkAuto() { +function testSelectExistingNetworkAuto(aHomeNetwork) { // Now try the same thing but using automatic selection - log("Selecting automatically (should already be auto)"); - let request = connection.selectNetworkAutomatically(); + log("Selecting '" + aHomeNetwork.longName + "' automatically (should already be selected)"); + is(aHomeNetwork.longName, mobileConnection.voice.network.longName, + "aHomeNetwork.longName"); - let voiceChanged = false; - connection.addEventListener("voicechange", function voiceChange() { - connection.removeEventListener("voicechange", voiceChange); - voiceChanged = true; - }); + function voiceChange() { + let network = mobileConnection.voice.network; + if (network.longName !== aHomeNetwork.longName) { + ok(false, "voicechange event emitted while selecting existing '" + + aHomeNetwork.longName + "' automatically"); + } + } - request.onsuccess = function() { - // Give the voicechange event another opportunity to fire - setTimeout(function() { - is(voiceChanged, false, - "voiceNetwork changed while automatically selecting network? " + - voiceChanged); - cleanUp(); - }, 0); - }; + mobileConnection.addEventListener("voicechange", voiceChange); - request.onerror = function() { - ok(false, request.error); - cleanUp(); - }; + return selectNetworkAutomatically() + .then(function resolve() { + let deferred = Promise.defer(); + + // Give the voicechange event another opportunity to fire + setTimeout(function() { + mobileConnection.removeEventListener("voicechange", voiceChange); + deferred.resolve(); + }, 3000); + + return deferred.promise; + }, function reject() { + mobileConnection.removeEventListener("voicechange", voiceChange); + ok(false, "selectNetwork fails"); + }); } -function cleanUp() { - SpecialPowers.removePermission("mobileconnection", document); - finish(); -} +startTestCommon(function() { + let promise = Promise.resolve(); + if (mobileConnection.networkSelectionMode != "automatic") { + promise = promise.then(selectNetworkAutomatically); + } -testConnectionInfo(); + return promise + .then(() => testConnectionInfo()) + .then(() => testGetNetworks()) + .then(function(aNetworks) { + let homeNetwork = aNetworks[0], + roamingNetwork = aNetworks[1]; + + // We're initially connected to home network, so let's connect to roaming + // network first. + return testSelectNetwork(roamingNetwork, isRoamingNetwork) + + // Then connect back to home network automatically. + .then(() => testSelectNetworkAutomatically(homeNetwork, isHomeNetwork)) + + // Then try connect to roaming network again. + .then(() => testSelectNetworkErrors(roamingNetwork, homeNetwork)) + + // Roaming network should has been selected, try select it again. + .then(() => testSelectExistingNetworkManual(roamingNetwork)) + + // Switch back to home network and try selecte it again. + .then(() => selectNetworkAutomaticallyAndWait()) + .then(() => testSelectExistingNetworkAuto(homeNetwork)); + }); +});