'use strict';
/* global AppUpdatable, Service, UpdateManager, l10nAssert,
MockApp, MockAppUpdatable, MockAppsMgmt, MockChromeEvent,
MockCustomDialog, MocksHelper, MockL10n, MockMozActivity,
MockNavigatorMozMobileConnections, MockNavigatorSettings,
MockNavigatorWakeLock, MockNotificationScreen,
MockSettingsListener, MockSystemBanner, MockSystemUpdatable */
require('/shared/js/component_utils.js');
require('/shared/elements/gaia_checkbox/script.js');
requireApp('system/js/update_manager.js');
requireApp('system/test/unit/mock_app.js');
requireApp('system/test/unit/mock_updatable.js');
requireApp('system/test/unit/mock_apps_mgmt.js');
requireApp('system/shared/test/unit/mocks/mock_custom_dialog.js');
requireApp('system/test/unit/mock_utility_tray.js');
requireApp('system/test/unit/mock_system_banner.js');
requireApp('system/test/unit/mock_chrome_event.js');
requireApp('system/test/unit/mock_lazy_loader.js');
requireApp('system/shared/test/unit/mocks/mock_settings_listener.js');
requireApp('system/js/service.js');
requireApp('system/test/unit/mock_notification_screen.js');
requireApp('system/shared/test/unit/mocks/mock_moz_activity.js');
requireApp('system/shared/test/unit/mocks/mock_navigator_moz_settings.js');
requireApp('system/shared/test/unit/mocks/mock_navigator_wake_lock.js');
require(
'/shared/test/unit/mocks/mock_navigator_moz_mobile_connections.js');
require('/shared/test/unit/mocks/mock_l10n.js');
requireApp('system/test/unit/mock_asyncStorage.js');
require('/test/unit/mock_update_manager.js');
var mocksForUpdateManager = new MocksHelper([
'SystemBanner',
'NotificationScreen',
'CustomDialog',
'SystemUpdatable',
'AppUpdatable',
'SettingsListener',
'asyncStorage',
'LazyLoader',
'MozActivity'
]).init();
suite('system/UpdateManager', function() {
var realL10n;
var realWifiManager;
var realRequestWakeLock;
var realNavigatorSettings;
var realDispatchEvent;
var realMozMobileConnections;
var apps;
var updatableApps;
var uAppWithDownloadAvailable;
var appWithDownloadAvailable;
var fakeNode;
var fakeToaster;
var fakeDialog;
var fakeWarning;
var TINY_TIMEOUT = 10;
var lastDispatchedEvent = null;
var MOBILE_CONNECTION_COUNT = 2;
mocksForUpdateManager.attachTestHelpers();
suiteSetup(function() {
realNavigatorSettings = navigator.mozSettings;
navigator.mozSettings = MockNavigatorSettings;
realL10n = navigator.mozL10n;
navigator.mozL10n = MockL10n;
realWifiManager = navigator.mozWifiManager;
navigator.mozWifiManager = {
connection: {
status: 'connected'
}
};
realMozMobileConnections = navigator.mozMobileConnections;
navigator.mozMobileConnections = MockNavigatorMozMobileConnections;
for (var i = 0; i < MOBILE_CONNECTION_COUNT; i++) {
MockNavigatorMozMobileConnections.mAddMobileConnection();
MockNavigatorMozMobileConnections[i].data = {
connected: !i,
type: (!i ? 'evdo0' : undefined),
roaming: (!i ? true : undefined)
};
}
realRequestWakeLock = navigator.requestWakeLock;
navigator.requestWakeLock = MockNavigatorWakeLock.requestWakeLock;
realDispatchEvent = UpdateManager._dispatchEvent;
UpdateManager._dispatchEvent = function fakeDispatch(type, value) {
lastDispatchedEvent = {
type: type,
value: value
};
};
});
suiteTeardown(function() {
navigator.mozSettings = realNavigatorSettings;
realNavigatorSettings = null;
navigator.mozL10n = realL10n;
navigator.mozWifiManager = realWifiManager;
navigator.requestWakeLock = realRequestWakeLock;
realRequestWakeLock = null;
MockNavigatorMozMobileConnections.mTeardown();
navigator.mozMobileConnections = realMozMobileConnections;
UpdateManager._dispatchEvent = realDispatchEvent;
});
setup(function() {
this.sinon.stub(Service, 'request', function(action) {
if (action === 'showCustomDialog') {
MockCustomDialog.show(arguments[1],
arguments[2], arguments[3], arguments[4]);
} else if (action === 'hideCustomDialog') {
MockCustomDialog.hide(arguments[1],
arguments[2], arguments[3], arguments[4]);
}
});
// they are automatically restored at teardown by the test agent
this.sinon.useFakeTimers();
UpdateManager._mgmt = MockAppsMgmt;
apps = [new MockApp(), new MockApp(), new MockApp()];
updatableApps = apps.map(function(app) {
return new AppUpdatable(app);
});
MockAppsMgmt.mApps = apps;
uAppWithDownloadAvailable = updatableApps[2];
appWithDownloadAvailable = apps[2];
appWithDownloadAvailable.downloadAvailable = true;
fakeNode = document.createElement('div');
fakeNode.id = 'update-manager-container';
fakeNode.innerHTML = [
'
',
'',
''
].join('');
fakeToaster = document.createElement('div');
fakeToaster.id = 'update-manager-toaster';
fakeToaster.innerHTML = [
'',
'
',
'',
'
'
].join('');
fakeDialog = document.createElement('form');
fakeDialog.id = 'updates-download-dialog';
fakeDialog.innerHTML = [
'',
'',
'Updates',
'
',
'',
'',
''
].join('');
fakeWarning = document.createElement('form');
fakeWarning.id = 'updates-viaDataConnection-dialog';
fakeWarning.innerHTML = [
'',
'',
'Updates',
'
',
'',
'
',
'',
''
].join('');
document.body.appendChild(fakeNode);
document.body.appendChild(fakeToaster);
document.body.appendChild(fakeDialog);
document.body.appendChild(fakeWarning);
});
teardown(function() {
UpdateManager.updatableApps = [];
UpdateManager.systemUpdatable = null;
UpdateManager.updatesQueue = [];
UpdateManager.downloadsQueue = [];
UpdateManager._downloading = false;
UpdateManager._uncompressing = false;
UpdateManager.container = null;
UpdateManager.message = null;
UpdateManager.toaster = null;
UpdateManager.toasterMessage = null;
UpdateManager.laterButton = null;
UpdateManager.downloadButton = null;
UpdateManager.downloadDialog = null;
UpdateManager.downloadDialogTitle = null;
UpdateManager.downloadDialogList = null;
UpdateManager.lastUpdatesAvailable = 0;
UpdateManager._notificationTimeout = null;
UpdateManager._errorTimeout = null;
MockAppsMgmt.mTeardown();
fakeNode.parentNode.removeChild(fakeNode);
fakeToaster.parentNode.removeChild(fakeToaster);
fakeDialog.parentNode.removeChild(fakeDialog);
lastDispatchedEvent = null;
MockNavigatorWakeLock.mTeardown();
MockNavigatorSettings.mTeardown();
});
suite('init', function() {
test('should get all applications', function() {
this.sinon.stub(MockAppsMgmt, 'getAll').returns({});
UpdateManager.start();
sinon.assert.called(MockAppsMgmt.getAll);
});
test('should create AppUpdatable on init', function() {
MockAppUpdatable.mTeardown();
var request = {};
this.sinon.stub(MockAppsMgmt, 'getAll').returns(request);
UpdateManager.start();
assert.isFunction(request.onsuccess);
request.onsuccess({
target: {
result: apps
}
});
assert.equal(MockAppUpdatable.mCount, apps.length);
});
test('should bind dom elements', function() {
UpdateManager.start();
assert.equal('update-manager-container', UpdateManager.container.id);
assert.equal('title-container', UpdateManager.message.className);
assert.equal('update-manager-toaster', UpdateManager.toaster.id);
assert.equal('message', UpdateManager.toasterMessage.className);
assert.equal('updates-later-button', UpdateManager.laterButton.id);
assert.equal('updates-download-button', UpdateManager.downloadButton.id);
assert.equal('updates-download-dialog', UpdateManager.downloadDialog.id);
assert.equal('updates-viaDataConnection-dialog',
UpdateManager.downloadViaDataConnectionDialog.id);
assert.equal('updates-viaDataConnection-notnow-button',
UpdateManager.notnowButton.id);
assert.equal('updates-viaDataConnection-download-button',
UpdateManager.downloadViaDataConnectionButton.id);
assert.equal('H1', UpdateManager.downloadDialogTitle.tagName);
assert.equal('UL', UpdateManager.downloadDialogList.tagName);
});
test('should bind to the click event', function() {
UpdateManager.start();
assert.equal(UpdateManager.containerClicked.name,
UpdateManager.container.onclick.name);
assert.equal(UpdateManager.toasterClicked.name,
UpdateManager.toaster.onclick.name);
assert.equal(UpdateManager.requestDownloads.name,
UpdateManager.downloadButton.onclick.name);
assert.equal(UpdateManager.cancelPrompt.name,
UpdateManager.laterButton.onclick.name);
assert.equal(UpdateManager.cancelDataConnectionUpdatesPrompt.name,
UpdateManager.notnowButton.onclick.name);
assert.equal(UpdateManager.requestDownloads.name,
UpdateManager.downloadViaDataConnectionButton.onclick.name);
});
});
suite('events', function() {
suite('app install', function() {
var installedApp;
setup(function() {
MockAppUpdatable.mTeardown();
MockAppsMgmt.mApps = [];
UpdateManager.start();
installedApp = new MockApp();
installedApp.downloadAvailable = true;
MockAppsMgmt.mTriggerOninstall(installedApp);
});
test('should instantiate an updatable app', function() {
assert.equal(MockAppUpdatable.mCount, 1);
});
});
suite('app uninstall', function() {
var partialApp;
setup(function() {
UpdateManager.start();
UpdateManager.updatableApps = updatableApps;
UpdateManager.addToUpdatesQueue(uAppWithDownloadAvailable);
partialApp = {
origin: appWithDownloadAvailable.origin,
manifestURL: appWithDownloadAvailable.manifestURL
};
});
test('should remove the updatable app', function() {
var initialLength = UpdateManager.updatableApps.length;
MockAppsMgmt.mTriggerOnuninstall(partialApp);
assert.equal(initialLength - 1, UpdateManager.updatableApps.length);
});
test('should remove from the update queue', function() {
var initialLength = UpdateManager.updatesQueue.length;
MockAppsMgmt.mTriggerOnuninstall(partialApp);
assert.equal(initialLength - 1, UpdateManager.updatesQueue.length);
});
test('should remove from the update queue even if no downloadavailable',
function() {
uAppWithDownloadAvailable.app.downloadAvailable = false;
var initialLength = UpdateManager.updatesQueue.length;
MockAppsMgmt.mTriggerOnuninstall(partialApp);
assert.equal(initialLength - 1, UpdateManager.updatesQueue.length);
});
test('should call uninit on the updatable', function() {
var lastIndex = UpdateManager.updatesQueue.length - 1;
var updatableApp = UpdateManager.updatesQueue[lastIndex];
MockAppsMgmt.mTriggerOnuninstall(partialApp);
assert.isTrue(updatableApp.mUninitCalled);
});
});
suite('system update available', function() {
var event;
setup(function() {
UpdateManager.start();
event = new MockChromeEvent({
type: 'update-available',
size: 42
});
UpdateManager.handleEvent(event);
});
test('should add a system updatable to the updates', function() {
var lastIndex = UpdateManager.updatesQueue.length - 1;
assert.equal(undefined, UpdateManager.updatesQueue[lastIndex].app);
});
test('should init the updatable with the download size', function() {
var lastIndex = UpdateManager.updatesQueue.length - 1;
assert.equal(42, UpdateManager.updatesQueue[lastIndex].size);
});
test('should not add or instanciate a system updatable if there is one',
function() {
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.handleEvent(event);
assert.equal(UpdateManager.updatesQueue.length, initialLength);
assert.equal(MockSystemUpdatable.mInstancesCount, 1);
});
test('should remember that update is available', function() {
assert.isTrue(UpdateManager.systemUpdatable.mKnownUpdate);
});
});
suite('no system update available', function() {
setup(function() {
UpdateManager.start();
});
test('should not remember about the update', function() {
assert.isUndefined(UpdateManager.systemUpdatable.mKnownUpdate);
});
});
suite('device locked', function() {
setup(function() {
UpdateManager.start();
});
test('should close all dialogs', function() {
UpdateManager.showDownloadPrompt();
window.dispatchEvent(new CustomEvent('lockscreen-appopened'));
assert.isFalse(UpdateManager.downloadDialog.
classList.contains('visible'));
assert.isFalse(UpdateManager.downloadViaDataConnectionDialog.
classList.contains('visible'));
assert.isFalse(MockCustomDialog.mShown);
});
test('should decline install if showing apply prompt', function() {
this.sinon.spy(UpdateManager.systemUpdatable, 'declineInstallWait');
UpdateManager.systemUpdatable.showingApplyPrompt = true;
window.dispatchEvent(new CustomEvent('lockscreen-appopened'));
assert.isTrue(
UpdateManager.systemUpdatable.declineInstallWait.calledOnce);
});
var testCases = [
{
title: 'should dispatchEvent updatepromptshown, showDownloadPrompt',
eventType: 'updatepromptshown',
method: 'showDownloadPrompt'
},
{
title: 'should dispatchEvent updatepromptshown,' +
'showPromptWifiPrioritized',
eventType: 'updatepromptshown',
method: 'showPromptWifiPrioritized'
},
{
title: 'should dispatchEvent updatepromptshown,' +
'showForbiddenDownload',
eventType: 'updatepromptshown',
method: 'showForbiddenDownload'
},
{
title: 'should dispatchEvent updatepromptshown,' +
'showPromptNoConnection',
eventType: 'updatepromptshown',
method: 'showPromptNoConnection'
},
{
title: 'should dispatchEvent updateprompthidden,' +
' cancelPrompt',
eventType: 'updateprompthidden',
method: 'cancelPrompt'
}
];
testCases.forEach(function(testCase) {
test(testCase.title, function(done) {
window.addEventListener(testCase.eventType, function listener(evt) {
window.removeEventListener(testCase.eventType, listener);
assert.equal(testCase.eventType, evt.type);
done();
});
switch (testCase.method) {
case 'showDownloadPrompt':
UpdateManager.showDownloadPrompt();
break;
case 'showPromptWifiPrioritized':
UpdateManager.showPromptWifiPrioritized();
break;
case 'showForbiddenDownload':
UpdateManager.showForbiddenDownload();
break;
case 'showPromptNoConnection':
UpdateManager.showPromptNoConnection();
break;
case 'cancelPrompt':
UpdateManager.cancelPrompt();
break;
}
});
});
// Places to create new custom dialog
var hasDialogTestCases = [
{
method: 'containerClicked'
},
{
method: 'showPromptWifiPrioritized'
},
{
method: 'showForbiddenDownload'
},
{
method: 'showPromptNoConnection'
}
];
hasDialogTestCases.forEach(function(testCase) {
test('should close all dialogs when ' + testCase.method +
' dialog is opened', function() {
switch (testCase.method) {
case 'containerClicked':
UpdateManager._downloading = true;
UpdateManager.containerClicked();
break;
case 'showPromptWifiPrioritized':
UpdateManager.showPromptWifiPrioritized();
break;
case 'showForbiddenDownload':
UpdateManager.showForbiddenDownload();
break;
case 'showPromptNoConnection':
UpdateManager.showPromptNoConnection();
break;
}
window.dispatchEvent(new CustomEvent('lockscreen-appopened'));
assert.isFalse(UpdateManager.downloadDialog.
classList.contains('visible'));
assert.isFalse(UpdateManager.downloadViaDataConnectionDialog.
classList.contains('visible'));
assert.isFalse(MockCustomDialog.mShown);
assert.ok(Service.request.calledWith('hideCustomDialog'));
});
});
});
suite('home button events', function() {
setup(function() {
UpdateManager.start();
});
test('should close dialogs when home button is pressed',
function () {
UpdateManager.showDownloadPrompt();
window.dispatchEvent(new CustomEvent('home'));
assert.ok(Service.request.calledWith('hideCustomDialog'));
});
test('should close dialogs when home button is held',
function () {
UpdateManager.showDownloadPrompt();
window.dispatchEvent(new CustomEvent('holdhome'));
assert.ok(Service.request.calledWith('hideCustomDialog'));
});
test('should not close dialogs when none exist (home button)',
function() {
window.dispatchEvent(new CustomEvent('home'));
assert.isFalse(Service.request.calledWith('hideCustomDialog'));
});
test('should not close dialogs when none exist (hold home button)',
function() {
window.dispatchEvent(new CustomEvent('holdhome'));
assert.isFalse(Service.request.calledWith('hideCustomDialog'));
});
});
});
suite('UI', function() {
setup(function() {
MockAppsMgmt.mApps = [];
UpdateManager.start();
UpdateManager.updatableApps = updatableApps;
});
teardown(function() {
});
suite('downloading state', function() {
test('should add the css class if downloading', function() {
UpdateManager._downloading = true;
UpdateManager.render();
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('downloading'));
});
test('should remove the css class if not downloading', function() {
UpdateManager._downloading = true;
UpdateManager.render();
UpdateManager._downloading = false;
UpdateManager.render();
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('downloading'));
});
test('should show the downloading progress if downloading', function() {
UpdateManager._downloading = true;
UpdateManager.render();
var l10nAttrs = MockL10n.getAttributes(UpdateManager.message);
assert.equal(l10nAttrs.id, 'downloadingUpdateMessage');
assert.deepEqual(l10nAttrs.args, { progress: '0.00 bytes' });
});
suite('if downloading', function() {
setup(function() {
UpdateManager._downloading = true;
UpdateManager.addToUpdatesQueue(uAppWithDownloadAvailable);
this.sinon.clock.tick(UpdateManager.TOASTER_TIMEOUT);
});
test('should not show the toaster', function() {
var css = UpdateManager.toaster.classList;
assert.isFalse(css.contains('displayed'));
});
});
test('should show the available message if not downloading', function() {
UpdateManager.updatesQueue = updatableApps;
UpdateManager.render();
var l10nAttrs = MockL10n.getAttributes(UpdateManager.message);
assert.equal(l10nAttrs.id, 'updateAvailableInfo');
assert.deepEqual(l10nAttrs.args, { n: 3 });
});
test('should show the system app available message if not downloading ' +
'and only a system update is present',
function() {
UpdateManager.updatesQueue = [new MockSystemUpdatable()];
UpdateManager.render();
l10nAssert(UpdateManager.message, 'systemUpdateAvailableInfo');
});
});
suite('progress display', function() {
setup(function() {
UpdateManager.updatesQueue = [uAppWithDownloadAvailable];
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, true);
UpdateManager.startDownloads(evt);
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
UpdateManager.downloadProgressed(1234);
});
test('downloadedBytes should be reset by startDownloads', function() {
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, true);
UpdateManager.startDownloads(evt);
var l10nAttrs = MockL10n.getAttributes(UpdateManager.message);
assert.equal(l10nAttrs.id, 'downloadingUpdateMessage');
assert.deepEqual(l10nAttrs.args, { progress: '0.00 bytes' });
});
test('downloadedBytes should be reset when stopping the download',
function() {
UpdateManager.removeFromDownloadsQueue(uAppWithDownloadAvailable);
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
var l10nAttrs = MockL10n.getAttributes(UpdateManager.message);
assert.equal(l10nAttrs.id, 'downloadingUpdateMessage');
assert.deepEqual(l10nAttrs.args, { progress: '0.00 bytes' });
});
test('should increment the downloadedBytes', function() {
UpdateManager.downloadProgressed(100);
var l10nAttrs = MockL10n.getAttributes(UpdateManager.message);
assert.equal(l10nAttrs.id, 'downloadingUpdateMessage');
assert.deepEqual(l10nAttrs.args, { progress: '1.30 kB' });
});
test('should not update if bytes <= 0', function() {
UpdateManager.downloadProgressed(-100);
var l10nAttrs = MockL10n.getAttributes(UpdateManager.message);
assert.equal(l10nAttrs.id, 'downloadingUpdateMessage');
assert.deepEqual(l10nAttrs.args, { progress: '1.21 kB' });
});
test('should display the notification', function() {
assert.isTrue(fakeNode.classList.contains('displayed'));
});
});
suite('uncompress display', function() {
var systemUpdatable;
setup(function() {
systemUpdatable = new MockSystemUpdatable();
});
suite('when we only have the system update', function() {
setup(function() {
UpdateManager.addToUpdatesQueue(systemUpdatable);
UpdateManager.addToDownloadsQueue(systemUpdatable);
UpdateManager.startedUncompressing();
});
test('should render in uncompressing mode', function() {
assert.equal(UpdateManager.message.getAttribute('data-l10n-id'),
'uncompressingMessage');
});
});
suite('when we have various ongoing updates', function() {
setup(function() {
UpdateManager.addToUpdatableApps(uAppWithDownloadAvailable);
UpdateManager.addToUpdatesQueue(uAppWithDownloadAvailable);
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
UpdateManager.addToUpdatesQueue(systemUpdatable);
UpdateManager.addToDownloadsQueue(systemUpdatable);
UpdateManager.startedUncompressing();
});
test('should stay in downloading mode', function() {
assert.include(UpdateManager.message.getAttribute('data-l10n-id'),
'downloadingUpdateMessage');
});
suite('once the app updates are done', function() {
setup(function() {
UpdateManager.removeFromDownloadsQueue(uAppWithDownloadAvailable);
UpdateManager.removeFromUpdatesQueue(uAppWithDownloadAvailable);
});
test('should render in uncompressing mode', function() {
assert.equal(UpdateManager.message.getAttribute('data-l10n-id'),
'uncompressingMessage');
});
});
});
});
suite('container visibility', function() {
setup(function() {
UpdateManager.addToUpdatesQueue(uAppWithDownloadAvailable);
});
suite('notification behavior after addToDownloadsQueue', function() {
setup(function() {
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
});
test('should be displayed only once', function() {
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(
MockNotificationScreen.wasMethodCalled.addUnreadNotification,
1);
});
test('should not be displayed again after timeout', function() {
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(
MockNotificationScreen.wasMethodCalled.addUnreadNotification,
1);
});
});
suite('notification behavior after addToDownloadsQueue after timeout',
function() {
// context is: uAppWithDownloadAvailable was added to updates queue
setup(function() {
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
});
test('should not increment the counter if already displayed',
function() {
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(
MockNotificationScreen.wasMethodCalled.addUnreadNotification,
1);
});
});
suite('displaying the container after a timeout', function() {
// context is: uAppWithDownloadAvailable was added to updates queue
setup(function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
});
test('should display after a timeout', function() {
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(
MockNotificationScreen.wasMethodCalled.addUnreadNotification,
1);
});
test('should not display if there are no more updates', function() {
UpdateManager.updatesQueue.forEach(function(uApp) {
UpdateManager.removeFromUpdatesQueue(uApp);
});
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
});
test('should display an updated count', function() {
UpdateManager.addToUpdatesQueue(updatableApps[1]);
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
var l10nAttrs = MockL10n.getAttributes(
UpdateManager.message);
assert.equal(l10nAttrs.id, 'updateAvailableInfo');
assert.deepEqual(l10nAttrs.args, { n: 2 });
});
suite('update toaster', function() {
test('should display after a timeout', function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
css = UpdateManager.toaster.classList;
assert.isTrue(css.contains('displayed'));
var l10nAttrs = MockL10n.getAttributes(
UpdateManager.toasterMessage);
assert.equal(l10nAttrs.id, 'updateAvailableInfo');
assert.deepEqual(l10nAttrs.args, { n: 1 });
});
test('should reset toaster value when notification was activated',
function() {
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
UpdateManager.addToUpdatesQueue(updatableApps[1]);
var l10nAttrs = MockL10n.getAttributes(
UpdateManager.toasterMessage);
assert.equal(l10nAttrs.id, 'updateAvailableInfo');
assert.deepEqual(l10nAttrs.args, { n: 1 });
});
test('should show the right message', function() {
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
var l10nAttrs = MockL10n.getAttributes(
UpdateManager.toasterMessage);
assert.equal(l10nAttrs.id, 'updateAvailableInfo');
assert.deepEqual(l10nAttrs.args, { n: 1 });
});
test('should hide after TOASTER_TIMEOUT', function() {
UpdateManager.addToUpdatesQueue(updatableApps[1]);
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
this.sinon.clock.tick(UpdateManager.TOASTER_TIMEOUT);
var css = UpdateManager.toaster.classList;
assert.isFalse(css.contains('displayed'));
});
});
test('should add a new statusbar notification', function() {
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
var method1 = 'addUnreadNotification';
assert.ok(MockNotificationScreen.wasMethodCalled[method1]);
});
});
suite('should show download prompt when tap on toaster', function() {
setup(function() {
UpdateManager._downloading = false;
UpdateManager.toasterClicked();
});
test('should hide the utility tray', function() {
assert.isTrue(Service.request.calledWith('UtilityTray:hide'));
});
test('should show the download dialog', function() {
var css = UpdateManager.downloadDialog.classList;
assert.isTrue(css.contains('visible'));
});
});
suite('no more updates', function() {
setup(function() {
UpdateManager.container.classList.add('displayed');
UpdateManager.updatesQueue = [uAppWithDownloadAvailable];
UpdateManager.removeFromUpdatesQueue(uAppWithDownloadAvailable);
});
test('should hide the container', function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
});
test('should decrease the external notifications count', function() {
var method1 = 'removeUnreadNotification';
assert.ok(MockNotificationScreen.wasMethodCalled[method1]);
});
});
});
suite('after downloads', function() {
test('should check if new updates where found', function() {
var uApp = updatableApps[0];
UpdateManager.updatableApps = updatableApps;
UpdateManager.downloadsQueue = [uApp];
UpdateManager.removeFromDownloadsQueue(uApp);
assert.equal(uAppWithDownloadAvailable.app.mId,
UpdateManager.updatesQueue[0].app.mId);
});
});
suite('error banner requests', function() {
setup(function() {
UpdateManager.start();
UpdateManager.requestErrorBanner();
});
test('should wait before showing the system banner', function() {
assert.equal(0, MockSystemBanner.mShowCount);
});
test('should show after NOTIFICATION_BUFFERING_TIMEOUT', function() {
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
assert.equal(1, MockSystemBanner.mShowCount);
assert.equal('downloadError', MockSystemBanner.mMessage);
});
test('should show only once if called multiple time', function() {
UpdateManager.requestErrorBanner();
this.sinon.clock.tick(UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT);
assert.equal(1, MockSystemBanner.mShowCount);
});
});
suite('humanizeSize', function() {
test('should handle 0', function() {
assert.equal('0.00 bytes', UpdateManager._humanizeSize(0));
});
test('should handle bytes size', function() {
assert.equal('42.00 bytes', UpdateManager._humanizeSize(42));
});
test('should handle kilobytes size', function() {
assert.equal('1.00 kB', UpdateManager._humanizeSize(1024));
});
test('should handle megabytes size', function() {
assert.equal('4.67 MB', UpdateManager._humanizeSize(4901024));
});
test('should handle gigabytes size', function() {
assert.equal('3.73 GB', UpdateManager._humanizeSize(4000901024));
});
});
});
suite('actions', function() {
setup(function() {
UpdateManager.start();
});
suite('start downloads', function() {
var systemUpdatable, appUpdatable, evt;
setup(function() {
systemUpdatable = new MockSystemUpdatable();
appUpdatable = new MockAppUpdatable(new MockApp());
appUpdatable.name = 'Angry birds';
appUpdatable.size = '423459';
UpdateManager.addToUpdatableApps(appUpdatable);
UpdateManager.addToUpdatesQueue(appUpdatable);
UpdateManager.addToUpdatesQueue(systemUpdatable);
UpdateManager.container.click();
evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, true);
});
suite('data connection warning', function() {
var downloadDialog;
setup(function() {
downloadDialog = UpdateManager.downloadDialog;
});
teardown(function() {
navigator.mozWifiManager.connection.status = 'connected';
});
test('should switch the online data attribute when online',
function() {
downloadDialog.dataset.online = false;
window.dispatchEvent(new CustomEvent('online'));
assert.equal(downloadDialog.dataset.online, 'true');
});
test('should leave the online data attribute true when online',
function() {
downloadDialog.dataset.online = true;
window.dispatchEvent(new CustomEvent('online'));
assert.equal(downloadDialog.dataset.online, 'true');
});
test('should switch the nowifi data attribute when connected',
function() {
downloadDialog.dataset.nowifi = true;
window.dispatchEvent(new CustomEvent('wifi-statuschange'));
assert.equal(downloadDialog.dataset.nowifi, 'false');
});
test('should switch the nowifi data attribute when disconnected',
function() {
downloadDialog.dataset.nowifi = false;
navigator.mozWifiManager.connection.status = 'disconnected';
window.dispatchEvent(new CustomEvent('wifi-statuschange'));
assert.equal(downloadDialog.dataset.nowifi, 'true');
});
});
test('should enable the download button', function() {
var downloadButton = UpdateManager.downloadButton;
assert.isFalse(downloadButton.disabled);
});
suite('with all the checkboxes checked', function() {
setup(function() {
UpdateManager.startDownloads(evt);
});
test('should download system updates', function() {
assert.isTrue(systemUpdatable.mDownloadCalled);
});
test('should call download on checked app updatables', function() {
assert.isTrue(appUpdatable.mDownloadCalled);
});
});
suite('with no checkbox checked', function() {
setup(function() {
var dialog = UpdateManager.downloadDialogList;
var checkboxes = dialog.querySelectorAll('gaia-checkbox');
for (var i = 0; i < checkboxes.length; i++) {
var checkbox = checkboxes[i];
if (checkbox.checked) {
checkbox.checked = false;
}
}
UpdateManager.startDownloads(evt);
});
test('the download button should be enabled', function() {
assert.isFalse(UpdateManager.downloadButton.disabled);
});
test('should still download system updates', function() {
assert.isTrue(systemUpdatable.mDownloadCalled);
});
test('should not call download on unchecked app updatables',
function() {
assert.isFalse(appUpdatable.mDownloadCalled);
});
});
suite('with only app updates', function() {
setup(function() {
UpdateManager.removeFromUpdatesQueue(systemUpdatable);
UpdateManager.container.click();
});
suite('unchecking all the checkboxes', function() {
var dialog, downloadButton;
setup(function() {
dialog = UpdateManager.downloadDialogList;
var checkboxes = dialog.querySelectorAll('gaia-checkbox');
for (var i = 0; i < checkboxes.length; i++) {
var checkbox = checkboxes[i];
if (checkbox.checked) {
checkboxes[i].checked = false;
// Trigger an onchange event.
UpdateManager.updateDownloadButton();
}
}
downloadButton = UpdateManager.downloadButton;
});
test('should disable the download button', function() {
assert.isTrue(downloadButton.disabled);
});
suite('then checking one back', function() {
setup(function() {
var checkbox = dialog.querySelector('gaia-checkbox');
checkbox.checked = !checkbox.checked;
UpdateManager.updateDownloadButton();
});
test('should enable the download button back', function() {
assert.isFalse(downloadButton.disabled);
});
});
// Bug 830901 - Disabling all checkboxes in the update prompt...
suite('cancel and reopen', function() {
setup(function() {
// cancel
UpdateManager.cancelPrompt();
// reopen
UpdateManager.containerClicked();
});
test('should check all checkboxes', function() {
var checkboxes = dialog.querySelectorAll(
'gaia-checkbox'
);
for (var i = 0; i < checkboxes.length; i++) {
var checkbox = checkboxes[i];
assert.isTrue(checkbox.checked);
}
});
test('should enable the download button', function() {
assert.isFalse(downloadButton.disabled);
});
});
});
});
});
suite('cancel all downloads', function() {
var systemUpdatable;
setup(function() {
systemUpdatable = new MockSystemUpdatable();
UpdateManager.updatableApps = updatableApps;
[systemUpdatable, uAppWithDownloadAvailable].forEach(
function(updatable) {
UpdateManager.addToUpdatesQueue(updatable);
UpdateManager.addToDownloadsQueue(updatable);
});
UpdateManager.cancelAllDownloads();
});
test('should call cancelDownload on the app updatables', function() {
assert.isTrue(uAppWithDownloadAvailable.mCancelCalled);
});
test('should call cancelDownload on the system updatable', function() {
assert.isTrue(systemUpdatable.mCancelCalled);
});
test('should empty the downloads queue', function() {
assert.equal(UpdateManager.downloadsQueue.length, 0);
});
test('should leave the updates available', function() {
assert.equal(UpdateManager.updatesQueue.length, 2);
});
});
suite('downloaded', function() {
var updatableApp, downloadDialog;
setup(function() {
UpdateManager.start();
var installedApp = new MockApp();
updatableApp = new MockAppUpdatable(installedApp);
UpdateManager.updatableApps = [updatableApp];
downloadDialog = UpdateManager.downloadDialog;
});
test('should handle downloaded when started using data connection',
function() {
UpdateManager._startedDownloadUsingDataConnection = true;
UpdateManager.downloaded(updatableApp);
assert.isFalse(UpdateManager._startedDownloadUsingDataConnection);
});
test('should handle downloaded when started using wifi', function() {
UpdateManager._startedDownloadUsingDataConnection = false;
UpdateManager.downloaded(updatableApp);
assert.isFalse(UpdateManager._startedDownloadUsingDataConnection);
});
});
suite('download prompt', function() {
var systemUpdatable = null;
var mockBuildID = '20150929135540';
var mockDetailsURL = 'https://www.mozilla.org';
var mockDisplayVersion = '2.5';
setup(function() {
systemUpdatable = new MockSystemUpdatable();
systemUpdatable.size = 5296345;
systemUpdatable.buildID = mockBuildID;
systemUpdatable.detailsURL = mockDetailsURL;
systemUpdatable.displayVersion = mockDisplayVersion;
var appUpdatable = new MockAppUpdatable(new MockApp());
appUpdatable.name = 'Angry birds';
appUpdatable.nameID = '';
appUpdatable.size = '423459';
var hostedAppUpdatable = new MockAppUpdatable(new MockApp());
hostedAppUpdatable.name = 'Twitter';
hostedAppUpdatable.nameID = '';
UpdateManager.updatesQueue = [hostedAppUpdatable, appUpdatable,
systemUpdatable];
UpdateManager.containerClicked();
UpdateManager._startedDownloadUsingDataConnection = false;
UpdateManager.downloadDialog.dataset.nowifi = false;
navigator.mozWifiManager.connection.status = 'connected';
});
teardown(function() {
MockNavigatorSettings.
mSettings[UpdateManager.WIFI_PRIORITIZED_KEY] = true;
});
suite('download prompt', function() {
test('should hide the utility tray', function() {
assert.isTrue(Service.request.calledWith('UtilityTray:hide'));
});
test('should show the download dialog', function() {
var css = UpdateManager.downloadDialog.classList;
assert.isTrue(css.contains('visible'));
});
test('should set the title', function() {
var title = fakeDialog.querySelector('h1');
var l10nAttrs = MockL10n.getAttributes(title);
assert.equal(l10nAttrs.id, 'numberOfUpdates');
assert.deepEqual(l10nAttrs.args, { n: 3 });
});
suite('update list rendering', function() {
test('should create an item for each update', function() {
assert.equal(3, UpdateManager.downloadDialogList.children.length);
});
test('should render system update item first with required',
function() {
var item = UpdateManager.downloadDialogList.children[0];
l10nAssert(item.children[0], 'required');
l10nAssert(item.children[1], 'systemUpdateWithVersion', {
version: mockDisplayVersion
});
assert.equal(item.children[2].textContent, '5.05 MB');
l10nAssert(item.children[3], 'build-id', { buildid: mockBuildID });
l10nAssert(item.children[4], 'view-release-notes');
});
test('should display the release notes when tapping on the link',
function() {
var item = UpdateManager.downloadDialogList.children[0];
var link = item.children[4];
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var canceled = !link.dispatchEvent(event);
assert.isTrue(canceled); // preventDefault() was called
assert.equal(MockMozActivity.calls.length, 1);
assert.deepEqual(MockMozActivity.calls[0], {
name: 'view',
data: {
type: 'url',
url: mockDetailsURL
}
});
});
test('should not display the release notes if the URL is not ' +
'present or blank',
function() {
var item;
systemUpdatable.detailsURL = null;
UpdateManager.containerClicked();
item = UpdateManager.downloadDialogList.children[0];
assert.equal(item.children.length, 4);
systemUpdatable.detailsURL = 'about:blank';
UpdateManager.containerClicked();
item = UpdateManager.downloadDialogList.children[0];
assert.equal(item.children.length, 4);
});
test('should render packaged app items alphabetically with checkbox',
function() {
var item = UpdateManager.downloadDialogList.children[1];
assert.include(item.textContent, '413.53 kB');
var name = item.querySelector('span.name');
assert.equal(name.textContent, 'Angry birds');
assert.isUndefined(name.dataset.l10nId);
var checkbox = item.querySelector('gaia-checkbox');
assert.isTrue(checkbox.checked);
assert.equal(checkbox.dataset.position, '1');
});
test('should render hosted app items alphabetically with checkbox',
function() {
var item = UpdateManager.downloadDialogList.children[2];
var name = item.querySelector('span.name');
assert.equal(name.textContent, 'Twitter');
assert.isUndefined(name.dataset.l10nId);
var checkbox = item.querySelector('gaia-checkbox');
assert.isTrue(checkbox.checked);
assert.equal(checkbox.dataset.position, '2');
});
});
});
test('should handle cancellation', function() {
UpdateManager.cancelPrompt();
var css = UpdateManager.downloadDialog.classList;
assert.isFalse(css.contains('visible'));
});
});
suite('cancel prompt', function() {
setup(function() {
UpdateManager._downloading = true;
UpdateManager.containerClicked();
});
test('should show the cancel', function() {
assert.isTrue(MockCustomDialog.mShown);
assert.isTrue(Service.request.calledWith('UtilityTray:hide'));
assert.equal(
'cancelAllDownloads',
MockCustomDialog.mShowedTitle
);
assert.equal('wantToCancelAll', MockCustomDialog.mShowedMsg);
assert.equal('no', MockCustomDialog.mShowedCancel.title);
assert.equal('yes', MockCustomDialog.mShowedConfirm.title);
});
test('should handle cancellation', function() {
assert.equal('um_cancelPrompt',
MockCustomDialog.mShowedCancel.callback.name);
UpdateManager.cancelPrompt();
assert.isFalse(MockCustomDialog.mShown);
});
test('should handle confirmation', function() {
assert.equal('um_cancelAllDownloads',
MockCustomDialog.mShowedConfirm.callback.name);
UpdateManager.cancelAllDownloads();
assert.isFalse(MockCustomDialog.mShown);
});
});
suite('cancel prompt continued', function() {
setup(function() {
var systemUpdatable = new MockSystemUpdatable();
UpdateManager.addToUpdatesQueue(systemUpdatable);
UpdateManager.addToDownloadsQueue(systemUpdatable);
UpdateManager.startedUncompressing();
UpdateManager.containerClicked();
});
test('should not display prompt while uncompressing', function() {
assert.isFalse(MockCustomDialog.mShown);
});
});
suite('check for updates', function() {
setup(function() {
UpdateManager.start();
});
test('should observe the setting', function() {
assert.equal('gaia.system.checkForUpdates', MockSettingsListener.mName);
assert.equal(false, MockSettingsListener.mDefaultValue);
assert.equal(UpdateManager.checkForUpdates.name,
MockSettingsListener.mCallback.name);
});
suite('when asked to check', function() {
setup(function() {
UpdateManager.checkForUpdates(true);
});
test('should dispatch force update event if asked for', function() {
assert.equal('force-update-check', lastDispatchedEvent.type);
});
test('should set the setting back to false', function() {
var setting = 'gaia.system.checkForUpdates';
assert.isFalse(MockNavigatorSettings.mSettings[setting]);
});
});
test('should not dispatch force update event if not asked', function() {
UpdateManager.checkForUpdates(false);
assert.isNull(lastDispatchedEvent);
});
});
});
suite('System updates', function() {
var showForbiddenDwnSpy;
var checkWifiPrioritizedSpy;
var realStartDownloadsFunc;
var startDownloadsSpy;
var showPromptWifiPrioritizedSpy;
var showAdditionalCostIfNeededSpy;
var getDataRoamingSettingSpy;
var checkUpdate2gEnabled;
var showPromptNoConnectionSpy;
var mockMozWifiManager;
var mockMozMobileConnections;
var realOnLine;
var isOnLine = true;
function navigatorOnLine() {
return isOnLine;
}
function setNavigatorOnLine(value) {
isOnLine = value;
}
setup(function() {
this.sinon.useFakeTimers();
realStartDownloadsFunc = UpdateManager.startDownloads;
UpdateManager.startDownloads = function() {
UpdateManager.downloadDialog.classList.remove('visible');
return true;
};
mockMozWifiManager = navigator.mozWifiManager;
mockMozMobileConnections = navigator.mozMobileConnections;
realOnLine = Object.getOwnPropertyDescriptor(navigator, 'onLine');
Object.defineProperty(navigator, 'onLine', {
configurable: true,
get: navigatorOnLine,
set: setNavigatorOnLine
});
showForbiddenDwnSpy =
this.sinon.spy(UpdateManager, 'showForbiddenDownload');
checkWifiPrioritizedSpy =
this.sinon.spy(UpdateManager, 'getWifiPrioritized');
showPromptWifiPrioritizedSpy =
this.sinon.spy(UpdateManager, 'showPromptWifiPrioritized');
startDownloadsSpy =
this.sinon.spy(UpdateManager, 'startDownloads');
showAdditionalCostIfNeededSpy =
this.sinon.spy(UpdateManager, 'showPrompt3GAdditionalCostIfNeeded');
getDataRoamingSettingSpy =
this.sinon.spy(UpdateManager, '_getDataRoamingSetting');
checkUpdate2gEnabled =
this.sinon.spy(UpdateManager, 'getUpdate2GEnabled');
showPromptNoConnectionSpy =
this.sinon.spy(UpdateManager, 'showPromptNoConnection');
UpdateManager.start();
});
teardown(function() {
this.sinon.clock.restore();
UpdateManager.startDownloads = realStartDownloadsFunc;
UpdateManager.downloadDialog.dataset.online = true;
if (realOnLine) {
Object.defineProperty(navigator, 'onLine', realOnLine);
}
navigator.mozWifiManager = mockMozWifiManager;
navigator.mozMobileConnections = mockMozMobileConnections;
navigator.mozWifiManager.connection.status = 'connected';
});
// 3G -> conn: 'evdo0',
// 2G -> conn: 'gprs',
var testCases = [
{
title: 'WIFI, 2G, no Setting update2G, wifi prioritized' +
'-> download available',
wifi: true,
conns: [
{
type: 'gprs',
connected: true
},
{
connected: false
}
],
wifiPrioritized: true,
testResult: 'startDownloads'
},
{
title: 'WIFI, 2G, Setting update2G is true, wifi prioritized' +
'-> download available',
wifi: true,
conns: [
{
connected: false
},
{
type: 'gprs',
connected: true
}
],
update2g: true,
wifiPrioritized: true,
testResult: 'startDownloads'
},
{
title: 'WIFI, 2G, no Setting update2G, wifi not prioritized' +
'-> download available',
wifi: true,
conns: [
{
type: 'gprs',
connected: true
},
{
connected: false
}
],
update2g: false,
wifiPrioritized: false,
testResult: 'startDownloads'
},
{
title: 'WIFI, 2G, Setting update2G is true, wifi not prioritized' +
'-> download available',
wifi: true,
conns: [
{
type: 'gprs',
connected: true
},
{
connected: false
}
],
update2g: false,
wifiPrioritized: false,
testResult: 'startDownloads'
},
{
title: 'WIFI, 3G, Setting update2G is true, wifi not prioritized' +
'-> download available',
wifi: true,
conns: [
{
type: 'gprs',
connected: true
},
{
connected: false
}
],
update2g: false,
wifiPrioritized: false,
testResult: 'startDownloads'
},
{
title: 'Not WIFI, 3G, no Setting update2G, wifi not prioritized' +
'-> download available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'evdo0',
connected: true
}
],
update2g: false,
wifiPrioritized: false,
testResult: 'additionalCostIfNeeded'
},
{
title: 'Not WIFI, 3G, Setting update2G is true, wifi not prioritized' +
'-> download available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'evdo0',
connected: true
}
],
update2g: true,
wifiPrioritized: false,
testResult: 'additionalCostIfNeeded'
},
{
title: 'Not WIFI, 3G, no Setting update2G, wifi prioritized' +
'-> download available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'evdo0',
connected: true
}
],
update2g: false,
wifiPrioritized: true,
testResult: 'wifiPrioritized'
},
{
title: 'Not WIFI, 3G, Setting update2G is true, wifi prioritized' +
'-> download available',
wifi: false,
conns: [
{
type: 'evdo0',
connected: false
},
{
connected: true
}
],
update2g: true,
wifiPrioritized: true,
testResult: 'wifiPrioritized'
},
{
title: 'Not WIFI, 2G, Setting update2G is true, wifi prioritized' +
'-> download available',
wifi: false,
conns: [
{
type: 'gprs',
connected: false
},
{
connected: true
}
],
update2g: true,
wifiPrioritized: true,
testResult: 'wifiPrioritized'
},
{
title: 'Not WIFI, 2G, Setting update2G is true, wifi not prioritized' +
'-> download available',
wifi: false,
conns: [
{
type: 'gprs',
connected: false
},
{
connected: true
}
],
update2g: true,
wifiPrioritized: false,
testResult: 'additionalCostIfNeeded'
},
{
title: 'Not WIFI, 2G, Setting update2G is true, wifi not prioritized,' +
'roaming -> download available',
wifi: false,
conns: [
{
type: 'gprs',
connected: false
},
{
connected: true
}
],
update2g: true,
wifiPrioritized: false,
testResult: 'roamingDialog',
roaming: true
},
{
title: 'Not WIFI, 2G, no Setting update2G, wifi prioritized' +
'System update available -> download not available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'gprs',
connected: true
}
],
update2g: false,
wifiPrioritized: true,
systemUpdate: true,
testResult: 'forbidden'
},
{
title: 'Not WIFI, 2G, no Setting update2G, wifi prioritized' +
'System update unavailable -> download available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'gprs',
connected: true
}
],
update2g: false,
wifiPrioritized: true,
systemUpdate: false,
testResult: 'wifiPrioritized'
},
{
title: 'Not WIFI, 2G, no Setting update2G, wifi not prioritized' +
'System update available -> download not available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'gprs',
connected: true
}
],
update2g: false,
wifiPrioritized: false,
systemUpdate: true,
testResult: 'forbidden'
},
{
title: 'Not WIFI, 2G, no Setting update2G, wifi not prioritized' +
'System update unavailable -> download available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'gprs',
connected: true
}
],
update2g: false,
wifiPrioritized: false,
systemUpdate: false,
testResult: 'additionalCostIfNeeded'
},
{
title: 'Not WIFI, No Data connection -> download not available',
wifi: false,
conns: [
{
connected: false
},
{
type: 'gprs',
connected: false
}
],
update2g: false,
wifiPrioritized: false,
noConnection: true,
testResult: 'noConnection'
},
{
title: 'B2G/Mulet download, navigator online -> download available',
onLine: true,
testResult: 'startDownloads'
},
{
title: 'B2G/Mulet download, navigator offline' +
'-> download not available',
onLine: false,
testResult: 'noConnection'
},
{
title: 'Connections undefined -> download not available',
testResult: 'noConnection'
}
];
testCases.forEach(function(testCase) {
test(testCase.title, function(done) {
if (testCase.update2g === undefined) {
delete MockNavigatorSettings.mSettings[UpdateManager.UPDATE_2G_SETT];
} else {
MockNavigatorSettings.mSettings[UpdateManager.UPDATE_2G_SETT] =
testCase.update2g;
}
if (testCase.wifiPrioritized === undefined) {
delete MockNavigatorSettings.
mSettings[UpdateManager.WIFI_PRIORITIZED_KEY];
} else {
MockNavigatorSettings.mSettings[UpdateManager.WIFI_PRIORITIZED_KEY] =
testCase.wifiPrioritized;
}
if (testCase.onLine === undefined) {
navigator.mozWifiManager.connection.status =
testCase.wifi ? 'connected' : 'disconnected';
} else {
navigator.mozWifiManager = null;
navigator.onLine = testCase.onLine ? true : false;
}
MockNavigatorSettings.mSettings['ril.data.roaming_enabled'] =
testCase.roaming ? true : false;
if (testCase.conns === undefined) {
navigator.mozMobileConnections = null;
} else {
for (var i = 0, iLen = testCase.conns.length;
i < iLen && i < MOBILE_CONNECTION_COUNT;
i++) {
MockNavigatorMozMobileConnections[i].data = {
connected: testCase.conns[i].connected,
type: testCase.conns[i].type,
roaming: (testCase.roaming ? true : false)
};
}
}
UpdateManager._systemUpdateDisplayed =
testCase.systemUpdate ? true : false;
if (testCase.noConnection) {
UpdateManager.downloadDialog.dataset.online = false;
}
UpdateManager.promptOrDownload();
this.sinon.clock.tick(TINY_TIMEOUT);
switch (testCase.testResult) {
case 'startDownloads':
assert.isTrue(startDownloadsSpy.lastCall.returnValue);
assert.ok(startDownloadsSpy.calledOnce,
'wifi is connected so the download is available');
done();
break;
case 'additionalCostIfNeeded':
Promise.all([checkWifiPrioritizedSpy.lastCall.returnValue,
checkUpdate2gEnabled.lastCall.returnValue]).then(function() {
getDataRoamingSettingSpy.lastCall.returnValue.then(function() {
assert.ok(showAdditionalCostIfNeededSpy.calledOnce,
'check if the user is currently roaming');
assert.ok(startDownloadsSpy.calledOnce,
'roaming is not enabled, so the download can start');
}).then(done, done);
}).then(done, done);
break;
case 'wifiPrioritized':
Promise.all([checkWifiPrioritizedSpy.lastCall.returnValue,
checkUpdate2gEnabled.lastCall.returnValue]).then(function() {
assert.ok(showPromptWifiPrioritizedSpy.calledWith(),
'wifi prioritized dialog is shown to the user');
}).then(done, done);
break;
case 'forbidden':
Promise.all([checkWifiPrioritizedSpy.lastCall.returnValue,
checkUpdate2gEnabled.lastCall.returnValue]).then(function() {
assert.ok(showForbiddenDwnSpy.calledOnce,
'forbidden download');
}).then(done, done);
break;
case 'roamingDialog':
Promise.all([checkWifiPrioritizedSpy.lastCall.returnValue,
checkUpdate2gEnabled.lastCall.returnValue]).then(function() {
getDataRoamingSettingSpy.lastCall.returnValue.then(function() {
var css = UpdateManager.downloadViaDataConnectionDialog.
classList;
var titleL10nId =
UpdateManager.downloadViaDataConnectionTitle
.getAttribute('data-l10n-id');
var messageL10nId =
UpdateManager.downloadViaDataConnectionMessage
.getAttribute('data-l10n-id');
assert.isTrue(css.contains('visible'));
assert.equal(titleL10nId,
'downloadUpdatesViaDataRoamingConnection');
assert.equal(messageL10nId,
'downloadUpdatesViaDataRoamingConnectionMessage');
}).then(done, done);
}).then(done, done);
break;
case 'noConnection':
assert.isTrue(showPromptNoConnectionSpy.calledOnce);
done();
break;
}
});
});
});
suite('queues support', function() {
suite('updates queue', function() {
suite('addToUpdatesQueue', function() {
setup(function() {
UpdateManager.start();
var installedApp = new MockApp();
var updatableApp = new MockAppUpdatable(installedApp);
var pendingApp = new MockApp({ installState: 'pending' }),
uPendingApp = new MockAppUpdatable(pendingApp);
UpdateManager.updatableApps = [updatableApp, uPendingApp];
});
test('should add the updatable app to the array', function() {
var updatableApp = UpdateManager.updatableApps[0];
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.addToUpdatesQueue(updatableApp);
assert.equal(initialLength + 1, UpdateManager.updatesQueue.length);
});
test('should render', function() {
var updatableApp = UpdateManager.updatableApps[0];
UpdateManager.addToUpdatesQueue(updatableApp);
var l10nAttrs = MockL10n.getAttributes(
UpdateManager.message);
assert.equal(l10nAttrs.id, 'updateAvailableInfo');
assert.deepEqual(l10nAttrs.args, { n: 1 });
});
test('should not add app if not in updatableApps array', function() {
var updatableApp = new MockAppUpdatable(new MockApp());
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.addToUpdatesQueue(updatableApp);
assert.equal(initialLength, UpdateManager.updatesQueue.length);
});
test('should add a system update to the array', function() {
var systemUpdate = new MockSystemUpdatable();
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.addToUpdatesQueue(systemUpdate);
assert.equal(initialLength + 1, UpdateManager.updatesQueue.length);
});
test('should not add more than one system update', function() {
var systemUpdate = new MockSystemUpdatable();
UpdateManager.updatesQueue.push(new MockSystemUpdatable());
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.addToUpdatesQueue(systemUpdate);
assert.equal(initialLength, UpdateManager.updatesQueue.length);
});
test('should not add if app already in the array', function() {
var updatableApp = UpdateManager.updatableApps[0];
UpdateManager.addToUpdatesQueue(updatableApp);
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.addToUpdatesQueue(updatableApp);
assert.equal(initialLength, UpdateManager.updatesQueue.length);
});
test('should not add if downloading', function() {
UpdateManager._downloading = true;
var updatableApp = UpdateManager.updatableApps[0];
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.addToUpdatesQueue(updatableApp);
assert.equal(initialLength, UpdateManager.updatesQueue.length);
});
test('should not add a pending app to the array', function() {
var updatableApp = UpdateManager.updatableApps[1];
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.addToUpdatesQueue(updatableApp);
assert.equal(UpdateManager.updatesQueue.length, initialLength);
});
});
suite('removeFromUpdatesQueue', function() {
var updatableApp;
setup(function() {
UpdateManager.start();
var installedApp = new MockApp();
updatableApp = new MockAppUpdatable(installedApp);
UpdateManager.updatableApps = [updatableApp];
UpdateManager.updatesQueue = [updatableApp];
});
test('should remove if in updatesQueue array', function() {
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.removeFromUpdatesQueue(updatableApp);
assert.equal(initialLength - 1, UpdateManager.updatesQueue.length);
});
test('should render', function() {
UpdateManager.removeFromUpdatesQueue(updatableApp);
var l10nAttrs = MockL10n.getAttributes(
UpdateManager.message);
assert.equal(l10nAttrs.id, 'updateAvailableInfo');
assert.deepEqual(l10nAttrs.args, { n: 0 });
});
test('should remove system updates too', function() {
var systemUpdate = new MockSystemUpdatable();
UpdateManager.updatesQueue.push(systemUpdate);
var initialLength = UpdateManager.updatesQueue.length;
UpdateManager.removeFromUpdatesQueue(systemUpdate);
assert.equal(initialLength - 1, UpdateManager.updatesQueue.length);
});
});
});
suite('downloads queue', function() {
suite('addToDownloadsQueue', function() {
var updatableApp;
setup(function() {
UpdateManager.start();
var installedApp = new MockApp();
updatableApp = new MockAppUpdatable(installedApp);
UpdateManager.updatableApps = [updatableApp];
});
test('should add the updatable to the array', function() {
var initialLength = UpdateManager.downloadsQueue.length;
UpdateManager.addToDownloadsQueue(updatableApp);
assert.equal(initialLength + 1, UpdateManager.downloadsQueue.length);
});
test('should add system updates too', function() {
var initialLength = UpdateManager.downloadsQueue.length;
UpdateManager.addToDownloadsQueue(new MockSystemUpdatable());
assert.equal(initialLength + 1, UpdateManager.downloadsQueue.length);
});
test('should not add more than one system updates', function() {
var initialLength = UpdateManager.downloadsQueue.length;
UpdateManager.addToDownloadsQueue(new MockSystemUpdatable());
UpdateManager.addToDownloadsQueue(new MockSystemUpdatable());
assert.equal(initialLength + 1, UpdateManager.downloadsQueue.length);
});
suite('switching to downloading mode on first add', function() {
setup(function() {
UpdateManager.addToDownloadsQueue(updatableApp);
});
test('should add css class', function() {
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('downloading'));
});
test('should ask for statusbar indicator', function() {
var incMethod = 'incDownloads';
assert.isTrue(Service.request.calledWith(incMethod));
});
test('should request wifi wake lock', function() {
assert.equal('wifi', MockNavigatorWakeLock.mLastWakeLock.topic);
assert.isFalse(MockNavigatorWakeLock.mLastWakeLock.released);
});
});
test('should not add app if not in updatableApps array', function() {
var updatableApp = new MockAppUpdatable(new MockApp());
var initialLength = UpdateManager.downloadsQueue.length;
UpdateManager.addToDownloadsQueue(updatableApp);
assert.equal(initialLength, UpdateManager.downloadsQueue.length);
});
test('should not add if already in the array', function() {
UpdateManager.addToDownloadsQueue(updatableApp);
var initialLength = UpdateManager.downloadsQueue.length;
UpdateManager.addToDownloadsQueue(updatableApp);
assert.equal(initialLength, UpdateManager.downloadsQueue.length);
});
});
suite('removeFromDownloadsQueue', function() {
var updatableApp;
setup(function() {
UpdateManager.start();
var installedApp = new MockApp();
updatableApp = new MockAppUpdatable(installedApp);
UpdateManager.addToUpdatableApps(updatableApp);
UpdateManager.addToDownloadsQueue(updatableApp);
});
test('should remove if in downloadsQueue array', function() {
var initialLength = UpdateManager.downloadsQueue.length;
UpdateManager.removeFromDownloadsQueue(updatableApp);
assert.equal(initialLength - 1, UpdateManager.downloadsQueue.length);
});
suite('should switch off downloading mode on last remove', function() {
setup(function() {
UpdateManager.removeFromDownloadsQueue(updatableApp);
});
test('should remove css class', function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('downloading'));
});
test('should remove statusbar indicator', function() {
var decMethod = 'decDownloads';
assert.isTrue(Service.request.calledWith(decMethod));
});
test('should release the wifi wake lock', function() {
assert.equal('wifi', MockNavigatorWakeLock.mLastWakeLock.topic);
assert.isTrue(MockNavigatorWakeLock.mLastWakeLock.released);
});
});
test('should not break if wifi unlock throws an exception',
function() {
MockNavigatorWakeLock.mThrowAtNextUnlock();
UpdateManager.removeFromDownloadsQueue(updatableApp);
assert.ok(true);
});
test('should remove system updates too', function() {
var systemUpdate = new MockSystemUpdatable();
UpdateManager.downloadsQueue.push(systemUpdate);
var initialLength = UpdateManager.downloadsQueue.length;
UpdateManager.removeFromDownloadsQueue(systemUpdate);
assert.equal(initialLength - 1, UpdateManager.downloadsQueue.length);
});
});
});
});
});