Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,27 @@
'use strict';
/* jshint node: true, mocha: true */
/* global suiteSetup */
var helper = require('helper');
suite('Costcontrol tests', function() {
suiteSetup(helper.cleanupWorkspace);
teardown(helper.cleanupWorkspace);
test('APP=costcontrol make', function(done) {
helper.exec('APP=costcontrol make', function(error, stdout, stderr) {
helper.checkError(error, stdout, stderr);
var zipPath = process.cwd() +
'/profile/webapps/costcontrol.gaiamobile.org/application.zip';
var checkList = ['manifest.webapp'];
checkList.forEach(function(filePath) {
helper.checkFilePathInZip(zipPath, filePath);
});
done();
});
});
});

View file

@ -0,0 +1,17 @@
{
"extends": "../../../../.jshintrc",
"predef": [
"suite",
"test",
"setup",
"teardown",
"suiteSetup",
"suiteTeardown",
"marionette",
"marionetteScriptFinished",
"require",
"define",
"requireApp",
"sinon"
]
}

View file

@ -0,0 +1,130 @@
/* global require, marionette, setup, suite, test, __dirname */
'use strict';
var assert = require('chai').assert;
var CostControl = require('./lib/costcontrol.js');
marionette('First Time Experience View', function() {
var client = marionette.client({
profile: {
prefs: {
'focusmanager.testmode': true
}
},
desiredCapabilities: { raisesAccessibilityExceptions: false }
});
var costControlApp;
function assertIsNotDisplayed(element) {
assert.isFalse(element.displayed(), 'Element should not be displayed');
}
setup(function() {
costControlApp = CostControl.create(client);
client.contentScript.inject(
__dirname + '/mocks/navigator_moz_icc_manager.js'
);
client.contentScript.inject(
__dirname + '/mocks/navigator_moz_mobile_connections.js'
);
client.contentScript.inject(
__dirname + '/mocks/navigator_moz_network_stats.js'
);
});
suite('Non-configured SIM flow', function() {
setup(function() {
costControlApp.launch();
});
test('Should lead to DataUsage Tab', function() {
var fte = costControlApp.FirstTimeExperience;
fte.switchTo();
client.helper.waitForElement(fte.Welcome.main);
// Go next to Data Report view
fte.next();
client.helper.waitForElement(fte.DataReport.main);
// Go next to Data Alert view
fte.next();
client.helper.waitForElement(fte.DataAlert.main);
// Go next to DataUsageTab
fte.finish();
costControlApp.switchTo();
// Verify that DataUsage tab is active
client.helper.waitForElement(costControlApp.DataUsageTab.main);
assertIsNotDisplayed(fte.frame);
});
});
suite('Pre-configured SIM flow', function() {
setup(function() {
// Make current SIM as pre-configured
client.contentScript.inject(__dirname + '/mocks/configure_icc.js');
costControlApp.launch();
});
test('Should lead to Balance Tab for Prepaid plan', function() {
var fte = costControlApp.FirstTimeExperience;
fte.switchTo();
client.helper.waitForElement(fte.Welcome.main);
// Go next to plan selection
fte.next();
client.helper.waitForElement(fte.TypeOfContract.main);
fte.TypeOfContract.prepaidPlanOption.click();
// Go next to Prepaid low balance alert
fte.next();
client.helper.waitForElement(fte.PrepaidLowBalanceAlert.main);
// Go next to Data Report and Alert
fte.next();
client.helper.waitForElement(fte.PrepaidDataReportAndAlert.main);
// Go to Balance Tab
fte.finish();
costControlApp.switchTo();
// Verify that Balance tab is active
client.helper.waitForElement(costControlApp.BalanceTab.main);
assertIsNotDisplayed(fte.frame);
});
test('Should lead to Telephony Tab for Postpaid plan', function() {
var fte = costControlApp.FirstTimeExperience;
fte.switchTo();
client.helper.waitForElement(fte.Welcome.main);
// Go next to plan selection
fte.next();
client.helper.waitForElement(fte.TypeOfContract.main);
fte.TypeOfContract.postpaidPlanOption.click();
// Go next to Postpaid Phone and Data Report
fte.next();
client.helper.waitForElement(fte.PostPaidPhoneAndDataReport.main);
// Go next to Data Alert
fte.next();
client.helper.waitForElement(fte.PostPaidDataAlert.main);
// Go to Balance Tab
fte.finish();
costControlApp.switchTo();
// Verify that Telephony tab is active
client.helper.waitForElement(costControlApp.TelephonyTab.main);
assertIsNotDisplayed(fte.frame);
});
});
});

View file

@ -0,0 +1,225 @@
/* global module */
(function(module) {
'use strict';
var ORIGIN_URL = 'app://costcontrol.gaiamobile.org';
var SELECTORS = Object.freeze({
DataUsageTab: {
main: '#datausage-tab'
},
BalanceTab: {
main: '#balance-tab'
},
TelephonyTab: {
main: '#telephony-tab'
},
FirstTimeExperience: {
frame: '#fte_view',
main: '#firsttime-view',
nextButton: 'button[data-navigation=next]:not([disabled])',
backButton: 'button[data-navigation=back]',
finishButton: 'button[data-navigation=finish]',
Welcome: {
main: '#step-1'
},
TypeOfContract: {
main: '#step-2',
prepaidPlanOption: '#prepaid-plan',
postpaidPlanOption: '#postpaid-plan'
},
PrepaidLowBalanceAlert: {
main: '#prepaid-step-2'
},
PrepaidDataReportAndAlert: {
main: '#prepaid-step-3'
},
PostpaidPhoneAndDataReport: {
main: '#postpaid-step-2'
},
PostpaidDataAlert: {
main: '#postpaid-step-3'
},
DataReport: {
main: '#non-vivo-step-1'
},
DataAlert: {
main: '#non-vivo-step-2'
}
}
});
module.exports = {
create: function(client) {
return {
BalanceTab: {
get main() {
return client.findElement(SELECTORS.BalanceTab.main);
}
},
DataUsageTab: {
get main() {
return client.findElement(SELECTORS.DataUsageTab.main);
}
},
TelephonyTab: {
get main() {
return client.findElement(SELECTORS.TelephonyTab.main);
}
},
FirstTimeExperience: {
get frame() {
return client.findElement(SELECTORS.FirstTimeExperience.frame);
},
switchTo: function() {
client.switchToFrame(this.frame);
client.helper.waitForElement(SELECTORS.FirstTimeExperience.main);
},
Welcome: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.Welcome.main
);
}
},
TypeOfContract: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.TypeOfContract.main
);
},
get prepaidPlanOption() {
return client.helper.waitForElement(
SELECTORS.FirstTimeExperience.TypeOfContract.prepaidPlanOption
);
},
get postpaidPlanOption() {
return client.helper.waitForElement(
SELECTORS.FirstTimeExperience.TypeOfContract.postpaidPlanOption
);
}
},
PrepaidLowBalanceAlert: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.PrepaidLowBalanceAlert.main
);
}
},
PrepaidDataReportAndAlert: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.PrepaidDataReportAndAlert.main
);
}
},
PostPaidPhoneAndDataReport: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.PostpaidPhoneAndDataReport.main
);
}
},
PostPaidDataAlert: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.PostpaidDataAlert.main
);
}
},
DataReport: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.DataReport.main
);
}
},
DataAlert: {
get main() {
return client.findElement(
SELECTORS.FirstTimeExperience.DataAlert.main
);
}
},
getCurrentViewSelector: function() {
var viewSelectors = [
SELECTORS.FirstTimeExperience.Welcome.main,
SELECTORS.FirstTimeExperience.TypeOfContract.main,
SELECTORS.FirstTimeExperience.PrepaidLowBalanceAlert.main,
SELECTORS.FirstTimeExperience.PrepaidDataReportAndAlert.main,
SELECTORS.FirstTimeExperience.PostpaidPhoneAndDataReport.main,
SELECTORS.FirstTimeExperience.PostpaidDataAlert.main,
SELECTORS.FirstTimeExperience.DataReport.main,
SELECTORS.FirstTimeExperience.DataAlert.main
];
for(var i = 0; i < viewSelectors.length; i++) {
if (client.findElement(viewSelectors[i]).displayed()) {
return viewSelectors[i];
}
}
throw new Error('First Time Experience view is not displayed!');
},
go: function(directionButtonSelector) {
client.helper.waitForElement(
this.getCurrentViewSelector() + ' ' + directionButtonSelector
).tap();
},
next: function() {
this.go(SELECTORS.FirstTimeExperience.nextButton);
},
back: function() {
this.go(SELECTORS.FirstTimeExperience.backButton);
},
finish: function() {
this.go(SELECTORS.FirstTimeExperience.finishButton);
}
},
launch: function() {
client.switchToFrame();
client.apps.launch(ORIGIN_URL);
client.apps.switchToApp(ORIGIN_URL);
},
switchTo: function() {
client.switchToFrame();
client.apps.switchToApp(ORIGIN_URL);
}
};
}
};
})(module);

View file

@ -0,0 +1,22 @@
/* global Components, Services */
'use strict';
const Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView;
Object.defineProperty(window.wrappedJSObject, 'MockIccInfo', {
writable: true,
value: Components.utils.cloneInto({
mcc: '724',
mnc: '6'
}, window)
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,33 @@
/* global Components, Services */
'use strict';
const Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView;
Object.defineProperty(window.wrappedJSObject.navigator, 'mozIccManager', {
configurable: false,
writable: true,
value: Components.utils.cloneInto({
iccIds: ['1234575100210522938'],
getIccById: function(id) {
return Cu.waiveXrays(Cu.cloneInto({
cardState: 'ready',
iccInfo: window.wrappedJSObject.MockIccInfo || {
mcc: '0',
mnc: '0'
},
addEventListener: function() {}
}, window, { cloneFunctions: true }));
}
}, window, { cloneFunctions: true })
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,25 @@
/* global Components, Services */
'use strict';
Components.utils.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView;
var navigator = window.wrappedJSObject.navigator;
Object.defineProperty(navigator, 'mozMobileConnections', {
configurable: false,
writable: true,
value: Components.utils.cloneInto(
navigator.mozIccManager.iccIds.map(function(id) {
return { iccId: id };
}),
window
)
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,159 @@
/* global Components, Services */
'use strict';
const Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Services.obs.addObserver(function(document) {
if (!document || !document.location) {
return;
}
var window = document.defaultView;
var navigator = window.wrappedJSObject.navigator;
var Today = new Date();
var NetworkInterfaceType = {
WIFI: 0,
MOBILE: 1
};
var Networks = new Map([
['0', {
type: NetworkInterfaceType.WIFI,
id: '0'
}]
].concat(navigator.mozIccManager.iccIds.map(function(id) {
return [id, {
type: NetworkInterfaceType.MOBILE,
id: id
}];
})));
var appManifestURLs = ['app://system.gaiamobile.org/manifest.webapp'];
function generateSample(interfaceId, manifestURL, startValueInMb) {
return {
appManifestURL: manifestURL,
network: Networks.get(interfaceId),
start: new Date('2014-08-14T05:00:00.000Z'),
end: new Date('2014-08-31T05:00:00.000Z'),
data: [{
rxBytes: startValueInMb * 100000,
txBytes: (startValueInMb + 100) * 100000,
date: new Date(
Today.getFullYear(),
Today.getMonth(),
Today.getDate() - 15
)
}, {
rxBytes: startValueInMb * 200000,
txBytes: (startValueInMb + 100) * 200000,
date: Today
}]
};
}
const Samples = new Map([
['0', new Map([
[null, generateSample('0', null, 457)],
[appManifestURLs[0], generateSample('0', appManifestURLs[0], 457)]
])],
[navigator.mozIccManager.iccIds[0], new Map([
[null, generateSample(navigator.mozIccManager.iccIds[0], null, 257)],
[
appManifestURLs[0],
generateSample(
navigator.mozIccManager.iccIds[0],
appManifestURLs[0],
257
)
]
])]
]);
var Alarms = new Map();
Object.defineProperty(navigator, 'mozNetworkStats', {
configurable: false,
writable: true,
value: Components.utils.cloneInto({
WIFI: NetworkInterfaceType.WIFI,
getAvailableNetworks: function() {
var returnResult = Cu.waiveXrays(Cu.cloneInto({}, window));
window.setTimeout(function() {
var result = [];
Networks.forEach(function(network) {
result.push(network);
});
returnResult.result = Cu.waiveXrays(Cu.cloneInto(result, window));
if (typeof returnResult.onsuccess === 'function') {
returnResult.onsuccess.call(returnResult);
}
});
return returnResult;
},
getSamples: function getSamples(networkInterface, start, end, options) {
var networkSamples = Samples.get(networkInterface.id);
var returnResult = Cu.waiveXrays(Cu.cloneInto({}, window));
window.setTimeout(function() {
var samples = networkSamples.get(
(options && options.appManifestURL) || null
) || { data: [] };
returnResult.result = Cu.waiveXrays(Cu.cloneInto(
samples, window, { cloneFunctions: true }
));
if (typeof returnResult.onsuccess === 'function') {
returnResult.onsuccess.call(returnResult);
}
});
return returnResult;
},
getAllAlarms: function(interfaceId) {
var returnResult = Cu.waiveXrays(Cu.cloneInto({}, window));
window.setTimeout(function() {
returnResult.result = Cu.waiveXrays(Cu.cloneInto(
Alarms.get(interfaceId) || [], window
));
if (typeof returnResult.onsuccess === 'function') {
returnResult.onsuccess.call(returnResult);
}
});
return returnResult;
},
addAlarm: function(interfaceId, alarm) {
var returnResult = Cu.waiveXrays(Cu.cloneInto({}, window));
window.setTimeout(() => {
var interfaceAlarms = Alarms.get(interfaceId) || [];
interfaceAlarms.push(alarm);
Alarms.set(interfaceId, interfaceAlarms);
if (typeof returnResult.onsuccess === 'function') {
returnResult.onsuccess.call(returnResult);
}
});
return returnResult;
}
}, window, { cloneFunctions: true })
});
}, 'document-element-inserted', false);

View file

@ -0,0 +1,17 @@
{
"extends": "../../../../.jshintrc",
"predef": [
"assert",
"suite",
"test",
"setup",
"teardown",
"suiteSetup",
"suiteTeardown",
"require",
"requireApp",
"sinon",
"mocha",
"loadBodyHTML"
]
}

View file

@ -0,0 +1,93 @@
/* global CostControlApp, MocksHelper */
'use strict';
require('/test/unit/mock_debug.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/test/unit/mock_airplane_mode_helper.js');
require('/test/unit/mock_config_manager.js');
require('/test/unit/mock_cost_control.js');
require('/shared/test/unit/mocks/mock_settings_listener.js');
require('/test/unit/mock_non_ready_screen.js');
require('/shared/test/unit/mocks/mock_accessibility_helper.js');
require('/js/view_manager.js');
require('/js/app.js');
var MocksHelperForUnitTest = new MocksHelper([
'LazyLoader',
'AirplaneModeHelper',
'ConfigManager',
'CostControl',
'SettingsListener',
'NonReadyScreen',
'AccessibilityHelper'
]).init();
suite('Costcontrol App Test Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
suite('_onHashChange >', function() {
suiteSetup(function() {
// This initialization launches a startup to NonReadyScreen screen
// because of a mandatory api does not exists, this way the viewManager is
// initialized, but the app not. This is necessary to avoid the listeners
// to be attached.
CostControlApp.init();
});
suiteTeardown(function() {
CostControlApp.reset();
});
// The URL schema is: #tab-id[#overlay-id]
test('Error bad new url schema.',
function() {
var evt = {
newURL: 'app://usage/index.html###',
oldURL: 'app://usage/index.html#datausage-tab'
};
var previousHash = window.location.hash;
this.sinon.spy(console, 'error');
CostControlApp._onHashChange(evt);
assert.equal(window.location.hash, previousHash);
sinon.assert.called(console.error);
}
);
test('If the new hash does not exist, we maintain the old hash.',
function() {
var evt = {
newURL: 'app://usage/index.html',
oldURL: 'app://usage/index.html#datausage-tab'
};
CostControlApp._onHashChange(evt);
assert.equal(window.location.hash, '#datausage-tab');
}
);
test('Closing settings overlay with # returns to datausage tab.',
function() {
var evt = {
newURL: 'app://usage/index.html#',
oldURL: 'app://usage/index.html#datausage-tab#settings-view'
};
CostControlApp._onHashChange(evt);
assert.equal(window.location.hash, '#datausage-tab');
}
);
test('Openning settings overlay from datausage tab.',
function() {
var evt = {
newURL: 'app://usage/index.html##settings-view',
oldURL: 'app://usage/index.html#datausage-tab'
};
CostControlApp._onHashChange(evt);
assert.equal(window.location.hash, '#datausage-tab#settings-view');
}
);
});
});

View file

@ -0,0 +1,154 @@
/* global BalanceLowLimitView*/
'use strict';
require('/shared/js/component_utils.js');
require('/shared/elements/gaia_switch/script.js');
requireApp('costcontrol/js/views/BalanceLowLimitView.js');
suite('Balance low limit view and validator >', function() {
var ZERO = '0';
var POSITIVE_INTEGER = '1';
var POSITIVE_FLOAT = '1.5';
var NEGATIVE_INTEGER = '-1';
var NEGATIVE_FLOAT = '-1.5';
var EMPTY_STRING = '';
var NON_NUMERIC_VALUE = 'Cthulhu';
var lowLimitEnabler, lowLimitInput, lowLimitView;
setup(function() {
lowLimitEnabler = document.createElement('gaia-switch');
lowLimitInput = document.createElement('INPUT');
lowLimitView = new BalanceLowLimitView(
lowLimitEnabler,
lowLimitInput
);
});
function assertAlwaysValidate() {
[
NEGATIVE_FLOAT,
NEGATIVE_INTEGER,
ZERO,
POSITIVE_INTEGER,
POSITIVE_FLOAT,
EMPTY_STRING,
NON_NUMERIC_VALUE
]
.forEach(function(testValue) {
lowLimitInput.value = testValue;
lowLimitView.validate();
assert.isTrue(lowLimitView._isValid);
});
}
function assertOnlyPositiveValuesAreAccepted() {
[
POSITIVE_INTEGER,
POSITIVE_FLOAT
]
.forEach(function(testValue) {
lowLimitInput.value = testValue;
lowLimitView.validate();
assert.isTrue(lowLimitView._isValid);
});
[
NEGATIVE_FLOAT,
NEGATIVE_INTEGER,
ZERO,
EMPTY_STRING,
NON_NUMERIC_VALUE
]
.forEach(function(testValue) {
lowLimitInput.value = testValue;
lowLimitView.validate();
assert.isFalse(lowLimitView._isValid);
});
}
test(
'Disabling the view disables both components.',
function() {
lowLimitView.disabled = true;
assert.isTrue(lowLimitEnabler.disabled);
assert.isTrue(lowLimitInput.disabled);
}
);
test(
'Enabling the view enables both components.',
function() {
lowLimitView.disabled = false;
assert.isFalse(lowLimitEnabler.disabled);
assert.isFalse(lowLimitInput.disabled);
}
);
test(
'If the component is disabled it always validates.',
function() {
lowLimitView.disabled = true;
assertAlwaysValidate();
}
);
test(
'If the low limit enabler is not checked it always validates.',
function() {
lowLimitEnabler.checked = false;
assertAlwaysValidate();
}
);
test(
'Only validates with positive values.',
function() {
lowLimitView.disabled = false;
lowLimitEnabler.checked = true;
assertOnlyPositiveValuesAreAccepted();
}
);
test(
'Click on the enabler triggers a validation event.',
function(done) {
lowLimitView.disabled = false;
lowLimitEnabler.checked = true;
lowLimitView.onvalidation = function() {
done();
};
lowLimitEnabler.dispatchEvent(new CustomEvent('change'));
}
);
test(
'Changing the input value by user input triggers a validation event.',
function(done) {
lowLimitView.disabled = false;
lowLimitEnabler.checked = true;
lowLimitView.onvalidation = function() {
done();
};
var fakeInputEvent = document.createEvent('Event');
fakeInputEvent.initEvent('input', true, false);
lowLimitInput.dispatchEvent(fakeInputEvent);
}
);
test(
'Enabling / disabling the view triggers a validation event.',
function(done) {
lowLimitView.disabled = false;
lowLimitEnabler.checked = true;
lowLimitView.onvalidation = function() {
done();
};
lowLimitView.disabled = !lowLimitView.disabled;
}
);
});

View file

@ -0,0 +1,166 @@
/* global BalanceView */
'use strict';
requireApp('costcontrol/test/unit/mock_date.js');
requireApp('costcontrol/test/unit/mock_common.js');
requireApp('costcontrol/test/unit/mock_moz_l10n.js');
requireApp('costcontrol/js/utils/toolkit.js');
requireApp('costcontrol/js/utils/formatting.js');
requireApp('costcontrol/js/views/BalanceView.js');
var realDate,realCommon,
realMozL10n;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
suite(
'Balance view (remaining balance and time since last update) >',
function() {
var MINUTE = 60 * 1000,
HOUR = 60 * MINUTE,
DAY = 24 * HOUR,
MINIMUM_DELAY = 3 * HOUR;
var now;
var balanceLabel, timestampLabel, balanceView, balanceResult;
suiteSetup(function() {
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
realCommon = window.Common;
window.Common = new window.MockCommon();
realDate = window.Date;
now = new window.MockDateFactory.realDate(2013, 0, 3, 18);
window.Date = new window.MockDateFactory(now);
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
window.Date = realDate;
window.Common = realCommon;
});
setup(function() {
balanceResult = {
balance: 60,
currency: '$'
};
balanceLabel = document.createElement('p');
timestampLabel = document.createElement('p');
balanceView = new BalanceView(
balanceLabel, timestampLabel, MINIMUM_DELAY);
});
function setBalanceAgeUpTo(age) {
age = Math.floor(age);
balanceResult.timestamp = new Date(now.getTime() - age + MINUTE);
}
function removeMinimumDelay() {
balanceView = new BalanceView(balanceLabel, timestampLabel, 0);
}
function assertTimeElement() {
var timeElement = timestampLabel.children[0];
assert.equal(timeElement.tagName, 'TIME');
assert.equal(timeElement.childElementCount, 0);
}
function assertTimestampHighlight(colorClass) {
var timeElement = timestampLabel.children[0];
assert.equal(timeElement.classList.length, 1);
assert.isTrue(timeElement.classList.contains(colorClass));
}
test(
'Updating mode',
function() {
var isUpdating = true;
balanceResult.timestamp = now;
balanceView.update(balanceResult, isUpdating);
assert.equal(timestampLabel.getAttribute('data-l10n-id'),
'updating-ellipsis');
}
);
test(
'Balance not available',
function() {
balanceView.update(undefined);
assert.equal(balanceLabel.getAttribute('data-l10n-id'),
'not-available');
assert.equal(timestampLabel.innerHTML, '');
}
);
test('MINIMUM_DELAY disabled', function() {
removeMinimumDelay();
setBalanceAgeUpTo(MINIMUM_DELAY / 3);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('first-third');
setBalanceAgeUpTo(2 * MINIMUM_DELAY / 3);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('first-third');
setBalanceAgeUpTo(MINIMUM_DELAY);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('first-third');
});
test('Balance age in the first third of MINIMUM_DELAY', function() {
setBalanceAgeUpTo(MINIMUM_DELAY / 3);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('first-third');
});
test('Balance age in the second third of MINIMUM_DELAY', function() {
setBalanceAgeUpTo(2 * MINIMUM_DELAY / 3);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('second-third');
});
test('Balance age in the third third of MINIMUM_DELAY', function() {
setBalanceAgeUpTo(MINIMUM_DELAY);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('third-third');
});
test('Balance age is yesterday', function() {
setBalanceAgeUpTo(DAY);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('yesterday');
});
test('Balance age is before yesterday', function() {
setBalanceAgeUpTo(2 * DAY);
balanceView.update(balanceResult);
assertTimeElement();
assertTimestampHighlight('before');
});
}
);

View file

@ -0,0 +1,316 @@
/* global ChartUtils, Toolkit, Common, Formatting */
'use strict';
require('/test/unit/mock_date.js');
require('/test/unit/mock_debug.js');
require('/test/unit/mock_moz_l10n.js');
require('/js/common.js');
require('/js/utils/toolkit.js');
require('/js/utils/formatting.js');
require('/js/utils/chart.js');
suite('ChartUtils suite >', function() {
var CHART_BG_RATIO = 0.87;
var DAY = 24 * 60 * 60 * 1000;
var NEVER_PERIOD = 30 * DAY;
var realMozL10n, realDate;
var now;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
suiteSetup(function() {
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
realDate = window.Date;
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
window.Date = realDate;
});
setup(function() {
now = new realDate(2014, 0, 1); // 2014-01-01
window.Date = new window.MockDateFactory(now);
});
test('convert to device pixels', function() {
assert.equal(ChartUtils.toDevicePixels(100), 100 * window.devicePixelRatio);
});
test('make a valid CSS font string', function() {
assert.equal(ChartUtils.makeCSSFontString(10, 'normal'),
'normal 10px sans-serif');
});
test('get data limit in raw bytes', function() {
var mbSettings = {
dataLimitUnit: 'MB',
dataLimitValue: 1
};
var gbSettings = {
dataLimitUnit: 'GB',
dataLimitValue: 1
};
assert.equal(ChartUtils.getLimitInBytes(mbSettings), 1000000);
assert.equal(ChartUtils.getLimitInBytes(gbSettings), 1000000000);
});
test('calculate upper date', function() {
var weeklySettings = {
trackingPeriod: 'weekly',
lastCompleteDataReset: now,
nextReset: new realDate(2014, 0, 8)
};
var monthlySettings = {
trackingPeriod: 'monthly',
lastCompleteDataReset: now,
nextReset: new realDate(2014, 1, 1)
};
var neverSettings = {
trackingPeriod: 'never',
lastCompleteDataReset: now
};
assert.equal(ChartUtils.calculateUpperDate(weeklySettings).toUTCString(),
new realDate(weeklySettings.nextReset.getTime() - DAY).toUTCString());
assert.equal(ChartUtils.calculateUpperDate(monthlySettings).toUTCString(),
new realDate(monthlySettings.nextReset.getTime() - DAY).toUTCString());
assert.equal(ChartUtils.calculateUpperDate(neverSettings).toUTCString(),
new realDate(now.getTime() + NEVER_PERIOD).toUTCString());
});
test('calculate lower date', function() {
var weeklySettings = {
trackingPeriod: 'weekly',
lastCompleteDataReset: now,
nextReset: new realDate(2014, 0, 8)
};
var monthlySettings = {
trackingPeriod: 'monthly',
lastCompleteDataReset: now,
nextReset: new realDate(2014, 1, 1),
resetTime: '1'
};
var neverSettings = {
trackingPeriod: 'never',
lastCompleteDataReset: now
};
assert.equal(ChartUtils.calculateLowerDate(weeklySettings).toUTCString(),
new realDate(now).toUTCString());
assert.equal(ChartUtils.calculateLowerDate(monthlySettings).toUTCString(),
new realDate(now).toUTCString());
assert.equal(ChartUtils.calculateLowerDate(neverSettings).toUTCString(),
new realDate(now).toUTCString());
});
test('calculate lower date when corresponding to the current month',
function() {
var monthlySettings = {
trackingPeriod: 'monthly',
nextReset: new Date(2014, 10, 30),
resetTime: '1'
};
var expectedDate = new Date(2013, 10, 1);
window.Date = new window.MockDateFactory(new Date(2013, 10, 16));
assert.equal(ChartUtils.calculateLowerDate(monthlySettings).toUTCString(),
expectedDate.toUTCString());
});
suite('lower date (monthly -->> resetTime = 31) >', function() {
// The current testing scenarios are the following:
var testCaseList = [
{
// The current and the previous month has 31 days
today: new Date(2014, 0, 1),
nextReset : new Date(2014, 0, 31),
expected : new Date(2013, 11, 31)
}, {
// The current and the previous month has 31 days
// (first day of the period)
today : new Date(2013, 11, 31),
nextReset : new Date(2014, 0, 31),
expected : new Date(2013, 11, 31)
}, {
// the previous month has 31 days, but the current not.
today : new Date(2014, 1, 1),
nextReset : new Date(2014, 1, 28),
expected : new Date(2014, 0, 31)
}, {
// the current month has 31 days, but the previous not.
today : new Date(2014, 4, 1),
nextReset : new Date(2014, 5, 31),
expected : new Date(2014, 3, 30)
}, {
// the current month has 31 days, but the previous not.(February)
today : new Date(2014, 2, 1),
nextReset : new Date(2014, 2, 31),
expected : new Date(2014, 1, 28)
}
];
testCaseList.forEach(function(testCase) {
test('current date is : ' + testCase.today.toUTCString(), function() {
var monthlySettings = {
trackingPeriod: 'monthly',
nextReset: testCase.nextReset,
resetTime: '31'
};
window.Date = new window.MockDateFactory(testCase.today);
assert.equal(
ChartUtils.calculateLowerDate(monthlySettings).toUTCString(),
testCase.expected.toUTCString(),
'LowerDate must be ' + testCase.expected.toUTCString()
);
});
});
});
test('expand the base model with computed values', function() {
var base = {
width: 100,
height: 100,
originX: 15,
endX: 95,
axis: {
X: {
lower: new realDate(2014, 0, 1),
upper: new realDate(2014, 0, 31)
},
Y: {
lower: 0,
margin: 0.20
}
},
limits: {
enabled: true,
value: 10000000 // 10 MB
},
data: {
wifi: {
enabled: true,
total: 0
},
mobile: {
enabled: true,
total: 0
}
},
todayLabel: {}
};
ChartUtils.expandModel(base);
assert.equal(base.originY, Math.floor(base.height * CHART_BG_RATIO));
assert.equal(base.axis.X.today.toUTCString(),
Toolkit.toMidnight(now).toUTCString());
assert.equal(base.axis.X.len, base.endX - base.originX);
assert.equal(typeof base.axis.X.get, 'function');
assert.equal(typeof base.axis.Y.get, 'function');
assert.equal(base.axis.Y.maxValue, Math.max(
base.limits.value, base.data.mobile.total, base.data.wifi.total));
assert.equal(base.axis.Y.upper, (1 + base.axis.Y.margin) *
base.axis.Y.maxValue);
assert.equal(base.axis.Y.step, base.axis.Y.get(base.axis.Y.maxValue));
assert.equal(base.limits.warning, Common.DATA_USAGE_WARNING);
assert.equal(base.limits.warningValue, base.limits.value *
Common.DATA_USAGE_WARNING);
});
suite('accesibility', function() {
var canvas, model, date, upperDate, lowerDate;
function testAcesssibilityAttributes(identifier, data) {
assert.equal(canvas.getAttribute('data-l10n-id'), identifier);
assert.equal(canvas.getAttribute('data-l10n-args'), JSON.stringify(data));
}
setup(function() {
canvas = document.createElement('canvas');
date = new realDate(2014, 0, 15);
lowerDate = new realDate(2014, 0, 1);
upperDate = new realDate(2014, 0, 31);
model = {
axis: {
X: {
get: function() {},
today: date,
lower: lowerDate,
upper: upperDate
},
Y: { get: function() {}, lower: 0, margin: 0.20 }
},
data: {
wifi: { enabled: true, total: 0 },
mobile: { enabled: true, total: 0 }
},
todayLabel: {},
limits: {
enabled: true, value: null, dataLimitValue: 1, dataLimitUnit: 'MB'
}
};
});
test('> drawTodayLayer', function() {
ChartUtils.drawTodayLayer(canvas, model);
testAcesssibilityAttributes('today-layer',
{ today: ChartUtils.formatChartDate(date) });
});
test('> drawAxisLayer', function() {
ChartUtils.drawAxisLayer(canvas, model);
testAcesssibilityAttributes('axis-layer', {
from: ChartUtils.formatChartDate(lowerDate),
to: ChartUtils.formatChartDate(upperDate)
});
});
test('> drawLimits do not display limit', function() {
ChartUtils.drawLimits(canvas, model);
assert.isFalse(canvas.hasAttribute('data-l10n-id'));
assert.isFalse(canvas.hasAttribute('data-l10n-args'));
});
test('> drawLimits MB', function() {
ChartUtils.drawLimits(canvas, model, true);
testAcesssibilityAttributes('limit-layer-MB',
{ value: model.limits.dataLimitValue });
});
test('> drawLimits GB', function() {
model.limits.dataLimitUnit = 'GB';
ChartUtils.drawLimits(canvas, model, true);
testAcesssibilityAttributes('limit-layer-GB',
{ value: model.limits.dataLimitValue });
});
test('> drawWarningLayer do no warning', function() {
ChartUtils.drawWarningLayer(canvas, model);
assert.isFalse(canvas.hasAttribute('data-l10n-id'));
assert.isFalse(canvas.hasAttribute('data-l10n-args'));
});
test('> drawWarningLayer limit warning', function() {
model.limits.value = 10;
model.data.mobile.total = 9;
ChartUtils.drawWarningLayer(canvas, model);
testAcesssibilityAttributes('warning-layer',
{ value: Formatting.formatData(Formatting.roundData(1)) });
});
test('> drawWarningLayer limit exceeded', function() {
model.limits.value = 10;
model.data.mobile.total = 11;
ChartUtils.drawWarningLayer(canvas, model);
testAcesssibilityAttributes('limit-exceeded-layer',
{ value: Formatting.formatData(Formatting.roundData(1)) });
});
});
});

View file

@ -0,0 +1,430 @@
/* global MockAllNetworkInterfaces, Common, MockMozNetworkStats, ConfigManager,
WifiInterfaceType, SimManager, MobileInterfaceType, setNextReset,
Toolkit, MockNavigatormozApps */
'use strict';
require('/test/unit/mock_debug.js');
require('/js/common.js');
require('/js/sim_manager.js');
require('/js/config/config_manager.js');
require('/test/unit/mock_moz_l10n.js');
require('/test/unit/mock_moz_network_stats.js');
require('/js/utils/toolkit.js');
require('/shared/test/unit/mocks/mock_navigator_moz_apps.js');
var realMozL10n,
realMozNetworkStats,
realMozApps;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
if (!window.navigator.mozNetworkStats) {
window.navigator.mozNetworkStats = null;
}
if (!window.navigator.mozApps) {
window.navigator.mozApps = null;
}
suite('Cost Control Common >', function() {
suiteSetup(function() {
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
realMozNetworkStats = window.navigator.mozNetworkStats;
navigator.mozNetworkStats = MockMozNetworkStats;
realMozApps = window.navigator.mozApps;
navigator.mozApps = MockNavigatormozApps;
MockNavigatormozApps.mApps = [{
manifestURL: 'url1',
origin: 'app://app1',
manifest: {
name: 'App 1',
locales: {
'en-US': {
name: 'Localized App 1'
}
},
icons: {
'84': '/path/to/icon_84.png',
'126': '/path/to/icon_126.png',
'142': '/path/to/icon_142.png',
'189': '/path/to/icon_189.png',
'284': '/path/to/icon_284.png'
}
}
}, {
manifestURL: 'url2',
origin: 'app://app2',
manifest: {
name: 'App 2'
}
}];
document.documentElement.lang = 'en-US';
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
window.navigator.mozNetworkStats = realMozNetworkStats;
window.navigator.mozApps = realMozApps;
});
function getCustomClearStats(willFail) {
return function() {
var request = {};
setTimeout(function() {
if (willFail) {
request.error = { name: 'error' };
request.onerror && request.onerror();
} else {
request.result = {};
request.onsuccess && request.onsuccess();
}
}, 0);
return request;
};
}
function getSuccessfullClearStats() {
return getCustomClearStats(false);
}
function getFailingClearStats() {
return getCustomClearStats(true);
}
test('loadNetworkInterfaces correctly', function(done) {
Common.loadNetworkInterfaces(
function() {
assert.isTrue(Common.allNetworkInterfaceLoaded);
assert.equal(Common.allNetworkInterfaces.length,
MockAllNetworkInterfaces.length);
assert.equal(Common.allNetworkInterfaces[0].type, WifiInterfaceType);
assert.equal(Common.allNetworkInterfaces[1].type, MobileInterfaceType);
assert.equal(Common.allNetworkInterfaces[1].id,
MockAllNetworkInterfaces[1].id);
done();
}
);
});
test('loadApps correctly filtering apps', function(done) {
Common.specialApps = ['url1'];
Common.allAppsLoaded = false;
Common.loadApps().then(function(apps) {
done(function() {
assert.isTrue(Common.allAppsLoaded);
assert.equal(apps.length, 2);
assert.equal(apps[0].manifestURL, 'url2');
});
});
});
test('loadApps correctly', function(done) {
Common.specialApps = [];
Common.allAppsLoaded = false;
Common.loadApps().then(function(apps) {
done(function() {
assert.isTrue(Common.allAppsLoaded);
assert.equal(apps.length, 3);
assert.equal(apps[0].manifestURL, 'url1');
assert.equal(apps[1].manifestURL, 'url2');
});
});
});
test('loadApps load Browser App', function(done) {
Common.specialApps = [];
Common.allAppsLoaded = false;
Common.loadApps().then(function(apps) {
done(function() {
assert.isTrue(Common.allAppsLoaded);
assert.isTrue(apps.includes(Common.BROWSER_APP));
});
});
});
test('getApp by manifestURL correctly', function() {
var app1 = Common.getApp('url1');
var app2 = Common.getApp('url2');
assert.equal(app1, MockNavigatormozApps.mApps[0]);
assert.equal(app2, MockNavigatormozApps.mApps[1]);
});
test('getAppManifest by app correctly', function() {
var app1 = Common.getApp('url1');
var app2 = Common.getApp('url2');
var appManifest1 = Common.getAppManifest(app1);
var appManifest2 = Common.getAppManifest(app2);
assert.equal(appManifest1, app1.manifest);
assert.equal(appManifest2, app2.manifest);
});
test('getLocalizedAppName by app correctly', function() {
var app1 = Common.getApp('url1');
var app2 = Common.getApp('url2');
var localizedAppName1 = Common.getLocalizedAppName(app1);
var localizedAppName2 = Common.getLocalizedAppName(app2);
assert.equal(localizedAppName1, 'Localized App 1');
// Should fallback to un-localized app name in the app
// manifest if a localized name is not available.
assert.equal(localizedAppName2, 'App 2');
});
test('getAppIcon by app correctly', function() {
var app1 = Common.getApp('url1');
var app2 = Common.getApp('url2');
var appIcon1 = Common.getAppIcon(app1);
var appIcon2 = Common.getAppIcon(app2);
assert.equal(appIcon1, 'app://app1/path/to/icon_84.png');
// Should fallback to generic app icon if one is not available.
assert.equal(appIcon2, '../style/images/app/icons/default.png');
});
suite('Reset Data>', function() {
suiteSetup(function() {
sinon.stub(SimManager, 'requestDataSimIcc', function(callback) {
(typeof callback === 'function') &&
callback({iccId: Common.allNetworkInterfaces[1].id});
});
sinon.stub(ConfigManager, 'setOption', function() {});
sinon.stub(ConfigManager, 'requestSettings', function() {});
});
suiteTeardown(function() {
SimManager.requestDataSimIcc.restore();
ConfigManager.setOption.restore();
ConfigManager.requestSettings.restore();
});
test('resetData() wifi interface', function(done) {
sinon.stub(MockMozNetworkStats, 'clearStats', getSuccessfullClearStats());
Common.loadNetworkInterfaces(function() {
Common.resetData('wifi', function() {
assert.isTrue(MockMozNetworkStats.clearStats.calledOnce);
assert.isTrue(MockMozNetworkStats.clearStats
.calledWith(Common.allNetworkInterfaces[0]));
MockMozNetworkStats.clearStats.restore();
done();
});
});
});
test('resetData() mobile interface', function(done) {
sinon.stub(MockMozNetworkStats, 'clearStats', getSuccessfullClearStats());
Common.loadNetworkInterfaces(function() {
Common.resetData('mobile', function() {
assert.isTrue(MockMozNetworkStats.clearStats.calledOnce);
assert.isTrue(MockMozNetworkStats.clearStats
.calledWith(Common.allNetworkInterfaces[1]));
MockMozNetworkStats.clearStats.restore();
done();
});
});
});
test('resetData() all interfaces', function(done) {
sinon.stub(MockMozNetworkStats, 'clearStats', getSuccessfullClearStats());
Common.loadNetworkInterfaces(function() {
Common.resetData('all', function() {
assert.isTrue(MockMozNetworkStats.clearStats.calledTwice);
MockMozNetworkStats.clearStats.restore();
done();
});
});
});
test('resetData() wifi interface fails', function(done) {
sinon.stub(MockMozNetworkStats, 'clearStats', getFailingClearStats());
Common.loadNetworkInterfaces(function() {
Common.resetData('wifi', function() {}, function _onError() {
assert.isTrue(MockMozNetworkStats.clearStats.calledOnce);
MockMozNetworkStats.clearStats.restore();
done();
});
});
});
test('resetData() all interfaces fail', function(done) {
sinon.stub(MockMozNetworkStats, 'clearStats', getFailingClearStats());
var testOk = function() {
if (MockMozNetworkStats.clearStats.calledTwice) {
MockMozNetworkStats.clearStats.restore();
done();
}
};
Common.loadNetworkInterfaces(function() {
Common.resetData('all', function() {
setTimeout(testOk, 500);
});
});
});
});
suite('localizeWeekdaySelector>', function() {
var domForTesting, l10nStub;
setup(function() {
domForTesting = document.createElement('div');
domForTesting.innerHTML = '<select id="select-weekday">' +
'<option class="monday" value="1">Monday</option>' +
'<option value="2" >Tuesday</option>' +
'<option value="3">Wednesday</option>' +
'<option value="4">Thursday</option>' +
'<option value="5">Friday</option>' +
'<option value="6">Saturday</option>' +
'<option class="sunday" value="0">Sunday</option>' +
'</select>';
document.body.appendChild(domForTesting);
l10nStub = this.sinon.stub(navigator.mozL10n, 'get');
});
suiteTeardown(function() {
domForTesting.parentNode.removeChild(domForTesting);
});
test('localizeWeekdaySelector - week starts on sunday', function() {
l10nStub.withArgs('firstDayOfTheWeek').returns('0');
Common.localizeWeekdaySelector(domForTesting);
var monday = domForTesting.querySelector('.monday');
var weekdayList = monday.parentNode;
assert.isTrue(weekdayList.childNodes[0].classList.contains('sunday'));
});
test('localizeWeekdaySelector - week starts on monday', function() {
l10nStub.withArgs('firstDayOfTheWeek').returns('1');
Common.localizeWeekdaySelector(domForTesting);
var monday = domForTesting.querySelector('.monday');
var weekdayList = monday.parentNode;
assert.isTrue(weekdayList.childNodes[0].classList.contains('monday'));
});
});
suite('closeFTE>', function() {
var fteFrame;
setup(function() {
fteFrame = document.createElement('iframe');
fteFrame.id = 'fte_view';
window.parent.document.body.appendChild(fteFrame);
});
suiteTeardown(function() {
fteFrame.parentNode.removeChild(fteFrame);
});
test('FTE iframe is hidden after call closeFTE method', function() {
assert.isFalse(fteFrame.classList.contains('non-ready'));
Common.closeFTE();
assert.isTrue(fteFrame.classList.contains('non-ready'));
});
});
suite('updated nextReset>', function() {
setup(function() {
this.sinon.stub(window, 'setNextReset');
});
suiteTeardown(function() {
});
test('tracking period is never', function() {
Common.updateNextReset('never', 0, 'trakingPeriodNever');
sinon.assert.called(setNextReset);
sinon.assert.calledWith(setNextReset, null, 'trakingPeriodNever');
});
test('nextReset is updated to the next 3th when the monthly tracking ' +
'period is selected', function() {
var monthday = 3;
var today = new Date();
var month = today.getMonth();
var year = today.getFullYear();
if (today.getDate() >= monthday) {
month = (month + 1) % 12;
if (month === 0) {
year++;
}
}
var nextReset = new Date(year, month, monthday);
Common.updateNextReset('monthly', monthday, 'trackingPeriodMonthly');
// Check the method setNextReset is called with the correct parameters:
// the next day of the month since today.
sinon.assert.called(setNextReset);
sinon.assert.calledWith(setNextReset, nextReset, 'trackingPeriodMonthly');
});
test('nextReset is updated to the next third day of the next week when ' +
'the weekly tracking period is selected', function() {
var today = new Date();
var oneDay = 24 * 60 * 60 * 1000;
var weekday = 3;
var daysToTarget = weekday - today.getDay();
if (daysToTarget <= 0) {
daysToTarget = 7 + daysToTarget;
}
var nextReset = new Date();
nextReset.setTime(nextReset.getTime() + oneDay * daysToTarget);
Toolkit.toMidnight(nextReset);
Common.updateNextReset('weekly', weekday, 'trackingPeriodWeekly');
// Check the method setNextReset is called with the correct parameters:
// the next weekday since today.
sinon.assert.called(setNextReset);
sinon.assert.calledWith(setNextReset, nextReset, 'trackingPeriodWeekly');
});
});
suite('getDataLimit>', function() {
test('getDataLimit', function() {
var settings = {
dataLimitUnit : 'MB',
dataLimitValue : 7
};
assert.equal(Common.getDataLimit(settings), 7000000);
settings.dataLimitUnit = 'GB';
assert.equal(Common.getDataLimit(settings), 7000000000);
});
});
suite('Reset All>', function() {
test('reset All works ok when call to resetData', function() {
this.sinon.stub(Common, 'resetData', function (mode, onSuccess, onError) {
onSuccess();
});
this.sinon.stub(window, 'resetTelephony', function() {});
Common.resetAll();
sinon.assert.called(window.resetTelephony);
});
test('reset All fails when call to resetData', function() {
// If reset Data fails, then abort completely the process. Do not try to
// call resetTelephony method
this.sinon.stub(Common, 'resetData', function (mode, onSuccess, onError) {
onError();
});
this.sinon.stub(window, 'resetTelephony', function() {});
Common.resetAll();
sinon.assert.notCalled(window.resetTelephony);
});
});
});

View file

@ -0,0 +1,134 @@
/* global SimManager, LazyLoader, asyncStorage, ConfigManager, MocksHelper*/
'use strict';
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/shared/test/unit/mocks/mock_async_storage.js');
require('/test/unit/mock_debug.js');
require('/js/utils/toolkit.js');
require('/js/sim_manager.js');
require('/js/config/config_manager.js');
var MocksHelperForUnitTest = new MocksHelper([
'asyncStorage',
'LazyLoader'
]).init();
suite('Config Manager Test Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
var defaultConfig = { provider: 'default'};
var vivoConfig = { provider: 'vivo' };
function simulateSIMChange() {
ConfigManager.setConfig(null);
}
setup(function() {
this.sinon.stub(LazyLoader, 'getJSON')
.withArgs('/js/config/index.json')
.returns(Promise.resolve({'724_6': 'vivo', '123_4': 'testing'}));
this.sinon.stub(LazyLoader, 'load', function(fileName, callback) {
if (fileName === 'js/config/default/config.js') {
ConfigManager.setConfig(defaultConfig);
} else {
ConfigManager.setConfig(vivoConfig);
}
(typeof callback === 'function') && callback();
});
this.sinon.stub(asyncStorage, 'getItem').yields({});
simulateSIMChange();
});
test('After switching the simcard with the same carrier, a configuration is' +
' loaded',
function(done) {
var iccForTesting = {
iccId: 1234,
iccInfo: {
mcc:'724',
mnc:'6'
}
};
this.sinon.stub(SimManager, 'requestDataSimIcc')
.yields({ icc: iccForTesting });
ConfigManager.requestAll(function(configuration, settings) {
assert.deepEqual(configuration, vivoConfig);
simulateSIMChange();
// Loading the config for the "new Sim detected" (same carrier)
ConfigManager.requestAll(function(configuration, settings) {
// Checking if a configuration is loaded
assert.isNotNull(configuration);
done();
});
});
});
test('Switching the simcard with the same carrier, a valid configuration ' +
'is loaded (testing cache behaviour)',
function(done) {
var iccForTesting = {
iccId: 1234,
iccInfo: {
mcc:'123',
mnc:'4'
}
};
this.sinon.stub(SimManager, 'requestDataSimIcc')
.yields({ icc: iccForTesting });
ConfigManager.requestAll(function(configuration, settings) {
assert.deepEqual(configuration, vivoConfig);
assert.isTrue(LazyLoader.load.calledOnce);
simulateSIMChange();
// Force the config reload (second time)
ConfigManager.requestAll(function(configuration, settings) {
assert.isTrue(LazyLoader.load.calledOnce);
assert.deepEqual(configuration, vivoConfig);
done();
});
});
});
test(' Loading an non-existent configuration defaults in default config',
function(done) {
var iccForTesting = {
iccId: 1234,
iccInfo: {
mcc:'214',
mnc:'07'
}
};
this.sinon.stub(SimManager, 'requestDataSimIcc')
.yields({ icc: iccForTesting });
ConfigManager.requestAll(function(configuration, settings) {
assert.deepEqual(configuration, defaultConfig);
done();
});
});
test(' Load a valid configuration', function(done) {
var iccForTesting = {
iccId: 1234,
iccInfo: {
mcc:'724',
mnc:'6'
}
};
this.sinon.stub(SimManager, 'requestDataSimIcc')
.yields({ icc: iccForTesting });
ConfigManager.requestAll(function(configuration, settings) {
assert.deepEqual(configuration, vivoConfig);
done();
});
});
});

View file

@ -0,0 +1,85 @@
'use strict';
require('/test/unit/mock_common.js');
require('/test/unit/mock_moz_l10n.js');
require('/js/views/ConfirmDialog.js');
require('/js/view_manager.js');
/* global ConfirmDialog, ViewManager */
var realCommon, realMozL10n;
if (!window.Common) {
window.Common = null;
}
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
suite('Confirm Dialog test suite >', function() {
var screen, vManager;
var container, buttonContainer, okButton, cancelButton, header, message;
suiteSetup(function() {
realCommon = window.Common;
window.Common = new window.MockCommon();
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
});
suiteTeardown(function() {
window.Common = realCommon;
window.navigator.mozL10n = realMozL10n;
});
setup(function() {
buttonContainer = document.createElement('div');
header = document.createElement('h1');
message = document.createElement('p');
okButton = document.createElement('button');
okButton.classList.add('danger');
cancelButton = document.createElement('button');
cancelButton.classList.add('close-reset-dialog');
buttonContainer.appendChild(okButton);
buttonContainer.appendChild(cancelButton);
container = document.createElement('div');
container.appendChild(header);
container.appendChild(message);
container.appendChild(buttonContainer);
container.id = 'test';
vManager = new ViewManager();
screen = new ConfirmDialog(container, vManager);
});
test('setMessageMode() shows the message localized', function() {
var expectedMessage = 'Expected message';
screen.setMessage(expectedMessage);
assert.strictEqual(message.textContent, expectedMessage);
});
test('updateAcceptAction() changes the accept button behaviour', function() {
assert.isNull(okButton.onclick);
var expectedFunction = function() {};
screen.updateAcceptAction(expectedFunction);
assert.strictEqual(okButton.onclick, expectedFunction);
});
test('closeConfirmDialog() closes view', function() {
this.sinon.spy(vManager, 'closeCurrentView');
screen.closeConfirmDialog();
sinon.assert.calledOnce(vManager.closeCurrentView);
});
test('showConfirmDialog() changes the view', function() {
this.sinon.stub(vManager, 'changeViewTo', function() {});
screen.showConfirmDialog();
sinon.assert.calledWith(vManager.changeViewTo, container.id);
});
});

View file

@ -0,0 +1,581 @@
/* global MockCommon, MocksHelper, MockConfigManager, Common, SimManager,
MockMozNetworkStats, MockNavigatorMozMobileConnections, CostControl
*/
'use strict';
require('/test/unit/mock_debug.js');
require('/test/unit/mock_common.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/test/unit/mock_airplane_mode_helper.js');
require('/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js');
require('/test/unit/mock_config_manager.js');
require('/test/unit/mock_moz_network_stats.js');
require('/js/utils/toolkit.js');
require('/js/sim_manager.js');
require('/js/costcontrol.js');
var realMozNetworkStats,
realMozMobileConnections;
if (!window.navigator.mozMobileConnections) {
window.navigator.mozMobileConnections = null;
}
if (!window.navigator.mozNetworkStats) {
window.navigator.mozNetworkStats = null;
}
var MocksHelperForUnitTest = new MocksHelper([
'AirplaneModeHelper',
'Common',
'ConfigManager',
'LazyLoader'
]).init();
suite('Cost Control Service Hub Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
suiteSetup(function() {
window.Common = new MockCommon({});
realMozMobileConnections = navigator.mozMobileConnections;
window.navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
realMozNetworkStats = window.navigator.mozNetworkStats;
navigator.mozNetworkStats = MockMozNetworkStats;
});
suiteTeardown(function() {
window.navigator.mozMobileConnections = realMozMobileConnections;
window.navigator.mozNetworkStats = realMozNetworkStats;
});
teardown(function() {
CostControl.reset();
});
function setupDelaySinceLastBalance(lastBalanceRequest, delay,
applicationMode) {
applicationMode = applicationMode || 'PREPAID';
MockNavigatorMozMobileConnections[0] = {
voice: { connected: true, relSignalStrength: 60 },
data: {}
};
window.ConfigManager = new MockConfigManager({
applicationMode: applicationMode,
fakeConfiguration: {
balance: {
minimum_delay: delay
},
is_free: true,
is_roaming_free: false
},
fakeSettings: {
lastBalanceRequest: lastBalanceRequest
}
});
}
function setupInsufficentDelaySinceLastBalance() {
var age = 60 * 1000;
var lastBalanceRequest = new Date();
lastBalanceRequest.setTime(lastBalanceRequest.getTime() - age);
var delay = age * 2;
setupDelaySinceLastBalance(lastBalanceRequest, delay);
}
function setupEnoughDelaySinceLastBalance(applicationMode) {
var age = 60 * 1000;
var lastBalanceRequest = new Date();
lastBalanceRequest.setTime(lastBalanceRequest.getTime() - age);
var delay = Math.floor(age / 2);
setupDelaySinceLastBalance(lastBalanceRequest, delay, applicationMode);
}
function setupNonFreeMessage() {
var age = 60 * 1000;
var lastBalanceRequest = new Date();
lastBalanceRequest.setTime(lastBalanceRequest.getTime() - age);
var delay = Math.floor(age / 2);
MockNavigatorMozMobileConnections[0] = {
voice: { connected: true, relSignalStrength: 60 },
data: {}
};
window.ConfigManager = new MockConfigManager({
applicationMode: 'PREPAID',
fakeConfiguration: {
balance: {
minimum_delay: delay
},
is_free: false,
is_roaming_free: false
},
fakeSettings: {
lastBalanceRequest: lastBalanceRequest
}
});
}
function setupWaitingForRequest() {
var age = 60 * 1000;
var lastRequest = new Date();
lastRequest.setTime(lastRequest.getTime() - age);
var delay = Math.floor(age / 2);
MockNavigatorMozMobileConnections[0] = {
voice: { connected: true, relSignalStrength: 60 },
data: {}
};
window.ConfigManager = new MockConfigManager({
applicationMode: 'PREPAID',
fakeConfiguration: {
balance: {
minimum_delay: delay
},
is_free: true,
is_roaming_free: false
},
fakeSettings: {
lastBalanceRequest: lastRequest,
lastTopUpRequest: lastRequest,
waitingForTopUp: true,
waitingForBalance: true
}
});
}
test(
'Balance requests fail when not enough delay since the last request',
function(done) {
setupInsufficentDelaySinceLastBalance();
CostControl.getInstance(function(service) {
service.request({type: 'balance'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'minimum_delay');
done();
});
});
}
);
test(
'Balance requests doesn\'t fail if enough delay since the last request',
function(done) {
setupEnoughDelaySinceLastBalance();
CostControl.getInstance(function(service) {
service.request({type: 'balance'}, function(result) {
assert.notEqual(result.details, 'minimum_delay');
done();
});
});
}
);
test(
'Balance requests fail when not signal is detected',
function(done) {
setupEnoughDelaySinceLastBalance();
MockNavigatorMozMobileConnections[0] = {
voice: { connected: true, relSignalStrength: null },
data: {}
};
CostControl.getInstance(function(service) {
service.request({type: 'balance'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'no_coverage');
done();
});
});
}
);
test(
'Balance requests fail when not exist voice service',
function(done) {
setupEnoughDelaySinceLastBalance();
MockNavigatorMozMobileConnections[0] = {
data: {}
};
CostControl.getInstance(function(service) {
service.request({type: 'balance'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'no_service');
done();
});
});
}
);
test(
'Balance requests fail when applicationMode is not PREPAID',
function(done) {
setupEnoughDelaySinceLastBalance('POSTPAID');
CostControl.getInstance(function(service) {
service.request({type: 'balance'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'no_service');
done();
});
});
}
);
test(
'Balance requests fail when message is not free',
function(done) {
setupNonFreeMessage();
CostControl.getInstance(function(service) {
service.request({type: 'balance'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'non_free');
done();
});
});
}
);
test(
'Balance requests fail when roaming msg is not free',
function(done) {
setupEnoughDelaySinceLastBalance();
MockNavigatorMozMobileConnections[0] = {
voice: {
connected: true,
relSignalStrength: 60,
roaming: true
},
data: {}
};
CostControl.getInstance(function(service) {
service.request({type: 'balance'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'non_free_in_roaming');
done();
});
});
}
);
test(
'TopUp requests does not fail when is waiting for TopUp',
function(done) {
setupWaitingForRequest();
CostControl.getInstance(function(service) {
service.request({type: 'topup'}, function(result) {
assert.equal(result.status, 'in_progress');
done();
});
});
}
);
test(
'TopUp requests fail when not exist voice service',
function(done) {
setupEnoughDelaySinceLastBalance();
MockNavigatorMozMobileConnections[0] = {
data: {}
};
CostControl.getInstance(function(service) {
service.request({type: 'topup'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'no_service');
done();
});
});
}
);
test(
'TopUp requests fail when applicationMode is not PREPAID',
function(done) {
setupEnoughDelaySinceLastBalance('POSTPAID');
CostControl.getInstance(function(service) {
service.request({type: 'topup'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'no_service');
done();
});
});
}
);
test(
'TopUp requests fail when roaming msg is not free',
function(done) {
setupEnoughDelaySinceLastBalance();
MockNavigatorMozMobileConnections[0] = {
voice: {
connected: true,
relSignalStrength: 60,
roaming: true
},
data: {}
};
CostControl.getInstance(function(service) {
service.request({type: 'topup'}, function(result) {
assert.equal(result.status, 'error');
assert.equal(result.details, 'non_free_in_roaming');
done();
});
});
}
);
test(
'Get dataUsage correctly',
function(done) {
sinon.stub(SimManager, 'requestDataSimIcc', function (callback) {
(typeof callback === 'function') && callback({iccId:'12345'});
});
CostControl.getInstance(function(service) {
service.request({type: 'datausage'}, function(result) {
assert.equal(result.status, 'success');
assert.equal(result.data.wifi.total, 112123944);
assert.equal(result.data.mobile.total, 4800543137);
assert.equal(Object.keys(result.data.mobile.apps).length, 0);
SimManager.requestDataSimIcc.restore();
done();
});
});
}
);
test(
'Get dataUsage without simcard interface',
function(done) {
sinon.stub(Common, 'getDataSIMInterface').returns(undefined);
sinon.stub(SimManager, 'requestDataSimIcc', function (callback) {
(typeof callback === 'function') && callback({iccId:'12345'});
});
CostControl.getInstance(function(service) {
service.request({type: 'datausage'}, function(result) {
assert.equal(result.status, 'success');
assert.equal(result.data.wifi.total, 112123944);
assert.equal(result.data.mobile.total, 0);
Common.getDataSIMInterface.restore();
SimManager.requestDataSimIcc.restore();
done();
});
});
}
);
test(
'Get dataUsage without network interfaces',
function(done) {
sinon.stub(Common, 'getDataSIMInterface').returns(undefined);
sinon.stub(Common, 'getWifiInterface').returns(undefined);
sinon.stub(SimManager, 'requestDataSimIcc', function (callback) {
(typeof callback === 'function') && callback({iccId:'12345'});
});
CostControl.getInstance(function(service) {
service.request({type: 'datausage'}, function(result) {
assert.equal(result.status, 'success');
assert.equal(result.data.wifi.total, 0);
assert.equal(result.data.mobile.total, 0);
Common.getDataSIMInterface.restore();
Common.getWifiInterface.restore();
SimManager.requestDataSimIcc.restore();
done();
});
});
}
);
test(
'Get dataUsage works with date parameters',
function(done) {
var startDate = new Date(2012, 11, 20);
var endDate = new Date(2013, 0, 7);
var requestParameters =
{type: 'datausage', startDate: startDate, endDate: endDate};
this.sinon.stub(SimManager, 'requestDataSimIcc', function (callback) {
(typeof callback === 'function') && callback({iccId:'12345'});
});
this.sinon.spy(window.navigator.mozNetworkStats, 'getSamples');
CostControl.getInstance(function(service) {
service.request(requestParameters, function(result) {
done(function() {
sinon.assert.calledWith(window.navigator.mozNetworkStats.getSamples,
Common.getWifiInterface(), startDate, endDate);
});
});
});
}
);
test(
'Get dataUsage when start date is higher than end date',
function(done) {
var startDate = new Date(2012, 11, 20);
var endDate = new Date(2012, 11, 13);
var endDateExpected = new Date(2012, 11, 21);
var requestParameters =
{type: 'datausage', startDate: startDate, endDate: endDate};
this.sinon.stub(SimManager, 'requestDataSimIcc', function (callback) {
(typeof callback === 'function') && callback({iccId:'12345'});
});
this.sinon.spy(window.navigator.mozNetworkStats, 'getSamples');
CostControl.getInstance(function(service) {
service.request(requestParameters, function(result) {
done(function() {
sinon.assert.calledWith(window.navigator.mozNetworkStats.getSamples,
Common.getWifiInterface(), startDate, endDateExpected);
});
});
});
}
);
test(
'Get datausage per app',
function(done) {
var expectedLastDataUsage = {
mobile: { total: 10000, apps: {} },
wifi: { total: 20000, apps: {} }
};
var fakeSettings = { lastDataUsage: expectedLastDataUsage };
sinon.stub(SimManager, 'requestDataSimIcc', function (callback) {
(typeof callback === 'function') && callback({iccId:'12345'});
});
window.ConfigManager = new MockConfigManager({
fakeSettings: fakeSettings
});
CostControl.getInstance(function(service) {
var manifests = [MockMozNetworkStats.APP_MANIFEST_1,
MockMozNetworkStats.APP_MANIFEST_2];
service.request({type: 'datausage', apps: manifests}, function(result) {
assert.equal(result.status, 'success');
assert.equal(Object.keys(result.data.mobile.apps).length, 2);
var apps = result.data.mobile.apps;
var app1 = apps[MockMozNetworkStats.APP_MANIFEST_1];
var app2 = apps[MockMozNetworkStats.APP_MANIFEST_2];
assert.equal(app1.total, 1047);
assert.equal(app2.total, 2268);
assert.equal(result.data.mobile.total, app1.total + app2.total);
assert.equal(
fakeSettings.lastDataUsage.mobile.total,
expectedLastDataUsage.mobile.total
);
SimManager.requestDataSimIcc.restore();
done();
});
});
}
);
test(
'Get datausage per app shows browser App',
function(done) {
var expectedLastDataUsage = {
mobile: { total: 10000, apps: {} },
wifi: { total: 20000, apps: {} }
};
var fakeSettings = { lastDataUsage: expectedLastDataUsage };
this.sinon.stub(SimManager, 'requestDataSimIcc', function (callback) {
(typeof callback === 'function') && callback({iccId:'12345'});
});
window.ConfigManager = new MockConfigManager({
fakeSettings: fakeSettings
});
CostControl.getInstance(function(service) {
var manifests = [MockMozNetworkStats.APP_MANIFEST_1,
Common.BROWSER_APP.manifestURL];
service.request({type: 'datausage', apps: manifests}, function(result) {
assert.equal(result.status, 'success');
assert.equal(Object.keys(result.data.mobile.apps).length, 2);
var apps = result.data.mobile.apps;
var app1 = apps[MockMozNetworkStats.APP_MANIFEST_1];
var browserApp = apps[Common.BROWSER_APP.manifestURL];
assert.equal(app1.total, 1047);
assert.equal(browserApp.total, 595);
assert.equal(result.data.mobile.total, app1.total + browserApp.total);
assert.equal(
fakeSettings.lastDataUsage.mobile.total,
expectedLastDataUsage.mobile.total
);
done();
});
});
}
);
test('Querying data usage globally caches the result', function(done) {
this.sinon.stub(SimManager, 'requestDataSimIcc').yields({iccId: '12345'});
CostControl.getInstance(function(service) {
var lastDataUsagePerApp = {};
service.lastDataUsagePerApp = lastDataUsagePerApp;
service.request({type: 'datausage'}, function(result) {
done(function() {
assert.deepEqual(service.lastDataResults, result.data);
assert.deepEqual(service.lastDataResultsPerApp, lastDataUsagePerApp);
});
});
});
});
test(
'Data cache per App is refreshed after a request per App',
function(done) {
this.sinon.stub(SimManager, 'requestDataSimIcc').yields({iccId: '12345'});
CostControl.getInstance(function(service) {
// Request per app
var manifests = [MockMozNetworkStats.APP_MANIFEST_1,
MockMozNetworkStats.APP_MANIFEST_2];
var lastDataUsage = {};
service.lastDataUsage = lastDataUsage;
service.request({type: 'datausage', apps: manifests}, function(result) {
done(function() {
assert.deepEqual(service.lastDataResultsPerApp, result.data);
assert.deepEqual(service.lastDataResults, lastDataUsage);
});
});
});
}
);
});

View file

@ -0,0 +1,231 @@
/* global Formatting, Toolkit */
'use strict';
requireApp('costcontrol/test/unit/mock_moz_l10n.js');
requireApp('costcontrol/js/utils/toolkit.js');
requireApp('costcontrol/js/utils/formatting.js');
var realMozL10n;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
suite('Formatting Test Suite >', function() {
suiteSetup(function() {
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
});
function assertSmartRound(roundedValue, value, unit) {
assert.equal(roundedValue[0], value);
assert.equal(roundedValue[1], unit);
}
function assertRoundData(roundedValue, value, unit) {
assert.equal(roundedValue[0], value);
assert.equal(roundedValue[1], unit);
}
function createDOMForTesting() {
var markup =
'<section id="testing-formatTimeHTML">' +
'<div id="only-date1"></div>' +
'<div id="only-date2"></div>' +
'<div id="both-dates"></div>' +
'<div id="both-dates-changed"></div>' +
'<div id="same-dates"></div>' +
'</section>';
document.body.innerHTML = markup;
}
test(
'Get decimal positions test behaviour without delta argument.',
function() {
var getPositions = Formatting.getPositions;
assert.isTrue(getPositions(1.345) === 2);
assert.isTrue(getPositions(1.3) === 2);
assert.isTrue(getPositions(1) === 0);
assert.isTrue(getPositions(97) === 0);
assert.isTrue(getPositions(99.34) === 1);
assert.isTrue(getPositions(103.39) === 0);
assert.isTrue(getPositions(1021.3) === 0);
}
);
test(
'Get decimal positions test behaviour with delta argument.',
function() {
var getPositions = Formatting.getPositions;
// Positive
assert.isTrue(getPositions(1.345, 1) === 3);
assert.isTrue(getPositions(1.3, 1) === 3);
assert.isTrue(getPositions(1, 1) === 0);
assert.isTrue(getPositions(99.34, 1) === 2);
assert.isTrue(getPositions(103.39, 1) === 0);
// Negative
assert.isTrue(getPositions(1.345, -1) === 1);
assert.isTrue(getPositions(1.3, -1) === 1);
assert.isTrue(getPositions(1, -1) === 0);
assert.isTrue(getPositions(99.34, -1) === 0);
assert.isTrue(getPositions(103.39, -1) === 0);
}
);
test(
'SmartRound() test behaviour without delta argument.',
function() {
var f = Formatting;
assert.equal(assertSmartRound(f.smartRound(1.345), 1.34, 'B'));
assert.equal(assertSmartRound(f.smartRound(1.3), 1.30, 'B'));
assert.equal(assertSmartRound(f.smartRound(1), 1, 'B'));
assert.equal(assertSmartRound(f.smartRound(97), 97, 'B'));
assert.equal(assertSmartRound(f.smartRound(99.34), 99.3, 'B'));
assert.equal(assertSmartRound(f.smartRound(103.39), 103, 'B'));
assert.equal(assertSmartRound(f.smartRound(1021.8), 1.02, 'KB'));
assert.equal(assertSmartRound(f.smartRound(3431021.8), 3.43, 'MB'));
assert.equal(assertSmartRound(f.smartRound(3431021000.8), 3.43, 'GB'));
}
);
test(
'SmartRound() test behaviour with delta argument.',
function() {
var f = Formatting;
// Positive
assert.equal(assertSmartRound(f.smartRound(1.349, 1), 1.349, 'B'));
assert.equal(assertSmartRound(f.smartRound(1.3, 1), 1.300, 'B'));
assert.equal(assertSmartRound(f.smartRound(1, 1), 1, 'B'));
assert.equal(assertSmartRound(f.smartRound(99.34, 1), 99.34, 'B'));
assert.equal(assertSmartRound(f.smartRound(103.39, 1), 103, 'B'));
// Negative
assert.equal(assertSmartRound(f.smartRound(1.345, -1), 1.3, 'B'));
assert.equal(assertSmartRound(f.smartRound(1, -1), 1, 'B'));
assert.equal(assertSmartRound(f.smartRound(99.34, -1), 99, 'B'));
assert.equal(assertSmartRound(f.smartRound(103.39, -1), 103, 'B'));
}
);
test(
'roundData() test behaviour.',
function() {
var f = Formatting;
assert.equal(assertRoundData(f.roundData(1.349, 1), 1.3, 'B'));
assert.equal(assertRoundData(f.roundData(1.3, 2), 1.30, 'B'));
assert.equal(assertRoundData(f.roundData(1, 2), 1, 'B'));
assert.equal(assertRoundData(f.roundData(97, 2), 97, 'B'));
assert.equal(assertRoundData(f.roundData(99.346, 2), 99.35, 'B'));
assert.equal(assertRoundData(f.roundData(103.39, 1), 103.4, 'B'));
assert.equal(assertRoundData(f.roundData(1021.8, 2), 1.02, 'KB'));
assert.equal(assertRoundData(f.roundData(3431021.8, 2), 3.43, 'MB'));
assert.equal(assertRoundData(f.roundData(8431021000.8, 2), 8.43, 'GB'));
}
);
test(
'formatTime() test behaviour.',
function() {
var f = Formatting;
var today = Toolkit.toMidnight(new Date());
var MINUTE = 60 * 1000;
var yesterday = Toolkit.toMidnight(new Date(today.getTime() - MINUTE));
var oneTuesday = Toolkit.toMidnight(new Date(2014, 1, 25));
assert.equal(f.formatTime(), 'never');
f.formatTime(oneTuesday, f.formatters.shortWeekday);
assert.ok(f.formatTime(today).includes('today'));
assert.ok(f.formatTime(yesterday).includes('yesterday, '));
}
);
test(
'formatData() test behaviour.',
function() {
var data = [25, 'MB'];
assert.equal(Formatting.formatData(['x']), '');
assert.equal(Formatting.formatData(data), '25 MB');
}
);
test(
'formatTimeSinceNow() test behaviour.',
function() {
var f = Formatting;
var now = new Date();
var MINUTE = 60 * 1000;
var HOUR = 60 * MINUTE;
var aFewMinutesAgo = new Date(now.getTime() - 25 * MINUTE);
var aFewHoursAgo = new Date(now.getTime() - 15 * HOUR);
assert.equal(f.formatTimeSinceNow(now), 'just now');
assert.equal(f.formatTimeSinceNow(aFewMinutesAgo), '25m ago');
assert.equal(f.formatTimeSinceNow(aFewHoursAgo), '15h ago');
}
);
test(
'computeTelephonyMinutes() test behaviour.',
function() {
var f = Formatting;
// Less than one minute
var activity = { calltime: 100 };
assert.ok(f.computeTelephonyMinutes(activity) === 1);
// One minute
activity = { calltime: 60000 };
assert.ok(f.computeTelephonyMinutes(activity) === 1);
// One minute and one second
activity = { calltime: 60001 };
assert.ok(f.computeTelephonyMinutes(activity) > 1);
}
);
test(
'formatTimeHTML() test behaviour.',
function() {
var DAY = 24 * 60 * 60 * 1000;
var date1 = new Date(2014, 1, 25);
var date2 = new Date(date1.getTime() + (DAY * 5));
var body = document.body.innerHTML;
createDOMForTesting();
function assertformatTimeHTML(htmlId, initialDate, finalDate) {
var fragment = document.getElementById(htmlId);
fragment.appendChild(
Formatting.formatTimeHTML(initialDate, finalDate));
var timeElement = fragment.getElementsByTagName('time');
if (finalDate && (initialDate !== finalDate)) {
assert.equal(timeElement[1].innerHTML,
Formatting.formatTime(finalDate));
assert.equal(timeElement[0].innerHTML,
Formatting.formatTime(
initialDate,Formatting.formatters.shortDate
));
} else {
assert.equal(timeElement[0].innerHTML,
Formatting.formatTime(initialDate));
}
}
assertformatTimeHTML('only-date1', date1);
assertformatTimeHTML('only-date2', date2);
assertformatTimeHTML('both-dates', date1, date2);
assertformatTimeHTML('both-dates-changed', date2, date1);
assertformatTimeHTML('same-dates', date2, date2);
document.body.innerHTML = body;
}
);
});

View file

@ -0,0 +1,259 @@
/* global MockCommon, AutoSettings, MockConfigManager,
MocksHelper, SimManager
*/
'use strict';
require('/test/unit/mock_moz_l10n.js');
require('/test/unit/mock_config_manager.js');
require('/test/unit/mock_debug.js');
require('/js/utils/toolkit.js');
require('/test/unit/mock_common.js');
require('/shared/js/component_utils.js');
require('/shared/elements/gaia_radio/script.js');
require('/shared/test/unit/load_body_html_helper.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/js/views/BalanceLowLimitView.js');
require('/js/settings/limitdialog.js');
require('/js/utils/formatting.js');
require('/js/view_manager.js');
require('/js/settings/autosettings.js');
require('/js/sim_manager.js');
require('/js/fte.js');
var realMozL10n;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
var MocksHelperForUnitTest = new MocksHelper([
'ConfigManager',
'Common',
'LazyLoader'
]).init();
suite('FTE Test Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
var fteWizard;
var autoSettingsSpy;
suiteSetup(function() {
window.Common = new MockCommon();
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
sinon.stub(SimManager, 'requestDataSimIcc', function(callback) {
(typeof callback === 'function') && callback({});
});
sinon.stub(SimManager, 'isMultiSim').returns(false);
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
SimManager.requestDataSimIcc.restore();
SimManager.isMultiSim.restore();
});
setup(function() {
autoSettingsSpy = sinon.spy(AutoSettings, 'initialize');
});
teardown(function() {
autoSettingsSpy.restore();
parent.postMessage.restore();
window.location.hash = '';
});
function setupApplicationMode(applicationMode, fakeConfiguration) {
loadBodyHTML('/fte.html#' + applicationMode);
fteWizard = document.getElementById('firsttime-view');
window.ConfigManager = new MockConfigManager({
fakeConfiguration: fakeConfiguration,
fakeSettings: {
fte: true,
dataLimitValue: 40,
dataLimitUnit: 'MB',
lowLimit: true
},
applicationMode: applicationMode
});
}
function setupPrepaidMode() {
var fakeConfiguration = {
default_low_limit_threshold: 3,
credit: { currency: 'R$' }
};
setupApplicationMode('PREPAID', fakeConfiguration);
}
function setupPostPaidMode() {
var fakeConfiguration = {};
setupApplicationMode('POSTPAID', fakeConfiguration);
}
function setupDataUsageOnlyMode() {
var fakeConfiguration = {
};
setupApplicationMode('DATA_USAGE_ONLY', fakeConfiguration);
}
// When the FTE loaded, initLazyFTE() sends message to the parent window
// with type: 'fte_ready'.
function assetWhenFTEIsFinished(assertingFunction, done) {
sinon.stub(parent, 'postMessage', function(data, targetOrigin) {
if (data.hasOwnProperty('type') && data.type == 'fte_ready') {
assertingFunction(autoSettingsSpy);
done();
}
});
}
function assertDataUsageOnlyInit(autoSettingsSpy) {
assert.equal(fteWizard.dataset.steps, 3);
assert.equal(autoSettingsSpy.getCall(0).args[2], '#non-vivo-step-1');
}
function assertNoDataUsageOnlyInit(autoSettingsSpy) {
assert.equal(fteWizard.dataset.steps, 4);
assert.ok(autoSettingsSpy.calledOnce);
assert.equal(autoSettingsSpy.getCall(0).args[2], '#step-1');
assert.ok(document.getElementById('to-step-2').disabled);
}
function assertNavigationForward(autoSettingsSpy, stepsForward) {
var currentScreen =
document.querySelector('[role=region]:not([data-viewport])');
stepsForward.forEach(function(step) {
var buttonNext = currentScreen.querySelector('[data-navigation=next]');
if (buttonNext) {
triggerEvent(buttonNext, 'click');
}
// update currentScreen after press button next
currentScreen =
document.querySelector('[role=region]:not([data-viewport])');
assert.equal(currentScreen.id, step);
});
}
function assertNavigationBackward(autoSettingsSpy, stepsBackward) {
var currentScreen =
document.querySelector('[role=region]:not([data-viewport])');
stepsBackward.forEach(function(step) {
var buttonBack = currentScreen.querySelector('[data-navigation=back]');
if (buttonBack) {
triggerEvent(buttonBack, 'click');
}
// update currentScreen after press button next
currentScreen =
document.querySelector('[role=region]:not([data-viewport])');
assert.equal(currentScreen.id, step);
});
}
function assertDataUsageOnlyNavigationForward(autoSettingsSpy) {
var dataStepsForward = ['non-vivo-step-1', 'non-vivo-step-2'];
assertNavigationForward(autoSettingsSpy, dataStepsForward);
}
function assertDataUsageOnlyNavigationBackward(autoSettingsSpy) {
var dataStepsForward = ['non-vivo-step-1', 'non-vivo-step-2'];
assertNavigationForward(autoSettingsSpy, dataStepsForward);
var dataStepsBackward = ['non-vivo-step-1', 'step-1'];
assertNavigationBackward(autoSettingsSpy, dataStepsBackward);
}
function assertPrepaidNavigationForward(autoSettingsSpy) {
var prepaidStepsForward = ['prepaid-step-2', 'prepaid-step-3'];
var currentScreen = document.getElementById('step-1');
var buttonNext = currentScreen.querySelector('[data-navigation=next]');
triggerEvent(buttonNext, 'click');
assert.isTrue(document.getElementById('to-step-2').disabled);
triggerEvent(document.getElementById('prepaid-plan'), 'click');
assert.isFalse(document.getElementById('to-step-2').disabled);
document.getElementById('low-limit-input').value = 40;
assertNavigationForward(autoSettingsSpy, prepaidStepsForward);
}
function assertPostpaidNavigationForward(autoSettingsSpy) {
var postpaidStepsForward = ['postpaid-step-2', 'postpaid-step-3'];
var currentScreen = document.getElementById('step-1');
var buttonNext = currentScreen.querySelector('[data-navigation=next]');
triggerEvent(buttonNext, 'click');
assert.isTrue(document.getElementById('to-step-2').disabled);
triggerEvent(document.getElementById('postpaid-plan'), 'click');
assert.isFalse(document.getElementById('to-step-2').disabled);
document.getElementById('low-limit-input').value = 40;
assertNavigationForward(autoSettingsSpy, postpaidStepsForward);
}
function triggerEvent(element, eventName) {
var event = document.createEvent('HTMLEvents');
event.initEvent(eventName, true, true);
element.dispatchEvent(event);
}
function initFTE() {
var event = new CustomEvent('DOMContentLoaded');
window.dispatchEvent(event);
}
test('DATA_USAGE_ONLY mode initialized correctly', function(done) {
setupDataUsageOnlyMode();
assetWhenFTEIsFinished(assertDataUsageOnlyInit, done);
initFTE();
});
test('PREPAID mode initialized correctly', function(done) {
setupPrepaidMode();
assetWhenFTEIsFinished(assertNoDataUsageOnlyInit, done);
initFTE();
});
test('POSTPAID mode initialized correctly', function(done) {
setupPostPaidMode();
assetWhenFTEIsFinished(assertNoDataUsageOnlyInit, done);
initFTE();
});
test('DATA_USAGE_ONLY mode navigates forward', function(done) {
setupDataUsageOnlyMode();
assetWhenFTEIsFinished(assertDataUsageOnlyNavigationForward, done);
initFTE();
});
test('DATA_USAGE_ONLY mode navigates backward', function(done) {
setupDataUsageOnlyMode();
assetWhenFTEIsFinished(assertDataUsageOnlyNavigationBackward, done);
initFTE();
});
test('PREPAID mode navigates forward', function(done) {
setupPrepaidMode();
assetWhenFTEIsFinished(assertPrepaidNavigationForward, done);
initFTE();
});
test('POSTPAID mode navigates forward', function(done) {
setupPostPaidMode();
assetWhenFTEIsFinished(assertPostpaidNavigationForward, done);
initFTE();
});
});

View file

@ -0,0 +1,198 @@
/* global IACManager , MockNavigatormozSetMessageHandler, VivoConfig */
'use strict';
require('/js/utils/debug.js');
require('/js/iac_manager.js');
require('/shared/test/unit/mocks/mock_navigator_moz_set_message_handler.js');
require('/js/config/vivo/config.js');
suite('IAC Manager', function() {
suite('IAC Manager > Message generator', function() {
teardown(function() {
IACManager._reset();
});
test('Enabling SilentMode for balance', function() {
IACManager.init(VivoConfig);
var serviceType = 'balance';
var msg = IACManager._generateMsg(serviceType, 'enable');
assert.equal(msg.type, serviceType);
assert.equal(msg.action, 'enable');
assert.isTrue(Array.isArray(msg.smsNumbers));
});
test('getSmsNumberList includes all balance numbers', function() {
IACManager.init(VivoConfig);
var smsToSilent = IACManager._getSmsNumberList('balance');
var smsSenders = VivoConfig.balance.senders;
// Check if all senders are included on the smsToSilent List
smsSenders.forEach(function (sender) {
assert.include(smsToSilent, sender);
});
// Check if the destination number included on the smsToSilent List
assert.include(smsToSilent, VivoConfig.balance.destination);
});
test('getSmsNumberList includes all topup numbers', function() {
// Testing when the destination number is not in the sender list
VivoConfig.topup.destination = 7777;
IACManager.init(VivoConfig);
var smsToSilent = IACManager._getSmsNumberList('topup');
var smsSenders = VivoConfig.topup.senders;
// Check if all senders are included on the smsToSilent List
smsSenders.forEach(function (sender) {
assert.include(smsToSilent, sender);
});
// Check if the destination number included on the smsToSilent List
assert.include(smsToSilent, VivoConfig.topup.destination);
});
});
suite('IAC Manager > broadcastStartOfSMSQuery', function() {
teardown(function() {
IACManager._reset();
});
test('broadcastStartOfSMSQuery calls _sendBroadcastMessage with the' +
' correct arguments', function(done) {
IACManager.init(VivoConfig);
var msg = IACManager._generateMsg('balance', 'enable');
this.sinon.stub(IACManager, '_sendBroadcastMessage', function() {
sinon.assert.calledWith(IACManager._sendBroadcastMessage, msg);
done();
});
IACManager.broadcastStartOfSMSQuery('balance');
});
});
suite('IAC Manager > broadcastEndOfSMSQuery', function() {
teardown(function() {
IACManager._reset();
});
test('broadcastStartOfSMSQuery calls _sendBroadcastMessage with the' +
' correct arguments', function(done) {
IACManager.init(VivoConfig);
var msg = IACManager._generateMsg('topup', 'disable');
this.sinon.stub(IACManager, '_sendBroadcastMessage', function() {
sinon.assert.calledWith(IACManager._sendBroadcastMessage, msg);
done();
});
IACManager.broadcastEndOfSMSQuery('topup');
});
});
suite('IAC Manager > Broadcasting messages ', function() {
var realMozSetMessageHandler,
realMozApps;
var FakePort = function() {};
FakePort.prototype.onmessage = function(cb) {
cb();
};
FakePort.prototype.postMessage = function(e) {
this.onmessage();
};
suiteSetup(function() {
realMozSetMessageHandler = navigator.mozSetMessageHandler;
navigator.mozSetMessageHandler = MockNavigatormozSetMessageHandler;
MockNavigatormozSetMessageHandler.mSetup();
realMozApps = navigator.mozApps;
});
function setupMozAppBehaviour(willFail) {
var app = {
connect: function() {
return this;
},
then: function(onConnection, onRejection) {
if (!willFail) {
var fakePort = new FakePort();
(typeof onConnection === 'function') && onConnection([fakePort]);
} else {
(typeof onRejection === 'function') && onRejection('error');
}
}
};
navigator.mozApps = {
getSelf: function() {
return {
set onsuccess(callback) {
callback({
target: {
result: app
}
});
}
};
}
};
}
suiteTeardown(function() {
navigator.mozSetMessageHandler = realMozSetMessageHandler;
MockNavigatormozSetMessageHandler.mTeardown();
navigator.mozApps = realMozApps;
});
test('_sendBroadcastMessage > send the message correctly', function(done) {
IACManager.init(VivoConfig);
this.sinon.spy(window, 'clearTimeout');
setupMozAppBehaviour(false);
var msg = IACManager._generateMsg('balance', 'enable');
IACManager._sendBroadcastMessage(msg)
.then(function() {
sinon.assert.called(window.clearTimeout);
done();
}, function() {
assert.ok(false);
done();
});
});
test('_sendBroadcastMessage > can not connect', function(done) {
IACManager.init(VivoConfig);
setupMozAppBehaviour(true);
var msg = IACManager._generateMsg('balance', 'enable');
IACManager._sendBroadcastMessage(msg)
.then(function() {
assert.ok(false);
done();
},function() {
done();
});
});
test('_sendBroadcastMessage > fails by timeout', function(done) {
IACManager.init(VivoConfig);
this.sinon.stub(FakePort.prototype, 'onmessage', function(){});
this.sinon.stub(window, 'setTimeout', function (callback) {
callback();
});
setupMozAppBehaviour(false);
var msg = IACManager._generateMsg('balance', 'enable');
IACManager._sendBroadcastMessage(msg)
.then(function() {
assert.ok(false);
done();
},function() {
sinon.assert.calledOnce(window.setTimeout);
done();
});
});
});
});

View file

@ -0,0 +1,24 @@
/* exported MockAirplaneModeHelper */
'use strict';
var MockAirplaneModeHelper = {
_enabled: false,
_status: 'disabled',
_callbacks: [],
setEnabled: function(enabled) {
this._status = enabled ? 'enabled' : 'disabled';
this._enabled = enabled;
},
ready: function(cb) {
if (cb) {
cb();
}
},
// Mock with your own status setting mocks' property _status
getStatus: function() {
return this._status;
},
addEventListener: function(callback) {
this._callbacks.push(callback);
}
};

View file

@ -0,0 +1,11 @@
/* exported MockAllNetworkInterfaces */
'use strict';
var WifiInterfaceType = 0;
var MobileInterfaceType = 1;
var MockAllNetworkInterfaces = [
{'type': WifiInterfaceType, 'id': '0'},
{'type': MobileInterfaceType, 'id': '8100075100210526976'},
{'type': MobileInterfaceType, 'id': '1234575100210522938'},
{'type': MobileInterfaceType, 'id': '1234575100210511223'}
];

View file

@ -0,0 +1,113 @@
/* global MockAllNetworkInterfaces, Common */
/* exported MockCommon */
'use strict';
requireApp('costcontrol/test/unit/mock_all_network_interfaces.js');
var MockCommon = function(config) {
config = config || {};
var allInterfacesFake = MockAllNetworkInterfaces;
return {
COST_CONTROL_APP: 'app://costcontrol.gaiamobile.org',
BROWSER_APP: {
manifestURL: 'app://browser.gaiamobile.org/manifest.webapp',
origin: '',
manifest: {
icons: {
'84': '/shared/resources/branding/browser_84.png'
},
name: 'browser'
}
},
SYSTEM_MANIFEST: 'app://system.gaiamobile.org/manifest.webapp',
allNetworkInterfaces: {},
localize: function (element, label, args) {
element.textContent = label;
},
waitForDOMAndMessageHandler: function(window, callback) {
callback();
},
startFTE: function(mode) {
var iframe = document.getElementById('fte_view');
iframe.classList.remove('non-ready');
if (config && config.activateFTEListener) {
window.addEventListener('dataSlotChange', function _onDataSimChange() {
window.removeEventListener('dataSlotChange', _onDataSimChange);
// Close FTE if change the SimCard for data connections
Common.closeFTE();
});
}
var event = new CustomEvent('ftestarted', { detail: mode });
window.dispatchEvent(event);
},
closeFTE: function() {
var iframe = document.getElementById('fte_view');
iframe.classList.add('non-ready');
var event = new CustomEvent('fteClosed');
window.dispatchEvent(event);
},
startApp: function() {
var event = new CustomEvent('appstarted');
window.dispatchEvent(event);
},
closeApplication: function() {
var event = new CustomEvent('appclosed');
window.dispatchEvent(event);
},
modalAlert: function(msg) {
var event = new CustomEvent('fakealert', { detail: msg });
window.dispatchEvent(event);
console.log('Alert: ' + msg);
},
getDataSIMInterface: function getDataSIMInterface(iccId) {
var dataSimCard = allInterfacesFake[1];
return dataSimCard;
},
getWifiInterface: function() {
var wifiInterface = allInterfacesFake[0];
return wifiInterface;
},
loadNetworkInterfaces: function(onsuccess, onerror) {
setTimeout(function() {
Common.allNetworkInterfaces = allInterfacesFake;
(typeof onsuccess === 'function') && onsuccess();
}, 0);
},
loadDataSIMIccId: function(onsuccess, onerror) {
setTimeout(function() {
Common.dataSimIccId = allInterfacesFake[1].id;
if (typeof onsuccess === 'function') {
onsuccess(Common.dataSimIccId);
}
}, 0);
},
localizeWeekdaySelector: function _localizeWeekdaySelector(selector) {
var weekStartsOnMonday =
parseInt(navigator.mozL10n.get('firstDayOfTheWeek'), 10) === 1;
var monday = selector.querySelector('.monday');
var sunday = selector.querySelector('.sunday');
var list = monday.parentNode;
if (weekStartsOnMonday) {
list.insertBefore(monday, list.childNodes[0]); // monday is the first
list.appendChild(sunday); // sunday is the last
} else {
list.insertBefore(sunday, list.childNodes[0]); // sunday is the first
list.insertBefore(monday, sunday.nextSibling); // monday is the second
}
},
getDataLimit: function _getDataLimit(settings) {
var multiplier = (settings.dataLimitUnit === 'MB') ?
1000000 : 1000000000;
return settings.dataLimitValue * multiplier;
},
updateNextReset: function() {},
resetData : function() {}
};
};

View file

@ -0,0 +1,86 @@
/* exported MockConfigManager */
'use strict';
var MockConfigManager = function(config) {
config = config || {};
Date.prototype.toJSON = function() {
return {'__date__': this.toISOString()};
};
function settingsReviver(k, v) {
if (v === null || typeof v !== 'object' || !v.hasOwnProperty('__date__')) {
return v;
}
return new Date(v.__date__);
}
function getMockRequiredMessage(mocking, parameter, isAFunction) {
var whatIsBeingAccesed = mocking + (isAFunction ? '() is being called' :
'is being accessed');
return 'Please, ' + whatIsBeingAccesed + '. Provide the key `' +
parameter + '` in the constructor config object to mock it.';
}
var fakeSettings = config.fakeSettings || {};
var fakeConfiguration = config.fakeConfiguration || {};
var mCallbacks = {};
return {
option: function(key, value) {
if (value) {
fakeSettings[key] = value;
}
return fakeSettings[key];
},
requestAll: function(callback) {
var self = this;
self.requestConfiguration(function(configuration) {
self.requestSettings(undefined, function(settings) {
callback(configuration, settings);
});
});
},
requestConfiguration: function(callback) {
callback(fakeConfiguration);
},
requestSettings: function(iccId, callback) {
callback(JSON.parse(JSON.stringify(fakeSettings), settingsReviver));
},
setOption: function(options, callback) {
Object.keys(options).forEach(function (name) {
fakeSettings[name] = options[name];
});
(typeof callback === 'function') && callback();
},
observe: function(name, callback, avoidInitialCall) {
if (typeof mCallbacks[name] !== 'function') {
mCallbacks[name] = [];
}
mCallbacks[name] = callback;
},
getApplicationMode: function() {
assert.isDefined(
config.applicationMode,
getMockRequiredMessage('getApplicationMode', 'applicationMode', true)
);
return config.applicationMode;
},
get configuration() { return config; },
mTriggerCallback: function(name, value, settings) {
if (typeof mCallbacks[name] === 'function') {
if (settings === undefined) {
settings = fakeSettings;
}
mCallbacks[name](value, null, name, settings);
}
},
mRemoveObservers: function() {
mCallbacks = {};
},
setConfig: function(newConfig) {
config = newConfig;
},
supportCustomizeMode: false
};
};

View file

@ -0,0 +1,18 @@
/* exported MockCostControl */
'use strict';
var MockCostControl = function(config) {
config = config || {};
var fakeCostControlInstance = config;
return {
getInstance: function(callback) {
callback(fakeCostControlInstance);
},
reset: function() {
fakeCostControlInstance = {};
}
};
};

View file

@ -0,0 +1,44 @@
/* exported MockDateFactory */
'use strict';
/*
* To construct a Date mockup specifying what date to return for "now / today".
*
* Use it by replacing Date constructor with that returned by the factory:
* window.Date = new MockDateFactory(new window.Date(2012, 0, 1));
*
* Subsequents uses of `new Date()` will return January, 1st 2012. Real Date
* constructor is kept safe in `MockDateFactory.realDate`.
*/
var MockDateFactory = (function(realDate) {
function buildFakeDateConstructor(now) {
function FakeDate(year, month, day) {
if (this instanceof FakeDate) {
if (arguments.length === 1) {
return new realDate(year);
} else if (arguments.length === 3) {
return new realDate(year, month, day);
} else if (typeof now !== 'undefined') {
return new realDate(now);
} else {
return new realDate();
}
} else {
return realDate.apply(this, arguments);
}
}
FakeDate.prototype.toUTCString = function() {
return realDate.prototype.toUTCString.apply(this, arguments);
};
return FakeDate;
}
buildFakeDateConstructor.realDate = realDate;
return buildFakeDateConstructor;
}(window.Date));

View file

@ -0,0 +1,18 @@
/* exported DEBUGGING, debug */
'use strict';
var DEBUGGING = true;
function debug() {
var message = [];
for (var i = 0, len = arguments.length, obj; i < len; i++) {
obj = arguments[i];
message.push(typeof obj === 'object' ? JSON.stringify(obj) : obj);
}
if (window.dump) {
message.push('\n');
window.dump(message.join(' '));
} else if (console && console.log) {
console.log(message.join(' '));
}
}

View file

@ -0,0 +1,35 @@
/* exported MockMozL10n */
'use strict';
var MockMozL10n = {
get: function get(key, args) {
if (key === 'magnitude') {
return args.value + ' ' + args.unit;
}
if (key === 'currency') {
return args.value + ' ' + args.currency;
}
if (key === 'day-hour-format') {
return args.day + ', ' + args.time;
}
if (key === 'hours-ago-short') {
return args.value + 'h ago';
}
if (key === 'minutes-ago-short') {
if (args.value !== 0) {
return args.value + 'm ago';
} else {
return 'just now';
}
}
if (key === 'firstDayOfTheWeek') {
return '0';
}
return key;
},
ready: function(cb) {
if (cb) {
cb();
}
},
};

View file

@ -0,0 +1,191 @@
/* global MockAllNetworkInterfaces */
/* exported MockMozNetworkStats */
'use strict';
var MockMozNetworkStats;
requireApp('costcontrol/test/unit/mock_all_network_interfaces.js', function() {
MockMozNetworkStats = (function() {
var system_manifest = 'app://system.gaiamobile.org/manifest.webapp';
var samples1 = {
'manifestURL': null,
'network': {'type': 0, 'id': '0'},
'start': {'__date__': '2013-11-14T05:00:00.000Z'},
'end': {'__date__': '2013-11-30T05:00:00.000Z'},
'data': [
{'rxBytes': 1130089, 'txBytes': 54931883,
'date': {'__date__': '2013-11-14T05:00:00.000Z'}},
{'rxBytes': 1130089, 'txBytes': 54931883,
'date': {'__date__': '2013-11-15T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-16T05:00:00.000Z'}}
]
};
var samples2 = {
'manifestURL': null,
'network': {'type': 1, 'id': '8100075100210526976'},
'start': {'__date__': '2013-11-14T05:00:00.000Z'},
'end': {'__date__': '2013-11-30T05:00:00.000Z'},
'data': [
{'rxBytes': 3454523454, 'txBytes': 111111,
'date': {'__date__': '2013-11-14T05:00:00.000Z'}},
{'rxBytes': 1345345089, 'txBytes': 563483,
'date': {'__date__': '2013-11-15T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-16T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-17T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-18T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-19T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-20T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-21T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-22T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-23T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-24T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-25T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-26T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-27T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-28T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-29T05:00:00.000Z'}},
{'date': {'__date__': '2013-11-30T05:00:00.000Z'}}
]
};
var APP_MANIFEST_1 = 'manifest_url_1';
var APP_MANIFEST_2 = 'manifest_url_2';
var appSamples = {
'manifest_url_1': {
'appManifestURL': APP_MANIFEST_1,
'network': {'type': 1, 'id': '45678'},
'start': {'__date__': '2014-08-14T05:00:00.000Z'},
'end': {'__date__': '2014-08-31T05:00:00.000Z'},
'data': [
{'rxBytes': 123, 'txBytes': 234,
'date': {'__date__': '2014-08-14T05:00:00.000Z'}},
{'rxBytes': 234, 'txBytes': 456,
'date': {'__date__': '2014-08-15T05:00:00.000Z'}},
]
},
'manifest_url_2': {
'appManifestURL': APP_MANIFEST_2,
'network': {'type': 1, 'id': '45678'},
'start': {'__date__': '2014-08-14T05:00:00.000Z'},
'end': {'__date__': '2014-08-31T05:00:00.000Z'},
'data': [
{'rxBytes': 456, 'txBytes': 567,
'date': {'__date__': '2014-08-14T05:00:00.000Z'}},
{'rxBytes': 567, 'txBytes': 678,
'date': {'__date__': '2014-08-15T05:00:00.000Z'}},
]
},
'app://system.gaiamobile.org/manifest.webapp': {
browsingTrafficOnly: true,
'appManifestURL': system_manifest,
'network': {'type': 1, 'id': '45678'},
'start': {'__date__': '2014-08-14T05:00:00.000Z'},
'end': {'__date__': '2014-08-31T05:00:00.000Z'},
'data': [
{'rxBytes': 121, 'txBytes': 111,
'date': {'__date__': '2014-08-14T05:00:00.000Z'}},
{'rxBytes': 141, 'txBytes': 222,
'date': {'__date__': '2014-08-15T05:00:00.000Z'}},
]
}
};
var allInterfacesFake = MockAllNetworkInterfaces;
var FAILING_ALARM_ID = 99;
var alarms1 = [{
'alarmId' : 1,
'network' : {'type' : 1, 'id' : allInterfacesFake[1] }
}];
var alarms2 = [{
'alarmId' : FAILING_ALARM_ID,
'network' : {'type' : 1, 'id' : allInterfacesFake[2] }
}];
function MockFakeRequest(config) {
this.init(config || {});
}
MockFakeRequest.prototype = {
init: function mgs_init(config) {
setTimeout((function() {
this.call(config.error, config.result);
}).bind(this), 0);
},
call: function mgs_call(error, result) {
if (!error) {
this.result = result;
this.onsuccess && this.onsuccess();
} else {
this.onerror && this.onerror();
}
}
};
return {
sampleRate: 86400000,
maxStorageSamples: 15552000000,
WIFI: 0,
MOBILE: 1,
APP_MANIFEST_1: 'manifest_url_1',
APP_MANIFEST_2: 'manifest_url_2',
clearAllStats: {},
clearStats: function clearStats(networkInterface) {
return new MockFakeRequest({
error: samples1
});
},
getSamples: function getSamples(networkInterface, start, end, options) {
if (networkInterface.type === 0) {
return new MockFakeRequest({
result: samples1
});
}
if (options && options.appManifestURL in appSamples) {
return new MockFakeRequest({
result: appSamples[options.appManifestURL]
});
}
return new MockFakeRequest({
result: samples2
});
},
getAvailableNetworks: function getAvailableNetworks() {
return new MockFakeRequest({
result: allInterfacesFake
});
},
removeAlarms: function(alarmId) {
var result = { result: {} };
if (alarmId === FAILING_ALARM_ID) {
result = { error: {} };
}
return new MockFakeRequest(result);
},
addAlarm: function(networkInterface, limitValue) {
var result = { result: {} };
if (networkInterface === allInterfacesFake[3]) {
result = { error: {} };
}
return new MockFakeRequest(result);
},
getAllAlarms: function(networkInterface) {
if (networkInterface === allInterfacesFake[2]) {
return new MockFakeRequest({
result: alarms2
});
}
return new MockFakeRequest({
result: alarms1
});
}
};
}());
});

View file

@ -0,0 +1,11 @@
'use strict';
function MockNonReadyScreen(container) {
this.id = container.id;
}
MockNonReadyScreen.prototype.updateForState = function(cardState) {
var event = new CustomEvent('nonReadyScreenUpdated', { detail: cardState });
window.dispatchEvent(event);
console.log('NonReadyScreen in state: ' + cardState);
};

View file

@ -0,0 +1,9 @@
/* exported MockSettings */
'use strict';
var MockSettings = function() {
return {
initialize: function() {},
updateUI: function() {}
};
};

View file

@ -0,0 +1,37 @@
/* global MockNavigatorSettings */
/* exported MockSettingsListener */
'use strict';
requireApp('costcontrol/shared/test/unit/mocks/mock_navigator_moz_settings.js');
var MockSettingsListener = {
observe: function msl_observe(name, defaultValue, cb) {
this.mName = name;
this.mDefaultValue = defaultValue;
this.mCallback = cb;
this.mCallbacks[name] = cb;
},
getSettingsLock: function msl_getSettingsLock() {
var set = function set(settings) {
for (var name in settings) {
var object = {};
object[name] = settings[name];
MockNavigatorSettings.createLock().set(object);
}
};
return {
set: set
};
},
mName: null,
mDefaultValue: null,
mCallback: null,
mCallbacks: {},
mTeardown: function teardown() {
this.mName = null;
this.mDefaultValue = null;
this.mDefaultCallback = null;
}
};

View file

@ -0,0 +1,152 @@
'use strict';
/* global NetworkUsageAlarm, MockAllNetworkInterfaces, MockMozNetworkStats */
requireApp('costcontrol/test/unit/mock_all_network_interfaces.js');
requireApp('costcontrol/js/settings/networkUsageAlarm.js');
requireApp('costcontrol/test/unit/mock_moz_network_stats.js');
var realMozNetworkStats;
if (!window.navigator.mozNetworkStats) {
window.navigator.mozNetworkStats = null;
}
suite('Network usage alarms Test Suite >', function() {
var allInterfacesFake;
suiteSetup(function() {
realMozNetworkStats = window.navigator.mozNetworkStats;
navigator.mozNetworkStats = MockMozNetworkStats;
allInterfacesFake = MockAllNetworkInterfaces;
});
suiteTeardown(function() {
window.navigator.mozNetworkStats = realMozNetworkStats;
});
test(
'Clear Alarms - Test arguments validation',
function() {
var consoleSpy = this.sinon.spy(console, 'error');
NetworkUsageAlarm.clearAlarms(null);
assert.ok(consoleSpy.calledOnce);
assert.ok(consoleSpy.calledWith('Error, the network interface is not ' +
'defined when trying to remove alarms'));
consoleSpy.restore();
}
);
test(
'Clear Alarms - clear works correctly without errors',
function(done) {
var removeAlarmsSpy = this.sinon.spy(window.navigator.mozNetworkStats,
'removeAlarms');
var consoleSpy = this.sinon.spy(console, 'error');
NetworkUsageAlarm.clearAlarms(allInterfacesFake[1], function () {
assert.ok(removeAlarmsSpy.calledOnce);
assert.equal(consoleSpy.callCount, 0);
consoleSpy.restore();
removeAlarmsSpy.restore();
done();
});
}
);
test(
'Clear Alarms - clear works correctly with errors',
function(done) {
var removeAlarmsSpy = this.sinon.spy(window.navigator.mozNetworkStats,
'removeAlarms');
var consoleSpy = this.sinon.spy(console, 'error');
NetworkUsageAlarm.clearAlarms(allInterfacesFake[2], function () {
assert.ok(removeAlarmsSpy.calledOnce);
assert.ok(consoleSpy.calledOnce);
assert.ok(consoleSpy.calledWith('Error when trying to remove one ' +
'alarm.'));
consoleSpy.restore();
removeAlarmsSpy.restore();
done();
});
}
);
test(
'Update Alarms - Test arguments validation',
function() {
var consoleSpy = this.sinon.spy(console, 'error');
NetworkUsageAlarm.updateAlarm(null, 24);
assert.ok(consoleSpy.calledOnce);
assert.ok(consoleSpy.calledWith('Error, the network interface is not ' +
'defined when trying to update an alarm'));
NetworkUsageAlarm.updateAlarm(allInterfacesFake[1], null);
assert.ok(consoleSpy.calledTwice);
assert.ok(consoleSpy.calledWith('Error, the data limit value is not ' +
'defined when trying to update an alarm'));
consoleSpy.restore();
}
);
test(
'Update Alarms - normal behaviour test',
function(done) {
var removeAlarmsSpy = this.sinon.spy(window.navigator.mozNetworkStats,
'removeAlarms');
var addAlarmSpy = this.sinon.spy(window.navigator.mozNetworkStats,
'addAlarm');
var limitValue = 1972;
NetworkUsageAlarm.updateAlarm(allInterfacesFake[1], limitValue,
function _ok() {
assert.ok(removeAlarmsSpy.calledOnce);
assert.ok(addAlarmSpy.calledOnce);
assert.ok(addAlarmSpy.calledWith(allInterfacesFake[1], limitValue));
addAlarmSpy.restore();
removeAlarmsSpy.restore();
done();
},
function _error() {
var consoleSpy = this.sinon.spy(console, 'error');
assert.equal(consoleSpy.callCount, 0);
consoleSpy.restore();
addAlarmSpy.restore();
removeAlarmsSpy.restore();
done();
});
}
);
test(
'Update Alarms - test behaviour when fails add alarm',
function(done) {
var consoleSpy = this.sinon.spy(console, 'error');
var removeAlarmsSpy = this.sinon.spy(window.navigator.mozNetworkStats,
'removeAlarms');
var addAlarmSpy = this.sinon.spy(window.navigator.mozNetworkStats,
'addAlarm');
var limitValue = 1972;
NetworkUsageAlarm.updateAlarm(allInterfacesFake[3], limitValue, null,
function _error() {
assert.ok(removeAlarmsSpy.calledOnce);
assert.ok(addAlarmSpy.calledOnce);
assert.ok(addAlarmSpy.calledWith(allInterfacesFake[3], limitValue));
assert.ok(consoleSpy.calledOnce);
assert.ok(consoleSpy.calledWith('Error, when trying to addAlarm to ' +
'the interfaceId: ' + allInterfacesFake[3].id + ' and limit: ' +
limitValue));
addAlarmSpy.restore();
removeAlarmsSpy.restore();
consoleSpy.restore();
done();
});
}
);
});

View file

@ -0,0 +1,123 @@
'use strict';
requireApp('costcontrol/test/unit/mock_common.js');
requireApp('costcontrol/test/unit/mock_moz_l10n.js');
requireApp('costcontrol/js/utils/toolkit.js');
requireApp('costcontrol/js/views/NonReadyScreen.js');
/* global NonReadyScreen */
var realCommon, realMozL10n;
if (!window.Common) {
window.Common = null;
}
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
suite('SIM non-ready waiting screen >', function() {
var CARD_STATES = [
null, 'pinRequired', 'pukRequired', 'other', 'airplaneMode'
];
var EXPECTED_IDS = [
'no-sim3', 'sim2-locked', 'sim2-locked', undefined, 'airplane-mode'
];
var EXPECTED_MODES = [
assertMessageMode,
assertMessageMode,
assertMessageMode,
assertWaitingMode,
assertMessageMode
];
var screen;
var container, progress, buttonContainer, button, header, message;
suiteSetup(function() {
realCommon = window.Common;
window.Common = new window.MockCommon();
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
});
suiteTeardown(function() {
window.Common = realCommon;
window.navigator.mozL10n = realMozL10n;
});
setup(function() {
buttonContainer = document.createElement('div');
button = document.createElement('button');
header = document.createElement('h1');
message = document.createElement('p');
progress = document.createElement('progress');
buttonContainer.appendChild(button);
container = document.createElement('div');
container.appendChild(progress);
container.appendChild(header);
container.appendChild(message);
container.appendChild(buttonContainer);
container.id = 'test';
screen = new NonReadyScreen(container);
});
function assertMessageMode(cardstate) {
assert.ok(progress.hidden);
assert.ok(!header.hidden);
assert.ok(!message.hidden);
}
function assertWaitingMode() {
assert.ok(!progress.hidden);
assert.ok(header.hidden);
assert.ok(message.hidden);
}
test(
'Gets the correct message id for the card states.',
function() {
var message;
CARD_STATES.forEach(function (state, i) {
message = screen.getMessageIdFor(state);
assert.strictEqual(message, EXPECTED_IDS[i]);
});
}
);
test(
'setWaitingMode() hides the message and shows the progress.',
function() {
screen.setWaitingMode();
assertWaitingMode();
}
);
test(
'setMessageMode() shows the message and hides the progress.',
function() {
var cardstate = 'pinRequired';
screen.setMessageMode(cardstate);
assertMessageMode();
}
);
test(
'updateForState() sets the non ready screen in proper mode according to ' +
'the card state.',
function() {
CARD_STATES.forEach(function (state, i) {
screen.updateForState(state);
EXPECTED_MODES[i](state);
});
}
);
});

View file

@ -0,0 +1,163 @@
'use strict';
require('/test/unit/mock_settings.js');
require('/test/unit/mock_common.js');
require('/test/unit/mock_moz_l10n.js');
require('/js/utils/formatting.js');
require('/js/utils/toolkit.js');
require('/js/views/ConfirmDialog.js');
require('/js/views/ResetMenuDialog.js');
require('/js/view_manager.js');
/* global ResetMenuDialog, ConfirmDialog, ViewManager, ConfirmDialog, Common,
MocksHelper, MockCommon, MockSettings, Formatting
*/
var realMozL10n;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
var MocksHelperForUnitTest = new MocksHelper([
'Common',
'Settings'
]).init();
suite('Reset Menu Dialog Test Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
var confirmDialog, vManager, resetMenuDialog;
var container, menuContainer, header, message, confirmContainer, dataUsage;
suiteSetup(function() {
window.Common = new MockCommon();
window.Settings = new MockSettings();
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
});
setup(function() {
vManager = new ViewManager();
initConfirmContainer();
initResetMenuContainer();
dataUsage = {
wifi: 123435435,
mobile: 323423
};
confirmDialog = new ConfirmDialog(confirmContainer, vManager);
resetMenuDialog = new ResetMenuDialog(container, vManager);
});
function initConfirmContainer() {
var cancelButton = document.createElement('button');
var okButton = document.createElement('button');
confirmContainer = document.createElement('div');
cancelButton.classList.add('close-reset-dialog');
okButton.classList.add('danger');
confirmContainer.appendChild(cancelButton);
confirmContainer.appendChild(okButton);
message = document.createElement('p');
header = document.createElement('h1');
confirmContainer.appendChild(header);
confirmContainer.appendChild(message);
confirmContainer.id = 'confirmReset';
}
function initResetMenuContainer() {
var cancelButton = document.createElement('button');
cancelButton.classList.add('close-reset-dialog');
container = document.createElement('div');
menuContainer = document.createElement('menu');
menuContainer.appendChild(cancelButton);
container.appendChild(menuContainer);
container.id = 'resetMenu';
}
test('initializeResetModes() creates the reset buttons', function() {
resetMenuDialog.initializeResetModes(confirmDialog);
// Checking if exists a button for each reset Mode
resetMenuDialog.resetModes.forEach(function(resetMode) {
assert.isNotNull(
container.querySelector('#reset-' + resetMode + '-data-usage'));
});
});
test('closeConfirmDialog() closes view', function() {
this.sinon.spy(vManager, 'closeCurrentView');
resetMenuDialog.closeResetMenuDialog();
sinon.assert.calledOnce(vManager.closeCurrentView);
});
test('showResetMenuDialog() changes the view', function() {
this.sinon.stub(vManager, 'changeViewTo', function() {});
resetMenuDialog.showResetMenuDialog();
sinon.assert.calledWith(vManager.changeViewTo, container.id);
});
test('showResetMenuDialog() parameter is used to update the confirm message',
function() {
var resetMode = resetMenuDialog.resetModes[0];
this.sinon.spy(confirmDialog, 'setMessage');
this.sinon.stub(vManager, 'changeViewTo', function() {});
resetMenuDialog.initializeResetModes(confirmDialog);
resetMenuDialog.showResetMenuDialog(dataUsage);
// Calling updateConfirm method to check the dataUsage parameter is
// used by the view
resetMenuDialog.updateConfirmDialog(resetMode, confirmDialog);
// Checking the message is updated correctly
var l10nId = 'reset-' + resetMode + '-confirmation-warning';
var mobileUsage =
Formatting.formatData(Formatting.roundData(dataUsage.mobile));
var wifiUsage =
Formatting.formatData(Formatting.roundData(dataUsage.wifi));
var expectedData = {
mobileData: mobileUsage,
wifiData: wifiUsage
};
sinon.assert.calledWith(confirmDialog.setMessage, l10nId, expectedData);
});
test(
'updateConfirmDialog() configure the Confirm dialog correctly for each' +
' reset service',
function() {
this.sinon.stub(confirmDialog, 'setMessage', function() {});
this.sinon.stub(confirmDialog, 'showConfirmDialog',
function() {
resetMenuDialog.dataUsage = dataUsage;
});
this.sinon.stub(Common, 'resetData', function() {});
resetMenuDialog.initializeResetModes(confirmDialog);
// Checking if the message dialog is updated correctly
resetMenuDialog.resetModes.forEach(function(resetMode) {
var resetButton =
container.querySelector('#reset-' + resetMode + '-data-usage');
resetButton.click();
// Checking the message is updated correctly
var l10nId = 'reset-' + resetMode + '-confirmation-warning';
sinon.assert.calledWith(confirmDialog.setMessage, l10nId);
// Checking if we are resetting the correct service.
var confirmButton = confirmContainer.querySelector('.danger');
confirmButton.click();
sinon.assert.calledWith(Common.resetData, resetMode);
});
}
);
});

View file

@ -0,0 +1,722 @@
/* global Settings, ConfigManager, Formatting, MocksHelper, MockCommon,
MockConfigManager, MockCostControl, SimManager
*/
'use strict';
require('/test/unit/mock_date.js');
require('/test/unit/mock_moz_l10n.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/test/unit/mock_debug.js');
require('/test/unit/mock_common.js');
require('/shared/test/unit/load_body_html_helper.js');
require('/js/view_manager.js');
require('/js/views/BalanceView.js');
require('/test/unit/mock_cost_control.js');
require('/test/unit/mock_config_manager.js');
require('/js/utils/formatting.js');
require('/js/views/BalanceLowLimitView.js');
require('/js/views/ResetMenuDialog.js');
require('/js/views/ConfirmDialog.js');
require('/js/settings/limitdialog.js');
require('/js/settings/autosettings.js');
require('/js/settings/settings.js');
require('/js/sim_manager.js');
require('/js/utils/toolkit.js');
require('/shared/js/component_utils.js');
require('/shared/elements/gaia_switch/script.js');
require('/shared/elements/gaia-header/dist/gaia-header.js');
require('/shared/elements/gaia_subheader/script.js');
var realMozL10n,
realAddNetworkUsageAlarm,
realDate;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
if (!window.realAddNetworkUsageAlarm) {
window.realAddNetworkUsageAlarm = null;
}
var MocksHelperForUnitTest = new MocksHelper([
'LazyLoader',
'Common',
'CostControl',
'ConfigManager'
]).init();
suite('Settings Test Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
var mobileUsage, wifiUsage;
var domSelectorsForLayout = [
{
name: 'planTypeSelector',
selector: '#plantype-settings',
isHiddenOnPostpaidLayout: false,
isHiddenOnPrepaidLayout: false,
isHiddenOnDataUsageOnlyLayout: true
}, {
name: 'phoneActivitySettings',
selector: '#phone-activity-settings + .settings',
isHiddenOnPostpaidLayout: false,
isHiddenOnPrepaidLayout: true,
isHiddenOnDataUsageOnlyLayout: true
}, {
name: 'phoneActivityTitle',
selector: '#phone-activity-settings',
isHiddenOnPostpaidLayout: false,
isHiddenOnPrepaidLayout: true,
isHiddenOnDataUsageOnlyLayout: true
}, {
name: 'balanceTitle',
selector: '#balance-settings',
isHiddenOnPostpaidLayout: true,
isHiddenOnPrepaidLayout: false,
isHiddenOnDataUsageOnlyLayout: true
}, {
name: 'balanceSettings',
selector: '#balance-settings + .settings',
isHiddenOnPostpaidLayout: true,
isHiddenOnPrepaidLayout: false,
isHiddenOnDataUsageOnlyLayout: true
}, {
name: 'reportsTitle',
selector: '#phone-internet-settings',
isHiddenOnPostpaidLayout: false,
isHiddenOnPrepaidLayout: true,
isHiddenOnDataUsageOnlyLayout: false
}
];
suiteSetup(function() {
window.Common = new MockCommon();
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
realAddNetworkUsageAlarm = window.addNetworkUsageAlarm;
window.addNetworkUsageAlarm = function() {};
realDate = window.Date;
});
setup(function() {
var now = new Date(2014, 5, 24); // 2014-06-24
window.Date = new window.MockDateFactory(now);
loadBodyHTML('/settings.html');
// Data usage elements
mobileUsage = document.querySelector('#mobile-data-usage > span');
wifiUsage = document.querySelector('#wifi-data-usage > span');
});
teardown(function() {
window.Date = realDate;
window.location.hash = '';
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
window.addNetworkUsageAlarm = realAddNetworkUsageAlarm;
});
function setupApplicationMode(applicationMode, fakeConfiguration) {
window.ConfigManager = new MockConfigManager({
fakeConfiguration: fakeConfiguration,
fakeSettings: {
dataLimit: true,
dataLimitValue: 40,
dataLimitUnit: 'MB',
lowLimit: true,
trackingPeriod: 'monthly',
resetTime: 1
},
applicationMode: applicationMode
});
}
function setupPrepaidMode() {
var fakeConfiguration = {
default_low_limit_threshold: 3,
credit: { currency: 'R$' }
};
setupApplicationMode('PREPAID', fakeConfiguration);
}
function setupTestScenario(costControlConfig, applicationMode) {
window.CostControl = new MockCostControl(costControlConfig);
window.ConfigManager = new MockConfigManager({
fakeConfiguration: {
default_low_limit_threshold: 3,
credit: { currency: 'R$' }
},
fakeSettings: {
dataLimit: true,
dataLimitValue: 40,
dataLimitUnit: 'MB',
lowLimit: true,
lastTelephonyActivity: 3456
},
applicationMode: applicationMode
});
}
function triggerEvent(element, eventName) {
var event = document.createEvent('HTMLEvents');
event.initEvent(eventName, true, true);
element.dispatchEvent(event);
}
var requestToCheckLayout = function(assertingFunction, done) {
return {
request: function(requestedObj, callback) {
(typeof assertingFunction === 'function') && assertingFunction(done);
}
};
};
function assertPostpaidLayout(done) {
domSelectorsForLayout.forEach(function checkVisibility(element) {
var domElement = document.querySelector(element.selector);
assert.equal(domElement.hidden, element.isHiddenOnPostpaidLayout,
'The visibility of ' + element.name + ' is incorrect');
});
done();
}
function assertPrepaidLayout(done) {
domSelectorsForLayout.forEach(function checkVisibility(element) {
var domElement = document.querySelector(element.selector);
assert.equal(domElement.hidden, element.isHiddenOnPrepaidLayout,
'The visibility of ' + element.name + ' is incorrect');
});
done();
}
function assertDataUsageOnlyLayout(done) {
domSelectorsForLayout.forEach(function checkVisibility(element) {
var domElement = document.querySelector(element.selector);
assert.equal(domElement.hidden, element.isHiddenOnDataUsageOnlyLayout,
'The visibility of ' + element.name + 'is incorrect');
});
done();
}
test('Layout postpaid mode is correctly loaded', function(done) {
var costControlConfig = requestToCheckLayout(assertPostpaidLayout, done);
setupTestScenario(costControlConfig, 'POSTPAID');
Settings.initialize();
});
test('Layout prepaid mode is correctly loaded', function(done) {
var costControlConfig = requestToCheckLayout(assertPrepaidLayout, done);
setupTestScenario(costControlConfig, 'PREPAID');
Settings.initialize();
});
test('Layout data_usage_only mode is correctly loaded', function(done) {
var costControlConfig = requestToCheckLayout(assertDataUsageOnlyLayout,
done);
setupTestScenario(costControlConfig, 'DATA_USAGE_ONLY');
Settings.initialize();
});
test('updateDataUsage works correctly', function(done) {
setupPrepaidMode();
var lastDataUsage = {
timestamp: new Date(),
today: new Date(),
wifi: {
total: 222
},
mobile: {
total: 333
}
};
sinon.stub(Settings, 'updateUI', function() {
ConfigManager.mTriggerCallback('lastDataUsage', lastDataUsage,
{lastCompleteDataReset: new Date() });
var mobileDataUsage = Formatting.formatData(
Formatting.roundData(lastDataUsage.mobile.total));
var wifiDataUsage = Formatting.formatData(
Formatting.roundData(lastDataUsage.wifi.total));
assert.equal(mobileUsage.textContent, mobileDataUsage);
assert.equal(wifiUsage.textContent, wifiDataUsage);
Settings.updateUI.restore();
ConfigManager.mRemoveObservers();
done();
});
Settings.initialize();
});
test('Default values for reset time (monthly)', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
var today = new Date();
// Initial value for tracking period is monthly and for resetTime 1
// Force the initialization of the resetTime field
ConfigManager.mTriggerCallback('trackingPeriod');
assert.equal(ConfigManager.option('resetTime'), today.getDate());
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Default values for reset time (weekly)', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
var today = new Date();
// Initial value for tracking period is monthly and for resetTime 1
// Change tracking period to weekly
ConfigManager.option('trackingPeriod', 'weekly');
ConfigManager.mTriggerCallback('trackingPeriod', 'weekly');
assert.equal(ConfigManager.option('trackingPeriod'), 'weekly');
assert.equal(ConfigManager.option('resetTime'), today.getDay());
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
suite('Data Limit Configurator Test Suite >', function() {
var dataLimitDialog, dataLimitInput, dataLimitOkButton, limitUnitValue,
dataLimitSwitchUnitButton, dataLimitHeader;
var evtInput = new CustomEvent('input', {});
setup(function() {
dataLimitDialog = document.getElementById('data-limit-dialog');
dataLimitInput = dataLimitDialog.querySelector('input');
dataLimitOkButton = dataLimitDialog.querySelector('button.recommend');
dataLimitHeader = document.getElementById('limit-dialog-header');
dataLimitSwitchUnitButton = dataLimitDialog.
querySelector('.switch-unit-button');
limitUnitValue = dataLimitSwitchUnitButton.querySelector('span.tag');
});
function initDataLimitDialog() {
// Init the dataLimitDialog values
ConfigManager.mTriggerCallback('dataLimitValue', 40);
ConfigManager.mTriggerCallback('dataLimitUnit', 'MB');
// load Limit dialog
var dataLimitButton =
document.querySelector('[data-widget-type=data-limit]');
triggerEvent(dataLimitButton, 'click');
}
function assertDataLimitInputInvalid() {
assert.isTrue(dataLimitInput.classList.contains('error'));
assert.isTrue(dataLimitOkButton.disabled);
}
function assertDataLimitInputValid() {
assert.isFalse(dataLimitInput.classList.contains('error'));
assert.isFalse(dataLimitOkButton.disabled);
}
suite('Valid Values >', function() {
test('Real values', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '912.05';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
dataLimitInput.value = '0.5';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Atypical values', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
// bug 1073340 - 0.07 produces a decimal multiplication overflow
dataLimitInput.value = '0.07';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Numbers without significant digits', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '.1';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
dataLimitInput.value = '.78';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Natural numbers', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '120';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
dataLimitInput.value = '0000456';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Natural numbers with no significant zeros', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '0000456';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputValid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
});
suite('Invalid values >', function() {
test('Negative Values', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '-12.456';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputInvalid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Separator invalid', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '12,456';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputInvalid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Too decimal Separators', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '124..56';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputInvalid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Not numeric', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = 'a';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputInvalid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Too long', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '12456';
dataLimitInput.dispatchEvent(evtInput);
assertDataLimitInputInvalid();
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
});
suite('Automatic input corrections >', function() {
test('No action ', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '12.34';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '12.34');
dataLimitInput.value = '9912';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '9912');
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('No corrections with invalid entries', function(done) {
setupPrepaidMode();
this.sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '0';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '0');
assertDataLimitInputInvalid();
dataLimitInput.value = '0.';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '0.');
assertDataLimitInputInvalid();
dataLimitInput.value = '0.0';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '0.0');
assertDataLimitInputInvalid();
dataLimitInput.value = '.';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '.');
assertDataLimitInputInvalid();
dataLimitInput.value = '.0';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '.0');
assertDataLimitInputInvalid();
triggerEvent(dataLimitHeader, 'action');
done();
});
Settings.initialize();
});
test('Removing left zeros ', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '02.04';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '2.04');
dataLimitInput.value = '007';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '7');
dataLimitInput.value = '000012.31';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '12.31');
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Removing right zeros ', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '77.60';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '77.6');
dataLimitInput.value = '442.01000';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '442.01');
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Removing both sides ', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '012.010';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '12.01');
dataLimitInput.value = '0000062.1000';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '62.1');
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('Fill with left zero ', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '.31';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitInput.value, '0.31');
triggerEvent(dataLimitHeader, 'action');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
});
test('dataLimitConfigurer Cancel button behaviour', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
dataLimitInput.value = '124.56';
dataLimitInput.dispatchEvent(evtInput);
// Cancel not update the Config values
assert.equal(ConfigManager.option('dataLimitUnit'), 'MB');
assert.equal(ConfigManager.option('dataLimitValue'), '40');
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
test('dataLimitConfigurer OK button behaviour', function(done) {
setupPrepaidMode();
sinon.stub(Settings, 'updateUI', function() {
initDataLimitDialog();
assert.equal(ConfigManager.option('dataLimitUnit'), 'MB');
assert.equal(ConfigManager.option('dataLimitValue'), '40');
// Update the dataLimit
dataLimitInput.value = '124.56';
dataLimitInput.dispatchEvent(evtInput);
assert.equal(dataLimitSwitchUnitButton.getAttribute('data-l10n-id'),
'unit-MB');
assert.equal(limitUnitValue.getAttribute('data-l10n-id'), 'MB');
triggerEvent(dataLimitSwitchUnitButton, 'click');
assert.equal(dataLimitSwitchUnitButton.getAttribute('data-l10n-id'),
'unit-GB');
assert.equal(limitUnitValue.getAttribute('data-l10n-id'), 'GB');
sinon.stub(SimManager, 'requestDataSimIcc', function() {});
triggerEvent(dataLimitOkButton, 'click');
assert.equal(ConfigManager.option('dataLimitUnit'), 'GB');
assert.equal(ConfigManager.option('dataLimitValue'), '124.56');
SimManager.requestDataSimIcc.restore();
Settings.updateUI.restore();
done();
});
Settings.initialize();
});
});
});

View file

@ -0,0 +1,4 @@
'use strict';
require('/shared/test/unit/mocks/mocks_helper.js');

View file

@ -0,0 +1,419 @@
/* global MockAllNetworkInterfaces, MockNavigatorSettings, SimManager,
MockNavigatorMozMobileConnections, MockNavigatorMozIccManager,
MocksHelper, MockSettingsListener
*/
'use strict';
require('/test/unit/mock_all_network_interfaces.js');
require('/shared/test/unit/mocks/mock_navigator_moz_settings.js');
require('/shared/test/unit/mocks/mock_settings_listener.js');
require('/shared/test/unit/mocks/mock_navigator_moz_icc_manager.js');
require('/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/test/unit/mock_airplane_mode_helper.js');
require('/js/sim_manager.js');
var MocksHelperForUnitTest = new MocksHelper([
'AirplaneModeHelper',
'LazyLoader',
'SettingsListener'
]).init();
suite('Cost Control SimManager >', function() {
var realMozSettings,
realMozMobileConnections,
realMozIccManager;
MocksHelperForUnitTest.attachTestHelpers();
suiteSetup(function() {
realMozSettings = navigator.mozSettings;
window.navigator.mozSettings = MockNavigatorSettings;
realMozIccManager = navigator.mozIccManager;
window.navigator.mozIccManager = window.MockNavigatorMozIccManager;
realMozMobileConnections = navigator.mozMobileConnections;
window.navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
});
suiteTeardown(function() {
window.navigator.mozSettings = realMozSettings;
window.navigator.mozMobileConnections = realMozMobileConnections;
window.navigator.mozIccManager = realMozIccManager;
});
setup(function() {
MockNavigatorSettings.mSetup();
});
teardown(function() {
MockNavigatorSettings.mTeardown();
MockNavigatorMozIccManager.mTeardown();
MockNavigatorMozMobileConnections.mTeardown();
timeouts.forEach(clearTimeout);
timeouts = [];
SimManager.reset();
});
var timeouts = [];
function createFailingLockRequest() {
return function() {
return {
set: null,
get: function() {
var request = {};
timeouts.push(setTimeout(function() {
request.error = { name: 'error' };
request.onerror && request.onerror();
}));
return request;
}
};
};
}
suite(' Single SIM scenario >', function() {
setup(function() {
SimManager.reset();
MockNavigatorSettings.mTeardown();
window.navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
window.navigator.mozIccManager = window.MockNavigatorMozIccManager;
});
test('The data Icc is loading without errors', function(done) {
MockNavigatorMozMobileConnections[0] = {
iccId: MockAllNetworkInterfaces[1].id
};
MockNavigatorMozIccManager.addIcc(MockAllNetworkInterfaces[1].id, {});
assert.isFalse(SimManager.isMultiSim());
SimManager.requestDataSimIcc(function(dataSim) {
done(() => {
assert.isTrue(dataSim.initialized);
assert.equal(dataSim.iccId,
MockAllNetworkInterfaces[1].id);
MockNavigatorMozIccManager.removeIcc(MockAllNetworkInterfaces[1].id);
});
});
});
test('Not possible load the data Icc, when iccId is null', function(done) {
MockNavigatorMozMobileConnections[0] = {
iccId: null
};
this.sinon.spy(console, 'error');
SimManager.requestDataSimIcc(
() => done(new Error('Should not call success')),
function onerror() {
done(() => {
sinon.assert.calledWith(
console.error,
'The slot 0, configured as the data slot, is empty'
);
});
}
);
});
// On this case mozMobile connections has an iccId, but IccManager does not
// have a Icc object with this iccId
test('Not possible load the data Icc, when Icc is null', function(done) {
MockNavigatorMozMobileConnections[0] = {
iccId: MockAllNetworkInterfaces[1].id
};
SimManager.requestDataSimIcc(
() => done(new Error('Should not call success')),
() => done()
);
});
test('requestDataConnection()', function(done) {
var dataSlotId = 0,
dataSlot = 'ril.data.defaultServiceId';
MockNavigatorSettings.mSettings[dataSlot] = dataSlotId;
MockNavigatorMozMobileConnections[dataSlotId] = {
voice: { connected: true }
};
SimManager.requestDataConnection(function(connection) {
done(() => assert.isTrue(connection.voice.connected));
});
});
});
suite(' Multi SIM scenario (currently DSDS) >', function() {
setup(function() {
MockNavigatorMozMobileConnections.mAddMobileConnection();
MockNavigatorMozIccManager.addIcc(MockAllNetworkInterfaces[0].id, {});
MockNavigatorMozIccManager.addIcc(MockAllNetworkInterfaces[1].id, {});
MockNavigatorMozMobileConnections[0] = {
iccId: MockAllNetworkInterfaces[1].id
};
MockNavigatorMozMobileConnections[1] = {
iccId: MockAllNetworkInterfaces[0].id
};
// needs to call this again after we setup the connections
SimManager.reset();
});
test('requestDataSimIcc() calls onsuccess with the iccinfo object ',
function(done) {
MockNavigatorSettings.mSettings['ril.data.defaultServiceId'] = 0;
assert.isTrue(SimManager.isMultiSim());
SimManager.requestDataSimIcc(
function onsuccess(dataSim) {
done(() => {
assert.equal(dataSim.iccId, MockAllNetworkInterfaces[1].id);
});
},
function onerror() {
done(new Error('requestDataSimIcc should not report an error'));
}
);
}
);
test('requestDataSimIcc() without the setting returns a warning message',
function(done) {
this.sinon.spy(console, 'warn');
window.addEventListener('simManagerReady', function _onSMInit() {
window.removeEventListener('simManagerReady', _onSMInit);
done(() => {
sinon.assert.calledTwice(console.warn);
sinon.assert.calledWith(
console.warn,
'SimManager is not ready, waiting for initialized custom event'
);
sinon.assert.calledWith(
console.warn,
'The setting ril.data.defaultServiceId does not exists, ' +
'using default Slot (0)'
);
});
});
SimManager.requestDataSimIcc();
}
);
test('requestTelephonySimIcc() without settings returns warning messages',
function(done) {
this.sinon.spy(console, 'warn');
window.addEventListener('simManagerReady', function _onSMInit() {
window.removeEventListener('simManagerReady', _onSMInit);
done(() => {
sinon.assert.calledTwice(console.warn);
sinon.assert.calledWith(
console.warn,
'SimManager is not ready, waiting for initialized custom event'
);
sinon.assert.calledWith(
console.warn,
'The setting ril.telephony.' +
'defaultServiceId does not exists, using default Slot (0)'
);
});
});
SimManager.requestTelephonySimIcc();
}
);
test('requestMessageSimIcc() without the setting returns warning messages',
function(done) {
this.sinon.spy(console, 'warn');
window.addEventListener('simManagerReady', function _onSMInit() {
window.removeEventListener('simManagerReady', _onSMInit);
done(() => {
sinon.assert.calledTwice(console.warn);
sinon.assert.calledWith(
console.warn,
'SimManager is not ready, waiting for initialized custom event'
);
sinon.assert.calledWith(
console.warn,
'The setting ril.sms.' +
'defaultServiceId does not exists, using default Slot (0)'
);
});
});
SimManager.requestMessageSimIcc();
}
);
test('requestDataSimIcc() returns Icc without settings', function(done) {
assert.isTrue(SimManager.isMultiSim());
SimManager.requestDataSimIcc(
function onsuccess(dataSim) {
done(() => {
assert.isTrue(dataSim.initialized);
assert.isTrue(dataSim.dirty);
assert.equal(dataSim.iccId, MockAllNetworkInterfaces[1].id);
});
},
function onerror() {
done(
new Error('requestTelephonySimIcc should not report an error')
);
}
);
});
test('requestTelephonySimIcc() works ok when settings request fails',
function(done) {
this.sinon.stub(navigator.mozSettings, 'createLock',
createFailingLockRequest());
assert.isTrue(SimManager.isMultiSim());
SimManager.requestTelephonySimIcc(
function onsuccess(telephonySim) {
done(() => {
assert.equal(telephonySim.iccId, MockAllNetworkInterfaces[1].id);
});
},
function onerror() {
done(
new Error('requestTelephonySimIcc should not report an error')
);
}
);
}
);
test('requestDataSimIcc() when all fails (no settings, no icc)',
function(done) {
this.sinon.stub(navigator.mozSettings, 'createLock',
createFailingLockRequest());
MockNavigatorMozMobileConnections[0] = { iccId: null };
this.sinon.spy(console, 'warn');
SimManager.requestDataSimIcc(
function onsuccess() { done(new Error('Should not call success')); },
function onerror() {
done(() => {
sinon.assert.calledTwice(console.warn);
sinon.assert.calledWith(
console.warn,
'SimManager is not ready, waiting for initialized custom event'
);
sinon.assert.calledWith(
console.warn,
'The setting ril.data.defaultServiceId does not exists'
);
});
}
);
}
);
test('init() requests the correct slotId', function(done) {
var dataSlotId = 0, messageSlotId = 1, telephonySlotId = 1;
MockNavigatorSettings
.mSettings['ril.data.defaultServiceId'] = dataSlotId;
MockNavigatorSettings
.mSettings['ril.telephony.defaultServiceId'] = telephonySlotId;
MockNavigatorSettings
.mSettings['ril.sms.defaultServiceId'] = messageSlotId;
var promises = [];
promises.push(new Promise(SimManager.requestDataSimIcc));
promises.push(new Promise(SimManager.requestMessageSimIcc));
promises.push(new Promise(SimManager.requestTelephonySimIcc));
Promise.all(promises).then((sims) => {
sims.forEach((sim) => assert.ok(sim.initialized));
assert.equal(sims[0].slotId, dataSlotId);
assert.equal(sims[1].slotId, messageSlotId);
assert.equal(sims[2].slotId, telephonySlotId);
}, () => { throw new Error('A request failed.'); })
.then(done, done);
});
test('requestMessageSimIcc() launches initialized event', function(done) {
window.addEventListener('simManagerReady', function _onSMInit() {
window.removeEventListener('simManagerReady', _onSMInit);
done();
});
SimManager.requestMessageSimIcc();
});
test('requestDataSimIcc behaviour when changing the default data slot',
function(done) {
var defaultDataSlotId = 0, newDataSlotId = 1,
dataSlot = 'ril.data.defaultServiceId';
MockNavigatorSettings.mSettings[dataSlot] = defaultDataSlotId;
window.addEventListener('dataSlotChange', function _onSMInit() {
window.removeEventListener('dataSlotChange', _onSMInit);
SimManager.requestDataSimIcc(
function onsuccess(dataSim) {
done(() => { assert.equal(dataSim.slotId, newDataSlotId); });
},
function onerror() {
done(new Error('requestDataSimIcc should not report an error'));
}
);
});
SimManager.requestDataSimIcc(
function onsuccess(dataSim) {
assert.equal(dataSim.slotId, defaultDataSlotId);
MockSettingsListener.mTriggerCallback(dataSlot, newDataSlotId);
},
function onerror() {
done(new Error('requestDataSimIcc should not report an error'));
}
);
});
test('getTelephonyConnection() works fine, without settings',
function(done) {
MockNavigatorMozMobileConnections[0] = {
voice: { connected: true }
};
SimManager.requestDataConnection(function(telephonyConnection) {
done(() => { assert.isTrue(telephonyConnection.voice.connected); });
});
});
test('getTelephonyConnection() works ok when settings request fails',
function(done) {
this.sinon.stub(navigator.mozSettings, 'createLock',
createFailingLockRequest());
MockNavigatorMozMobileConnections[0] = {
voice: { connected: true }
};
SimManager.requestDataConnection(function (telephonyConnection) {
done(() => { assert.isTrue(telephonyConnection.voice.connected); });
});
});
test('getTelephonyConnection fails, no settings, no MobileConnections',
function(done) {
this.sinon.stub(navigator.mozSettings, 'createLock',
createFailingLockRequest());
MockNavigatorMozMobileConnections[0] = null;
SimManager.requestDataConnection(function (telephonyConnection) {
done(() => { assert.isNull(telephonyConnection); });
});
}
);
});
});

View file

@ -0,0 +1,517 @@
/* global MockCommon, MockCostControl, MockNavigatorMozMobileConnections, Event,
CostControlApp, Common, MockConfigManager, asyncStorage,
MockMozNetworkStats, MocksHelper, SimManager, MockNavigatorSettings,
AirplaneModeHelper
*/
'use strict';
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/shared/test/unit/mocks/mock_async_storage.js');
require('/test/unit/mock_debug.js');
require('/test/unit/mock_common.js');
require('/test/unit/mock_moz_l10n.js');
require('/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js');
require('/test/unit/mock_moz_network_stats.js');
require('/test/unit/mock_settings_listener.js');
require('/shared/test/unit/mocks/mock_navigator_moz_set_message_handler.js');
require('/shared/test/unit/mocks/mock_settings_listener.js');
require('/shared/test/unit/mocks/mock_navigator_moz_settings.js');
require('/shared/test/unit/mocks/mock_navigator_moz_icc_manager.js');
require('/test/unit/mock_cost_control.js');
require('/test/unit/mock_config_manager.js');
require('/test/unit/mock_non_ready_screen.js');
require('/js/utils/toolkit.js');
require('/js/view_manager.js');
require('/js/app.js');
require('/js/common.js');
require('/js/sim_manager.js');
require('/shared/test/unit/load_body_html_helper.js');
require('/shared/test/unit/mocks/mock_accessibility_helper.js');
require('/test/unit/mock_airplane_mode_helper.js');
var realCommon,
realMozSettings,
realMozMobileConnections,
realMozL10n,
realMozSetMessageHandler,
realMozNetworkStats,
realMozIccManager;
if (!window.navigator.mozNetworkStats) {
window.navigator.mozNetworkStats = null;
}
if (!window.navigator.mozIccManager) {
window.navigator.mozIccManager = null;
}
if (!window.Common) {
window.Common = null;
}
if (!window.navigator.mozSetMessageHandler) {
window.navigator.mozSetMessageHandler = null;
}
if (!window.navigator.mozMobileConnections) {
window.navigator.mozMobileConnections = null;
}
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
if (!window.navigator.mozSettings) {
window.navigator.mozSettings = null;
}
var MocksHelperForUnitTest = new MocksHelper([
'LazyLoader',
'asyncStorage',
'AirplaneModeHelper',
'ConfigManager',
'CostControl',
'SettingsListener',
'NonReadyScreen',
'AccessibilityHelper'
]).init();
suite('Application Startup Modes Test Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
suiteSetup(function() {
realCommon = window.Common;
realMozMobileConnections = window.navigator.mozMobileConnections;
window.navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
realMozSetMessageHandler = window.navigator.mozSetMessageHandler;
window.navigator.mozSetMessageHandler =
window.MockNavigatormozSetMessageHandler;
window.navigator.mozSetMessageHandler.mSetup();
realMozNetworkStats = window.navigator.mozNetworkStats;
navigator.mozNetworkStats = MockMozNetworkStats;
realMozSettings = navigator.mozSettings;
window.navigator.mozSettings = MockNavigatorSettings;
realMozIccManager = window.navigator.mozIccManager;
navigator.mozIccManager = window.MockNavigatorMozIccManager;
});
setup(function() {
SimManager.reset();
navigator.mozIccManager = window.MockNavigatorMozIccManager;
window.dispatchEvent(new Event('localized'));
});
teardown(function() {
CostControlApp.reset();
window.location.hash = '';
});
suiteTeardown(function() {
window.Common = realCommon;
window.navigator.mozMobileConnections = realMozMobileConnections;
window.navigator.mozL10n = realMozL10n;
window.navigator.mozSetMessageHandler.mTeardown();
window.navigator.mozSetMessageHandler = realMozSetMessageHandler;
window.navigator.mozNetworkStats = realMozNetworkStats;
window.navigator.mozIccManager = realMozIccManager;
window.navigator.mozSettings = realMozSettings;
});
function assertNonReadyScreen(msg, done) {
var consoleSpy = sinon.spy(console, 'log');
window.addEventListener('viewchanged', function _onalert(evt) {
window.removeEventListener('viewchanged', _onalert);
assert.equal(evt.detail.id, 'non-ready-screen');
assert.ok(consoleSpy.calledWith(msg));
consoleSpy.restore();
done();
});
}
function assertFTEStarted(mode, done) {
window.addEventListener('ftestarted', function _onftestarted(evt) {
window.removeEventListener('ftestarted', _onftestarted);
assert.equal(evt.detail, mode);
done();
});
}
function assertDisplayingOnlyDataUsage() {
var tabs = document.getElementById('tabs');
var dataUsageTab = document.getElementById('datausage-tab');
// Tab zone is hidden and standalone mode for data usage tab is set
assert.ok(tabs.hidden);
assert.isTrue(dataUsageTab.classList.contains('standalone'));
}
function assertDisplayingBalanceTab() {
var tabs = document.getElementById('tabs');
var dataUsageTab = document.getElementById('datausage-tab');
var balanceTab = document.getElementById('balance-tab');
var balanceTabFilter = document.getElementById('balance-tab-filter');
var telephonyTabFilter = document.getElementById('telephony-tab-filter');
// Tab zone is shown, the balance enabler (filter) is shown and the
// telephony one is hidden.
assert.ok(!tabs.hidden);
assert.ok(!balanceTabFilter.hidden);
assert.ok(telephonyTabFilter.hidden);
// Balance is currently shown
assert.equal(balanceTab.dataset.viewport, '');
// Data usage remains on the right
assert.equal(dataUsageTab.dataset.viewport, 'right');
assert.isFalse(dataUsageTab.classList.contains('standalone'));
}
function assertDisplayingTelephonyTab() {
var tabs = document.getElementById('tabs');
var dataUsageTab = document.getElementById('datausage-tab');
var telephonyTab = document.getElementById('telephony-tab');
var balanceTabFilter = document.getElementById('balance-tab-filter');
var telephonyTabFilter = document.getElementById('telephony-tab-filter');
// Tab zone is shown, the telephony enabler (filter) is shown and the
// balance one is hidden.
assert.ok(!tabs.hidden);
assert.ok(balanceTabFilter.hidden);
assert.ok(!telephonyTabFilter.hidden, 'true');
// Telephony is currently shown
assert.equal(telephonyTab.dataset.viewport, '');
// Data usage remains on the right
assert.equal(dataUsageTab.dataset.viewport, 'right');
assert.isFalse(dataUsageTab.classList.contains('standalone'));
}
function failingRequestDataSIMIccId(onsuccess, onerror) {
setTimeout(function() {
(typeof onerror === 'function') && onerror();
}, 0);
}
function setupCardState(icc) {
window.Common = new MockCommon();
window.CostControl = new MockCostControl();
window.MockNavigatorMozIccManager.mTeardown();
window.MockNavigatorMozIccManager.addIcc('12345', icc);
MockNavigatorMozMobileConnections[0] = { iccId: '12345' };
}
test('SIM is not ready', function(done) {
loadBodyHTML('/index.html');
setupCardState({cardState: null});
assertNonReadyScreen('NonReadyScreen in state: null', done);
CostControlApp.init();
});
test('Not exist a mandatory API', function(done) {
loadBodyHTML('/index.html');
assertNonReadyScreen('NonReadyScreen in state: null', done);
window.navigator.mozIccManager = null;
CostControlApp.init();
});
test('SIM is locked by PIN', function(done) {
loadBodyHTML('/index.html');
setupCardState({cardState: 'pinRequired'});
assertNonReadyScreen('NonReadyScreen in state: pinRequired', done);
CostControlApp.init();
});
test('SIM is locked by PUK', function(done) {
loadBodyHTML('/index.html');
setupCardState({cardState: 'pukRequired'});
assertNonReadyScreen('NonReadyScreen in state: pukRequired', done);
CostControlApp.init();
});
test('SIM is detected after a non detected SIM on a previous start-up',
function(done) {
loadBodyHTML('/index.html');
this.sinon.spy(window.navigator.mozIccManager, 'addEventListener');
// The icc request fails, because of this request doesn't work if the
// airplane mode is enabled.
sinon.stub(SimManager, 'requestDataSimIcc', failingRequestDataSIMIccId);
// airplanemode activated for enable the iccmanager listeners
AirplaneModeHelper._status = 'enabled';
window.addEventListener('viewchanged', function _onalert(evt) {
window.removeEventListener('viewchanged', _onalert);
// Restore the stub method and disabling the airplanemode
SimManager.requestDataSimIcc.restore();
AirplaneModeHelper._status = 'disabled';
// Config the app to start (FTE)
var applicationMode = 'DATA_USAGE_ONLY';
setupCardState({cardState: 'ready'});
window.ConfigManager = new MockConfigManager({
fakeSettings: { fte: true },
applicationMode: applicationMode
});
// The assertion function contains a listener to detect when the fte is
// ready, for this reason it must be placed before dispatching the
// airplanemode disabled event
assertFTEStarted(applicationMode, done);
// Launch the second start-up
var eventDetail = { detail: {serviceId: 'data'}};
var airplaneModeDisabledEvent =
new CustomEvent('airplaneModeDisabled', eventDetail);
window.dispatchEvent(airplaneModeDisabledEvent);
});
CostControlApp.init();
});
test('SIM is not detected, the icc request is failing',
function(done) {
loadBodyHTML('/index.html');
this.sinon.stub(SimManager, 'requestDataSimIcc',
failingRequestDataSIMIccId);
// Config the app to start (FTE)
var applicationMode = 'DATA_USAGE_ONLY';
window.CostControl = new MockCostControl();
window.ConfigManager = new MockConfigManager({
applicationMode: applicationMode
});
AirplaneModeHelper._status = 'disabled';
CostControlApp.init();
assertNonReadyScreen('NonReadyScreen in state: null', done);
});
function setupLayoutMode(applicationMode) {
loadBodyHTML('/index.html');
window.Common = new MockCommon();
window.CostControl = new MockCostControl();
window.ConfigManager = new MockConfigManager({
fakeSettings: { fte: false },
applicationMode: applicationMode
});
Common.dataSimIcc = {cardState: 'ready'};
}
test('Layout: Data Usage Only', function(done) {
setupLayoutMode('DATA_USAGE_ONLY');
window.addEventListener('tabchanged', function checkAssertions() {
window.removeEventListener('tabchanged', checkAssertions);
assertDisplayingOnlyDataUsage();
done();
});
CostControlApp.init();
});
test('Layout: Prepaid', function(done) {
setupLayoutMode('PREPAID');
window.addEventListener('tabchanged', function checkAssertions() {
window.removeEventListener('tabchanged', checkAssertions);
assertDisplayingBalanceTab();
done();
});
CostControlApp.init();
});
test('Layout: Postpaid', function(done) {
setupLayoutMode('POSTPAID');
window.addEventListener('tabchanged', function checkAssertions() {
window.removeEventListener('tabchanged', checkAssertions);
assertDisplayingTelephonyTab();
done();
});
CostControlApp.init();
});
suite('supportCustomizeMode setting', function() {
var MockMozAlarms = {
add: function() {},
remove: function() {}
};
var realMozAlarms;
suiteSetup(function() {
realMozAlarms = window.navigator.mozAlarms;
window.navigator.mozAlarms = MockMozAlarms;
});
suiteTeardown(function() {
window.navigator.mozAlarms = realMozAlarms;
});
test('Start up with custom mode when functionality is disabled produces ' +
'a change to the never mode',
function(done) {
var expectedMode = 'never';
var applicationMode = 'DATA_USAGE_ONLY';
setupCardState({cardState: 'ready'});
window.ConfigManager = new MockConfigManager(
{
fakeSettings: {
fte: true,
trackingPeriod: 'custom'
},
applicationMode: applicationMode
}
);
window.addEventListener('ftestarted', function _onftestarted(evt) {
window.removeEventListener('ftestarted', _onftestarted);
assert.equal(window.ConfigManager.option('trackingPeriod'),
expectedMode);
done();
});
CostControlApp.init();
}
);
test('Start up with custom mode when functionality is disabled remove ' +
'nextReset alarm',
function(done) {
var expectedMode = 'never';
var nextResetAlarmId = '111';
var applicationMode = 'DATA_USAGE_ONLY';
this.sinon.stub(asyncStorage, 'getItem').yields(nextResetAlarmId);
this.sinon.stub(asyncStorage, 'setItem').yields();
this.sinon.stub(navigator.mozAlarms, 'remove', function() {});
setupCardState({cardState: 'ready'});
window.ConfigManager = new MockConfigManager(
{
fakeSettings: {
fte: true,
trackingPeriod: 'custom',
nextReset: new Date()
},
applicationMode: applicationMode
}
);
window.addEventListener('ftestarted', function _onftestarted(evt) {
window.removeEventListener('ftestarted', _onftestarted);
assert.equal(window.ConfigManager.option('trackingPeriod'),
expectedMode);
sinon.assert.calledWith(navigator.mozAlarms.remove, nextResetAlarmId);
assert.isNull(window.ConfigManager.option('nextReset'));
done();
});
CostControlApp.init();
}
);
});
suite('FTE Startup Test Suite >', function() {
test(
'First Time Experience Loaded when new SIM > DATA_USAGE_ONLY',
function(done) {
var applicationMode = 'DATA_USAGE_ONLY';
setupCardState({cardState: 'ready'});
window.ConfigManager = new MockConfigManager({
fakeSettings: { fte: true },
applicationMode: applicationMode
});
assertFTEStarted(applicationMode, done);
CostControlApp.init();
}
);
test(
'First Time Experience Loaded when new SIM > PREPAID',
function(done) {
var applicationMode = 'PREPAID';
setupCardState({cardState: 'ready'});
window.ConfigManager = new MockConfigManager({
fakeSettings: { fte: true },
applicationMode: applicationMode
});
assertFTEStarted(applicationMode, done);
CostControlApp.init();
}
);
test(
'First Time Experience Loaded when new SIM > POSTPAID',
function(done) {
var applicationMode = 'POSTPAID';
setupCardState({cardState: 'ready'});
window.ConfigManager = new MockConfigManager({
fakeSettings: { fte: true },
applicationMode: applicationMode
});
assertFTEStarted(applicationMode, done);
CostControlApp.init();
}
);
var updateUITestCase = [
{
description : 'UpdateUI executes the callback after a mode change',
applicationMode : 'DATA_USAGE_ONLY'
},
{
description :
'UpdateUI executes the callback even if there is not a mode change',
applicationMode : null
}
];
updateUITestCase.forEach(function(testCase) {
test(testCase.description, function(done) {
var applicationMode = testCase.applicationMode;
setupCardState({cardState: 'ready'});
window.ConfigManager = new MockConfigManager({
fakeSettings: { fte: true },
applicationMode: applicationMode
});
function _finalizeFTE (evt) {
window.removeEventListener('ftestarted', _finalizeFTE);
window.ConfigManager.setOption({ fte: false }, function() {
window.postMessage({ type: 'fte_finished' },
Common.COST_CONTROL_APP);
});
}
window.addEventListener('ftestarted', _finalizeFTE);
this.sinon.stub(Common, 'closeFTE', done);
CostControlApp.init();
});
});
});
});

View file

@ -0,0 +1,84 @@
/* global TopUpLayoutView */
'use strict';
requireApp('costcontrol/js/views/TopUpLayoutView.js');
suite('Top Up layout attending to configuration >', function() {
var ENABLED = true;
var DISABLED = false;
var ussdTopUpButton, codeTopUpButton, layoutView;
setup(function() {
ussdTopUpButton = document.createElement('button');
codeTopUpButton = document.createElement('button');
layoutView = new TopUpLayoutView(
ussdTopUpButton,
codeTopUpButton
);
});
function assertElementIs(element, state) {
assert.equal(element.disabled, !state);
assert.equal(!!element.hidden, !state);
}
function assertAllTopUpMethodsDisabled() {
assertElementIs(ussdTopUpButton, DISABLED);
assertElementIs(codeTopUpButton, DISABLED);
}
function assertAllTopUpMethodsEnabled() {
assertElementIs(ussdTopUpButton, ENABLED);
assertElementIs(codeTopUpButton, ENABLED);
}
function assertOnlyUSSDTopUpMethodEnabled() {
assertElementIs(ussdTopUpButton, ENABLED);
assertElementIs(codeTopUpButton, DISABLED);
}
function assertOnlyCodeTopUpMethodEnabled() {
assertElementIs(ussdTopUpButton, DISABLED);
assertElementIs(codeTopUpButton, ENABLED);
}
test(
'All top up methods are disabled and hidden (no top up section)',
function() {
layoutView.setupLayout(undefined);
assertAllTopUpMethodsDisabled();
}
);
test(
'All top up methods are disabled and hidden (empty top up section)',
function() {
layoutView.setupLayout({});
assertAllTopUpMethodsDisabled();
}
);
test('All top up methods are enabled and visible', function() {
layoutView.setupLayout({
ussd_destination: '000',
destination: '000'
});
assertAllTopUpMethodsEnabled();
});
test('Only USSD top up method is enabled and visible', function() {
layoutView.setupLayout({
ussd_destination: '000'
});
assertOnlyUSSDTopUpMethodEnabled();
});
test('Only code top up method is enabled and visible', function() {
layoutView.setupLayout({
destination: '000'
});
assertOnlyCodeTopUpMethodEnabled();
});
});

View file

@ -0,0 +1,290 @@
/* global ViewManager, MocksHelper, LazyLoader */
'use strict';
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/test/unit/mock_date.js');
require('/test/unit/mock_debug.js');
require('/test/unit/mock_moz_l10n.js');
require('/js/common.js');
require('/js/utils/toolkit.js');
require('/js/view_manager.js');
var unitTestsMockHelper = new MocksHelper([
'LazyLoader'
]).init();
suite('ViewManager suite >', function() {
unitTestsMockHelper.attachTestHelpers();
var realMozL10n, viewManager;
var view1, view2;
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
suiteSetup(function() {
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
viewManager = new ViewManager();
view1 = document.createElement('div');
view1.id = 'view-1';
view2 = document.createElement('div');
view2.id = 'view-2';
document.body.appendChild(view1);
document.body.appendChild(view2);
});
suiteTeardown(function() {
window.navigator.mozL10n = realMozL10n;
document.body.removeChild(view1);
document.body.removeChild(view2);
});
suite('Basic tests >', function() {
var realLoadPanel;
setup(function() {
realLoadPanel = viewManager.loadPanel;
viewManager.loadPanel = sinon.spy();
});
teardown(function() {
viewManager.loadPanel = realLoadPanel;
});
test('Check if a view is a tab', function() {
viewManager._tabs['is-a-tab'] = {};
assert.ok(viewManager._isTab('is-a-tab'));
assert.ok(!viewManager._isTab('not-a-tab'));
});
test('Change to a new view', function() {
viewManager.changeViewTo('view-1');
assert.ok(viewManager.loadPanel.calledWith(view1));
});
test('Trigger viewchanged event when changing to a new view',
function(done) {
viewManager.loadPanel = realLoadPanel;
window.addEventListener('viewchanged',
function onviewchanged(evt) {
window.removeEventListener('viewchanged', onviewchanged);
assert.equal(evt.detail.id, 'view-1');
done();
}
);
viewManager.changeViewTo('view-1');
}
);
test('Pass parameters when changing to a new view',
function(done) {
viewManager.loadPanel = realLoadPanel;
window.addEventListener('viewchanged',
function onviewchanged(evt) {
window.removeEventListener('viewchanged', onviewchanged);
assert.equal(evt.detail.id, 'view-2');
assert.equal(evt.detail.params.foo, 'bar');
done();
}
);
viewManager.changeViewTo('view-2?foo=bar');
}
);
test('Obscured view gets "behind" class',
function(done) {
viewManager.loadPanel = realLoadPanel;
viewManager.changeViewTo('view-1', '#view-2', function() {
assert.ok(view2.classList.contains('behind'));
viewManager.closeCurrentView();
assert.ok(!view2.classList.contains('behind'));
done();
});
}
);
});
suite('loadPanel >', function() {
var panel, callbackStub;
function fillPanelWithScriptLinks(panel) {
return [1, 2, 3].map((number) => {
var scriptLinkNode = document.createElement('script');
scriptLinkNode.src = 'app://script-' + number + '/';
scriptLinkNode.type = 'text/javascript';
panel.appendChild(scriptLinkNode);
return scriptLinkNode;
});
}
function fillPanelWithStyleLinks(panel) {
return [1, 2, 3].map((number) => {
var styleLinkNode = document.createElement('link');
styleLinkNode.href = 'app://style-' + number + '/';
styleLinkNode.type = 'text/css';
panel.appendChild(styleLinkNode);
return styleLinkNode;
});
}
function fillPanelWithGaiaHeaders(panel) {
return [1, 2, 3].map((number) => {
var gaiaHeader = document.createElement('gaia-header');
gaiaHeader.setAttribute('action', 'close');
gaiaHeader.setAttribute('id', 'header-' + number);
panel.appendChild(gaiaHeader);
return gaiaHeader;
});
}
setup(function() {
this.sinon.stub(LazyLoader, 'load');
panel = document.createElement('div');
panel.hidden = true;
callbackStub = sinon.stub();
});
test('immediately calls callback if panel is visible', function() {
panel.hidden = false;
viewManager.loadPanel(panel, callbackStub);
sinon.assert.notCalled(LazyLoader.load);
sinon.assert.calledOnce(callbackStub);
assert.isFalse(panel.hidden);
});
test('tries to lazy load panel if it is hidden', function() {
viewManager.loadPanel(panel, callbackStub);
sinon.assert.notCalled(callbackStub);
LazyLoader.load.callArg(1);
sinon.assert.calledOnce(callbackStub);
assert.isFalse(panel.hidden);
});
test('activates nested resources', function() {
// Remember how many links we had in document before
var styleLinkCount = document.querySelectorAll('head > link').length;
var scriptLinkCount = document.querySelectorAll('head > script').length;
var scriptLinks = fillPanelWithScriptLinks(panel);
var styleLinks = fillPanelWithStyleLinks(panel);
viewManager.loadPanel(panel, callbackStub);
LazyLoader.load.callArg(1);
// Callback shouldn't be called if resources aren't loaded yet
sinon.assert.notCalled(callbackStub);
assert.equal(
document.querySelectorAll('head > link').length,
styleLinkCount + styleLinks.length
);
assert.equal(
document.querySelectorAll('head > script').length,
scriptLinkCount + scriptLinks.length
);
scriptLinks.concat(styleLinks).forEach((link, index) => {
var headLink = null;
if (link.type === 'text/css') {
headLink = document.head.querySelector(
'link[href="' + link.href + '"]'
);
} else {
headLink = document.head.querySelector(
'script[src="' + link.src + '"]'
);
}
assert.isFalse(document.contains(link));
assert.isNotNull(headLink);
headLink.dispatchEvent(new CustomEvent('load'));
// Callback should be called only once all links are loaded
if (index < scriptLinks.length + styleLinks.length - 1) {
sinon.assert.notCalled(callbackStub);
} else {
sinon.assert.called(callbackStub);
}
});
});
test('does not activate already activated nested resources', function() {
var scriptLinks = fillPanelWithScriptLinks(panel);
var styleLinks = fillPanelWithStyleLinks(panel);
var allResourceLinks = scriptLinks.concat(styleLinks);
// Register resources in head, so that they are considered as activated
allResourceLinks.forEach((link) => {
document.head.appendChild(link.cloneNode());
});
// Remember how many links we had before
var styleLinkCount = document.querySelectorAll('head > link').length;
var scriptLinkCount = document.querySelectorAll('head > script').length;
viewManager.loadPanel(panel, callbackStub);
sinon.assert.notCalled(callbackStub);
LazyLoader.load.callArg(1);
// No new resources are added, so callback is called immediately
sinon.assert.calledOnce(callbackStub);
assert.equal(
document.querySelectorAll('head > link').length,
styleLinkCount
);
assert.equal(
document.querySelectorAll('head > script').length,
scriptLinkCount
);
// Resource links should be removed from panel anyway
allResourceLinks.forEach(
(link) => assert.isFalse(document.contains(link))
);
});
test('attaches gaia-header close action callbacks', function() {
var gaiaHeaders = fillPanelWithGaiaHeaders(panel);
gaiaHeaders.forEach(
(header) => this.sinon.stub(header, 'addEventListener')
);
viewManager.loadPanel(panel, callbackStub);
LazyLoader.load.callArg(1);
sinon.assert.calledOnce(callbackStub);
gaiaHeaders.forEach((header) => {
sinon.assert.calledWithExactly(
header.addEventListener, 'action', sinon.match.func
);
});
});
});
});

View file

@ -0,0 +1,101 @@
/* global VivoConfig, MockDateFactory */
'use strict';
requireApp('costcontrol/shared/js/format.js');
requireApp('costcontrol/test/unit/mock_date.js');
requireApp('costcontrol/test/unit/mock_debug.js');
requireApp('costcontrol/js/config/config_manager.js');
requireApp('costcontrol/js/config/vivo/config.js');
suite('Custom VIVO configuration Test Suite >', function() {
var VIVO_RESERVED_CHARACTER = '0';
var VIVO_MAX_MESSAGE_LENGTH = 138;
var VIVO_OPERATION_CHECK_BALANCE = '0102';
var realDate;
suiteSetup(function() {
realDate = window.Date;
window.Date = new MockDateFactory(new Date('2013-01-01T00:00:00.000Z'));
});
suiteTeardown(function() {
window.Date = realDate;
});
function VivoRequestParser(message) {
return {
get padding() {
return message.slice(0, 32);
},
get system() {
return message.slice(32, 35);
},
get date() {
return message.slice(35, 43);
},
get time() {
return message.slice(43, 49);
},
get operationType() {
return message.slice(49, 51);
},
get totalMessages() {
return message.slice(51, 52);
},
get currentMessageNumber() {
return message.slice(52, 53);
},
get reserved() {
return message.slice(53, 54);
},
get operation() {
return message.slice(54, 58);
},
get parameters() {
return message.slice(58);
}
};
}
function assertIsDate(dateString) {
var now = new Date();
var year = parseInt(dateString.slice(0, 4), 10);
var month = parseInt(dateString.slice(4, 6), 10);
var day = parseInt(dateString.slice(6, 8), 10);
assert.isTrue(0 < year && year <= now.getUTCFullYear());
assert.isTrue(0 < month && month <= 12);
assert.isTrue(0 < day && day <= 31);
}
function assertIsTime(timeString) {
var hour = parseInt(timeString.slice(0, 2), 10);
var minutes = parseInt(timeString.slice(2, 4), 10);
var seconds = parseInt(timeString.slice(4, 6), 10);
assert.isTrue(0 <= hour && hour <= 23);
assert.isTrue(0 <= minutes && minutes <= 59);
assert.isTrue(0 <= seconds && seconds <= 59);
}
test('Balance requests have the proper length', function() {
var VIVO_BALANCE_REQUEST_LENGTH = 58;
var messageBody = VivoConfig.balance.text;
assert.isTrue(messageBody.length <= VIVO_MAX_MESSAGE_LENGTH);
assert.equal(messageBody.length, VIVO_BALANCE_REQUEST_LENGTH);
});
test('Balance request matches the proper pattern', function() {
var messageBody = new VivoRequestParser(VivoConfig.balance.text);
assert.match(messageBody.padding, /[0]{32}/);
assert.equal(messageBody.system, 'OWD');
assertIsDate(messageBody.date);
assertIsTime(messageBody.time);
assert.match(messageBody.operationType, /[0-9]{2}/);
assert.equal(messageBody.totalMessages, '1');
assert.equal(messageBody.currentMessageNumber, '1');
assert.equal(messageBody.reserved, VIVO_RESERVED_CHARACTER);
assert.equal(messageBody.operation, VIVO_OPERATION_CHECK_BALANCE);
assert.equal(messageBody.parameters.length, 0);
});
});

View file

@ -0,0 +1,549 @@
/* global MockCommon, MockCostControl, MockNavigatorMozMobileConnections,
Widget, MockConfigManager, MockNavigatorMozIccManager, MockMozL10n,
MockMozNetworkStats, AirplaneModeHelper, MocksHelper,
CostControl, Formatting, _, SimManager
*/
'use strict';
require('/test/unit/mock_moz_l10n.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/test/unit/mock_debug.js');
require('/js/utils/toolkit.js');
require('/test/unit/mock_common.js');
require('/shared/test/unit/load_body_html_helper.js');
require('/shared/test/unit/mocks/mock_settings_listener.js');
require('/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js');
require('/test/unit/mock_moz_network_stats.js');
require('/shared/test/unit/mocks/mock_navigator_moz_icc_manager.js');
require('/test/unit/mock_cost_control.js');
require('/test/unit/mock_config_manager.js');
require('/test/unit/mock_airplane_mode_helper.js');
require('/shared/js/lazy_loader.js');
require('/js/views/BalanceView.js');
require('/js/utils/formatting.js');
require('/js/sim_manager.js');
require('/js/widget.js');
require('/shared/js/airplane_mode_helper.js');
var realMozMobileConnections,
realMozL10n,
realMozNetworkStats,
realMozIccManager;
if (!window.navigator.mozNetworkStats) {
window.navigator.mozNetworkStats = null;
}
if (!window.navigator.mozIccManager) {
window.navigator.mozIccManager = null;
}
if (!window.navigator.mozMobileConnections) {
window.navigator.mozMobileConnections = null;
}
if (!window.navigator.mozL10n) {
window.navigator.mozL10n = null;
}
var MocksHelperForUnitTest = new MocksHelper([
'LazyLoader',
'AirplaneModeHelper',
'ConfigManager',
'CostControl',
'SettingsListener',
'Common'
]).init();
suite('Widget Startup Modes Test Suite >', function() {
MocksHelperForUnitTest.attachTestHelpers();
var fte, rightPanel, leftPanel, showSimErrorSpy;
suiteSetup(function() {
window.Common = new MockCommon({});
realMozMobileConnections = window.navigator.mozMobileConnections;
realMozL10n = window.navigator.mozL10n;
window.navigator.mozL10n = window.MockMozL10n;
realMozNetworkStats = window.navigator.mozNetworkStats;
realMozIccManager = window.navigator.mozIccManager;
});
setup(function() {
navigator.mozIccManager = window.MockNavigatorMozIccManager;
window.navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
MockNavigatorMozMobileConnections[0] = { iccId: '12345' };
navigator.mozNetworkStats = MockMozNetworkStats;
AirplaneModeHelper._status = 'disabled';
loadBodyHTML('/widget.html');
fte = document.getElementById('fte-view');
leftPanel = document.getElementById('left-panel');
rightPanel = document.getElementById('right-panel');
// Hide all panels
fte.hidden = true;
leftPanel.hidden = true;
rightPanel.hidden = true;
showSimErrorSpy = this.sinon.spy(Widget, 'showSimError');
});
teardown(function() {
window.location.hash = '';
});
suiteTeardown(function() {
window.navigator.mozMobileConnections = realMozMobileConnections;
window.navigator.mozL10n = realMozL10n;
window.navigator.mozNetworkStats = realMozNetworkStats;
window.navigator.mozIccManager = realMozIccManager;
});
function failingRequestDataSIMIccId(onsuccess, onerror) {
setTimeout(function() {
(typeof onerror === 'function') && onerror();
}, 0);
}
function setupCardState(costControlConfig) {
window.CostControl = new MockCostControl(costControlConfig);
}
function setupConfig(applicationMode, ftePending, configuration) {
window.ConfigManager = new MockConfigManager({
fakeSettings: { fte: ftePending},
fakeConfiguration: configuration,
applicationMode: applicationMode
});
}
function assertErrorMessage(errorTag) {
assert.ok(fte.textContent.trim().contains(errorTag));
assert.ok(!fte.hidden);
assert.ok(leftPanel.hidden);
assert.ok(rightPanel.hidden);
}
var requestDataUsageResult = {
status: 'success',
data: {
mobile: {
total: 4800543137
}
}
};
var resultRequestPostpaid = {
status:'success',
type:'telephony',
data: {
timestamp: { __date__: '2014-04-14T08:35:16.812Z' },
calltime:100,
smscount:0
}
};
var resultRequestPrepaid = {
status:'success',
type:'balance',
data: {
timestamp: new Date('2014-04-14T08:35:16.812Z'),
balance: 22.34,
currency: '$'
}
};
var newCostControlRequest = function(requestedData) {
var requestedInfo = requestedData || {};
return {
request: function(requestedObj, callback) {
var resultObj = requestedInfo[requestedObj.type] || {};
callback(resultObj);
}
};
};
function assertDataUseOnlyLayout(dataTag) {
assert.ok(fte.hidden);
assert.ok(!leftPanel.hidden);
assert.ok(rightPanel.hidden);
assert.ok(leftPanel.textContent.trim().contains(dataTag));
}
function assertNonDataUseOnlyLayout(leftDataTag, rightDataTag) {
assert.ok(fte.hidden);
assert.ok(!leftPanel.hidden);
assert.ok(!rightPanel.hidden);
assert.ok(rightPanel.textContent.trim().contains(rightDataTag));
assert.ok(leftPanel.textContent.trim().contains(leftDataTag));
}
function assertFTELayout(dataTag) {
assert.ok(!fte.hidden);
assert.ok(leftPanel.hidden);
assert.ok(rightPanel.hidden);
assert.ok(fte.textContent.trim().contains(dataTag));
}
var listMandatoryAPIs = [
'mozIccManager', 'mozMobileConnections', 'mozNetworkStats'
];
listMandatoryAPIs.forEach(
function(mandatoryAPIName) {
test('Not exists the mandatory API: ' + mandatoryAPIName, function() {
window.navigator[mandatoryAPIName] = null;
Widget.init();
assertErrorMessage('widget-no-sim3-meta');
assert.ok(showSimErrorSpy.calledOnce);
assert.ok(showSimErrorSpy.calledWith('no-sim3'));
showSimErrorSpy.restore();
});
}
);
test('startup with locked sim', function(done) {
showSimErrorSpy.restore();
this.sinon.stub(Widget, 'showSimError', function(errorId) {
done (function() {
assert.equal(errorId, 'sim2-locked');
});
});
this.sinon.stub(SimManager, 'requestDataSimIcc', function(callback) {
callback({icc: {cardState: 'pinRequired'} });
});
Widget.init();
});
test('startup without sim', function(done) {
showSimErrorSpy.restore();
this.sinon.stub(Widget, 'showSimError', function(errorId) {
done (function() {
assert.equal(errorId, 'no-sim3');
});
});
this.sinon.stub(SimManager, 'requestDataSimIcc', function(callback) {
callback({icc: {} });
});
Widget.init();
});
test('Airplane Mode enabled', function(done) {
// Force loadDataSimIccId to fail
sinon.stub(SimManager, 'requestDataSimIcc', failingRequestDataSIMIccId);
sinon.stub(MockMozL10n, 'ready', function(callback) {
callback();
assert.ok(showSimErrorSpy.calledOnce);
assert.ok(showSimErrorSpy.calledWith('airplane-mode'));
assertErrorMessage('widget-airplane-mode-meta');
// Restore the spy/stub
SimManager.requestDataSimIcc.restore();
MockMozL10n.ready.restore();
showSimErrorSpy.restore();
done();
});
AirplaneModeHelper._status = 'enabled';
Widget.init();
});
test('SIM is detected after an AirplaneMode message on a previous startup',
function(done) {
// Force loadDataSimIccId to fail
sinon.stub(SimManager, 'requestDataSimIcc', failingRequestDataSIMIccId);
sinon.stub(MockMozL10n, 'ready', function(callback) {
callback();
assert.ok(showSimErrorSpy.calledOnce);
assert.ok(showSimErrorSpy.calledWith('airplane-mode'));
assertErrorMessage('widget-airplane-mode-meta');
// Restore the spy/stub
SimManager.requestDataSimIcc.restore();
MockMozL10n.ready.restore();
// Send a iccdetected event to restart the widget
AirplaneModeHelper._status = 'disabled';
setupCardState();
var ftePending = true;
var applicationMode = 'DATA_USAGE_ONLY';
setupConfig(applicationMode, ftePending);
// In a normal start-up, when the cardState ready, the widget tries to
// recover de configuration with the method getInstance
sinon.stub(CostControl, 'getInstance', function(window, callback) {
assert.equal(showSimErrorSpy.callCount, 1);
SimManager.requestDataSimIcc(function (dataSimIcc) {
assert.equal(dataSimIcc.icc.cardState, 'ready');
CostControl.getInstance.restore();
showSimErrorSpy.restore();
done();
});
});
// This event is listen on the function waitForIccAndCheckSim of the
// widget that calls SimManager.requestDataSIMIcc(checkSIMStatus); to
// restart the widget
MockNavigatorMozIccManager.triggerEventListeners('iccdetected', {});
}
);
AirplaneModeHelper._status = 'enabled';
Widget.init();
});
test('fte start-up', function() {
setupCardState();
var ftePending = true;
var applicationMode = 'DATA_USAGE_ONLY';
setupConfig(applicationMode, ftePending);
AirplaneModeHelper._status = 'disabled';
Widget.init();
assertFTELayout('widget-nonauthed-sim2-heading');
});
test('normal start-up with DATA_USAGE_ONLY applicationMode', function(done) {
assert.equal(showSimErrorSpy.notCalled, true);
var fakeResultDataUsage = {
datausage: requestDataUsageResult
};
var costControlConfig = newCostControlRequest(fakeResultDataUsage);
setupCardState(costControlConfig);
var ftePending = false;
var applicationMode = 'DATA_USAGE_ONLY';
setupConfig(applicationMode, ftePending);
window.addEventListener('hashchange', function _onHashChange(evt) {
if (window.location.hash.split('#')[1] === 'updateDone') {
window.removeEventListener('hashchange', _onHashChange);
var mobileData =
Formatting.roundData(fakeResultDataUsage.datausage.data.mobile.total);
var mobileDataText = _('magnitude', {
value: mobileData[0],
unit: mobileData[1]
});
assertDataUseOnlyLayout(mobileDataText);
SimManager.requestDataSimIcc(function (dataSimIcc) {
assert.equal(dataSimIcc.icc.cardState, 'ready');
showSimErrorSpy.restore();
done();
});
}
});
AirplaneModeHelper._status = 'disabled';
Widget.init();
});
test('normal start-up with POSTPAID applicationMode', function(done) {
assert.equal(showSimErrorSpy.notCalled, true);
sinon.stub(Formatting, 'formatTime', function(timestamp, format) {
return timestamp;
});
var fakePostPaidResult = {
datausage: requestDataUsageResult,
telephony: resultRequestPostpaid
};
var costControlConfig = newCostControlRequest(fakePostPaidResult);
setupCardState(costControlConfig);
var ftePending = false;
var applicationMode = 'POSTPAID';
setupConfig(applicationMode, ftePending);
window.addEventListener('hashchange', function _onHashChange(evt) {
if (window.location.hash.split('#')[1] === 'updateDone') {
window.removeEventListener('hashchange', _onHashChange);
var mobileData =
Formatting.roundData(fakePostPaidResult.datausage.data.mobile.total);
var mobileDataText = _('magnitude', {
value: mobileData[0],
unit: mobileData[1]
});
var telephonyData =
Formatting.computeTelephonyMinutes(fakePostPaidResult.telephony.data);
var telephonyDataText = _('magnitude', {
value: telephonyData,
unit: 'min'
});
assertNonDataUseOnlyLayout(mobileDataText, telephonyDataText);
SimManager.requestDataSimIcc(function (dataSimIcc) {
assert.equal(dataSimIcc.icc.cardState, 'ready');
showSimErrorSpy.restore();
Formatting.formatTime.restore();
done();
});
}
});
AirplaneModeHelper._status = 'disabled';
Widget.init();
});
test('normal start-up with PREPAID applicationMode', function(done) {
assert.equal(showSimErrorSpy.notCalled, true);
sinon.stub(Formatting, 'formatTime', function(timestamp, format) {
return timestamp;
});
var fakePrePaidResult = {
datausage: requestDataUsageResult,
balance: resultRequestPrepaid
};
var costControlConfig = newCostControlRequest(fakePrePaidResult);
setupCardState(costControlConfig);
var ftePending = false;
var applicationMode = 'PREPAID';
setupConfig(applicationMode, ftePending);
window.addEventListener('hashchange', function _onHashChange(evt) {
if (window.location.hash.split('#')[1] === 'updateDone') {
window.removeEventListener('hashchange', _onHashChange);
var mobileData =
Formatting.roundData(fakePrePaidResult.datausage.data.mobile.total);
var mobileDataText = _('magnitude', {
value: mobileData[0],
unit: mobileData[1]
});
var balanceDataText = _('currency', {
value: fakePrePaidResult.balance.data.balance,
currency: fakePrePaidResult.balance.data.currency
});
var balanceView = document.getElementById('balance-view');
assert.isTrue(balanceView.classList.contains('updating'));
assertNonDataUseOnlyLayout(mobileDataText, balanceDataText);
SimManager.requestDataSimIcc(function (dataSimIcc) {
assert.equal(dataSimIcc.icc.cardState, 'ready');
showSimErrorSpy.restore();
Formatting.formatTime.restore();
done();
});
}
});
AirplaneModeHelper._status = 'disabled';
Widget.init();
});
test('DSDS start-up after SIM switching: from data usage only SIM to ' +
'prepaid SIM',
function(done) {
/*
Related to:
Bug 1128493 - [CostControl] Widget broken after switching data sim
*/
// SETUP TEST
var ftePending = false;
var self = this;
var fakeResult = {
datausage: requestDataUsageResult,
balance: resultRequestPrepaid
};
this.sinon.stub(SimManager, 'isMultiSim').returns(true);
this.sinon.stub(window.CostControl, 'getInstance')
.yields(newCostControlRequest(fakeResult));
function assertPrepaidDataLayout() {
var balanceDataText = _('currency', {
value: fakeResult.balance.data.balance,
currency: fakeResult.balance.data.currency
});
assertNonDataUseOnlyLayout('', balanceDataText);
return Promise.resolve();
}
function setupDataUsageOnlySIM() {
return new Promise(function(resolve) {
setupConfig('DATA_USAGE_ONLY', ftePending);
// Waiting for the end of the first startup (data_Usage_Only mode)
window.addEventListener('hashchange', function _onHashChange(evt) {
var message = window.location.hash.split('#')[1];
if (message === 'updateDone') {
window.removeEventListener('hashchange', _onHashChange);
resolve(done);
}
});
});
}
function assertDataUsageOnlyLayout() {
// right Panel is hidden when data_usage_only mode is loaded
assert.ok(rightPanel.hidden);
return Promise.resolve();
}
function setupPrepaidSim() {
return new Promise(function(resolve) {
self.sinon.stub(window.ConfigManager, 'getApplicationMode',
function() {
// updating prepaid configuration
var fakeConfiguration = {
balance: {
minimum_delay: 3 * 60 * 60 * 1000 // 3h
},
is_free: false,
is_roaming_free: false
};
setupConfig('PREPAID', false, fakeConfiguration);
return 'PREPAID';
}
);
// Waiting for the end of the second startup (with prepaid sim)
window.addEventListener('hashchange', function _onHashChange(evt) {
var message = window.location.hash.split('#')[1];
if (message === 'updateDone') {
window.removeEventListener('hashchange', _onHashChange);
resolve(done);
}
});
// Simulating a data slot change
var serviceSlotChangeEvent = new CustomEvent('dataSlotChange');
window.dispatchEvent(serviceSlotChangeEvent);
});
}
setupDataUsageOnlySIM()
.then(assertDataUsageOnlyLayout)
.then(setupPrepaidSim)
.then(assertPrepaidDataLayout)
.catch(function() {
assert.isTrue(false);
}).then(done, done);
AirplaneModeHelper._status = 'disabled';
Widget.init();
});
});