'use strict';
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/test/unit/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_settings_listener.js');
requireApp('system/test/unit/mock_statusbar.js');
requireApp('system/test/unit/mock_notification_screen.js');
requireApp('system/test/unit/mock_navigator_settings.js');
requireApp('system/test/unit/mock_navigator_wake_lock.js');
requireApp('system/test/unit/mock_navigator_moz_mobile_connection.js');
requireApp('system/test/unit/mock_l10n.js');
requireApp('system/test/unit/mock_asyncStorage.js');
requireApp('system/test/unit/mocks_helper.js');
var mocksForUpdateManager = [
'StatusBar',
'SystemBanner',
'NotificationScreen',
'UtilityTray',
'CustomDialog',
'SystemUpdatable',
'AppUpdatable',
'SettingsListener',
'asyncStorage'
];
mocksForUpdateManager.forEach(function(mockName) {
if (! window[mockName]) {
window[mockName] = null;
}
});
suite('system/UpdateManager', function() {
var realL10n;
var realWifiManager;
var realRequestWakeLock;
var realNavigatorSettings;
var realDispatchEvent;
var apps;
var updatableApps;
var uAppWithDownloadAvailable;
var appWithDownloadAvailable;
var fakeNode;
var fakeToaster;
var fakeDialog;
var fakeWarning;
var tinyTimeout = 10;
var lastDispatchedEvent = null;
var mocksHelper;
suiteSetup(function() {
realNavigatorSettings = navigator.mozSettings;
navigator.mozSettings = MockNavigatorSettings;
realL10n = navigator.mozL10n;
navigator.mozL10n = MockL10n;
realWifiManager = navigator.mozWifiManager;
navigator.mozWifiManager = {
connection: {
status: 'connected'
}
};
realRequestWakeLock = navigator.requestWakeLock;
navigator.requestWakeLock = MockNavigatorWakeLock.requestWakeLock;
realDispatchEvent = UpdateManager._dispatchEvent;
UpdateManager._dispatchEvent = function fakeDispatch(type, value) {
lastDispatchedEvent = {
type: type,
value: value
};
};
mocksHelper = new MocksHelper(mocksForUpdateManager);
mocksHelper.suiteSetup();
UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT = 0;
UpdateManager.TOASTER_TIMEOUT = 0;
});
suiteTeardown(function() {
navigator.mozSettings = realNavigatorSettings;
realNavigatorSettings = null;
navigator.mozL10n = realL10n;
navigator.mozWifiManager = realWifiManager;
navigator.requestWakeLock = realRequestWakeLock;
realRequestWakeLock = null;
UpdateManager._dispatchEvent = realDispatchEvent;
mocksHelper.suiteTeardown();
});
setup(function() {
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);
mocksHelper.setup();
});
teardown(function(done) {
// We wait for the nextTick in order to let the UpdateManger's
// timeouts finish (they are all set to 0)
setTimeout(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;
MockAppsMgmt.mTeardown();
mocksHelper.teardown();
fakeNode.parentNode.removeChild(fakeNode);
fakeToaster.parentNode.removeChild(fakeToaster);
fakeDialog.parentNode.removeChild(fakeDialog);
lastDispatchedEvent = null;
MockNavigatorWakeLock.mTeardown();
MockNavigatorSettings.mTeardown();
done();
});
});
suite('init', function() {
test('should get all applications', function(done) {
MockAppsMgmt.mNext = function() {
done();
};
UpdateManager.init();
});
test('should create AppUpdatable on init', function(done) {
MockAppUpdatable.mTeardown();
MockAppsMgmt.mNext = function() {
assert.equal(MockAppUpdatable.mCount, apps.length);
done();
};
UpdateManager.init();
});
test('should bind dom elements', function() {
UpdateManager.init();
assert.equal('update-manager-container', UpdateManager.container.id);
assert.equal('message', 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.init();
assert.equal(UpdateManager.containerClicked.name,
UpdateManager.container.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();
UpdateManager.init();
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.init();
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.init();
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.init();
});
test('should not remember about the update', function() {
assert.isUndefined(UpdateManager.systemUpdatable.mKnownUpdate);
});
});
});
suite('UI', function() {
setup(function() {
MockAppsMgmt.mApps = [];
UpdateManager.init();
UpdateManager.updatableApps = updatableApps;
});
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();
assert.equal('downloadingUpdateMessage{"progress":"0.00 bytes"}',
UpdateManager.message.textContent);
});
test('should not show the toaster if downloading', function(done) {
UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT = tinyTimeout;
UpdateManager.TOASTER_TIMEOUT = tinyTimeout;
UpdateManager._downloading = true;
UpdateManager.addToUpdatesQueue(uAppWithDownloadAvailable);
setTimeout(function() {
var css = UpdateManager.toaster.classList;
assert.isFalse(css.contains('displayed'));
UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT = 0;
UpdateManager.TOASTER_TIMEOUT = 0;
done();
}, tinyTimeout * 1.5);
});
test('should show the available message if not downloading', function() {
UpdateManager.updatesQueue = updatableApps;
UpdateManager.render();
assert.equal('updateAvailableInfo{"n":3}',
UpdateManager.message.textContent);
});
});
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);
assert.equal('downloadingUpdateMessage{"progress":"0.00 bytes"}',
UpdateManager.message.textContent);
});
test('downloadedBytes should be reset when stopping the download',
function() {
UpdateManager.removeFromDownloadsQueue(uAppWithDownloadAvailable);
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
assert.equal('downloadingUpdateMessage{"progress":"0.00 bytes"}',
UpdateManager.message.textContent);
});
test('should increment the downloadedBytes', function() {
UpdateManager.downloadProgressed(100);
assert.equal('downloadingUpdateMessage{"progress":"1.30 kB"}',
UpdateManager.message.textContent);
});
test('should not update if bytes <= 0', function() {
UpdateManager.downloadProgressed(-100);
assert.equal('downloadingUpdateMessage{"progress":"1.21 kB"}',
UpdateManager.message.textContent);
});
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.textContent,
'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.textContent,
'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.textContent,
'uncompressingMessage');
});
});
});
});
suite('container visibility', function() {
suiteSetup(function() {
UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT = tinyTimeout;
UpdateManager.TOASTER_TIMEOUT = tinyTimeout;
});
suiteTeardown(function() {
UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT = 0;
UpdateManager.TOASTER_TIMEOUT = 0;
});
setup(function() {
UpdateManager.addToUpdatesQueue(uAppWithDownloadAvailable);
});
teardown(function(done) {
// wait for all actions to happen in UpdateManager before reseting
setTimeout(function() {
done();
}, tinyTimeout * 2);
});
suite('notification behavior after addToDownloadsQueue', function() {
setup(function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
});
test('should be displayed only once', function() {
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(MockNotificationScreen.wasMethodCalled['incExternalNotifications'], 1);
});
test('should not be displayed after timeout', function(done) {
setTimeout(function() {
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(MockNotificationScreen.wasMethodCalled['incExternalNotifications'], 1);
done();
}, tinyTimeout * 2);
});
});
suite('notification behavior after addToDownloadsQueue after timeout', function() {
setup(function(done) {
setTimeout(function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
UpdateManager.addToDownloadsQueue(uAppWithDownloadAvailable);
done();
});
});
test('should not increment the counter if already displayed', function() {
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(MockNotificationScreen.wasMethodCalled['incExternalNotifications'], 1);
});
});
suite('displaying the container after a timeout', function() {
setup(function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
});
test('should display after a timeout', function(done) {
setTimeout(function() {
var css = UpdateManager.container.classList;
assert.isTrue(css.contains('displayed'));
assert.equal(MockNotificationScreen.wasMethodCalled['incExternalNotifications'], 1);
done();
}, tinyTimeout * 2);
});
test('should not display if there are no more updates', function(done) {
UpdateManager.updatesQueue.forEach(function(uApp) {
UpdateManager.removeFromUpdatesQueue(uApp);
});
setTimeout(function() {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
done();
}, tinyTimeout * 2);
});
test('should display an updated count', function(done) {
UpdateManager.addToUpdatesQueue(updatableApps[1]);
setTimeout(function() {
assert.equal('updateAvailableInfo{"n":2}',
UpdateManager.message.textContent);
done();
}, tinyTimeout * 2);
});
suite('update toaster', function() {
test('should display after a timeout', function(done) {
var css = UpdateManager.container.classList;
assert.isFalse(css.contains('displayed'));
setTimeout(function() {
var css = UpdateManager.toaster.classList;
assert.isTrue(css.contains('displayed'));
assert.equal('updateAvailableInfo{"n":1}',
UpdateManager.toasterMessage.textContent);
done();
}, tinyTimeout * 1.5);
});
test('should reset toaster value when notification was activated', function(done) {
setTimeout(function() {
UpdateManager.addToUpdatesQueue(updatableApps[1]);
assert.equal('updateAvailableInfo{"n":1}',
UpdateManager.toasterMessage.textContent);
done();
}, tinyTimeout * 2);
});
test('should show the right message', function(done) {
setTimeout(function() {
assert.equal('updateAvailableInfo{"n":1}',
UpdateManager.toasterMessage.textContent);
done();
}, tinyTimeout * 2);
});
test('should hide after TOASTER_TIMEOUT', function(done) {
UpdateManager.addToUpdatesQueue(updatableApps[1]);
setTimeout(function() {
setTimeout(function() {
var css = UpdateManager.toaster.classList;
assert.isFalse(css.contains('displayed'));
done();
}, tinyTimeout * 2);
}, tinyTimeout * 2);
});
});
test('should add a new statusbar notification', function(done) {
var method1 = 'incExternalNotifications';
setTimeout(function() {
assert.ok(MockNotificationScreen.wasMethodCalled[method1]);
done();
}, tinyTimeout * 2);
});
});
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 = 'decExternalNotifications';
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() {
suiteSetup(function() {
UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT = tinyTimeout;
UpdateManager.TOASTER_TIMEOUT = tinyTimeout;
});
suiteTeardown(function() {
UpdateManager.NOTIFICATION_BUFFERING_TIMEOUT = 0;
UpdateManager.TOASTER_TIMEOUT = 0;
});
setup(function() {
UpdateManager.init();
UpdateManager.requestErrorBanner();
});
teardown(function(done) {
// wait for all actions to happen in UpdateManager before reseting
setTimeout(function() {
done();
}, tinyTimeout * 2);
});
test('should wait before showing the system banner', function(done) {
assert.equal(0, MockSystemBanner.mShowCount);
setTimeout(function() {
done();
}, tinyTimeout * 2);
});
test('should show after NOTIFICATION_BUFFERING_TIMEOUT', function(done) {
setTimeout(function() {
assert.equal(1, MockSystemBanner.mShowCount);
assert.equal('downloadError', MockSystemBanner.mMessage);
done();
}, tinyTimeout * 2);
});
test('should show only once if called multiple time', function(done) {
UpdateManager.requestErrorBanner();
setTimeout(function() {
assert.equal(1, MockSystemBanner.mShowCount);
done();
}, tinyTimeout * 2);
});
});
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.init();
});
suite('start downloads', function() {
var systemUpdatable, appUpdatable, evt;
setup(function() {
UpdateManager.init();
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;
});
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('input[type="checkbox"]');
for (var i = 0; i < checkboxes.length; i++) {
var checkbox = checkboxes[i];
if (checkbox.checked) {
checkbox.click();
}
}
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('input[type="checkbox"]');
for (var i = 0; i < checkboxes.length; i++) {
var checkbox = checkboxes[i];
if (checkbox.checked) {
checkboxes[i].click();
}
}
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('input[type="checkbox"]');
checkbox.click();
});
test('should enable the download button back', 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('download prompt', function() {
setup(function() {
MockUtilityTray.show();
var systemUpdatable = new MockSystemUpdatable();
systemUpdatable.size = 5296345;
var appUpdatable = new MockAppUpdatable(new MockApp());
appUpdatable.name = 'Angry birds';
appUpdatable.size = '423459';
var hostedAppUpdatable = new MockAppUpdatable(new MockApp());
hostedAppUpdatable.name = 'Twitter';
UpdateManager.updatesQueue = [hostedAppUpdatable, appUpdatable,
systemUpdatable];
UpdateManager.containerClicked();
UpdateManager._isDataConnectionWarningDialogEnabled = true;
UpdateManager.downloadDialog.dataset.nowifi = false;
});
suite('download prompt', function() {
test('should hide the utility tray', function() {
assert.isFalse(MockUtilityTray.mShown);
});
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');
assert.equal('numberOfUpdates{"n":3}', title.textContent);
});
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];
assert.include(item.textContent, 'systemUpdate');
assert.include(item.textContent, '5.05 MB');
assert.include(item.textContent, 'required');
});
test('should render packaged app items alphabetically with checkbox',
function() {
var item = UpdateManager.downloadDialogList.children[1];
assert.include(item.textContent, 'Angry birds');
assert.include(item.textContent, '413.53 kB');
var checkbox = item.querySelector('input');
assert.equal(checkbox.type, '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];
assert.include(item.textContent, 'Twitter');
var checkbox = item.querySelector('input');
assert.equal(checkbox.type, 'checkbox');
assert.isTrue(checkbox.checked);
assert.equal(checkbox.dataset.position, '2');
});
});
});
test('should handle clicking download in the data connection warning dialog', function() {
UpdateManager.downloadDialog.dataset.nowifi = true;
var evt = {
preventDefault: function() {},
type: 'click',
target: UpdateManager.downloadViaDataConnectionButton
};
UpdateManager.requestDownloads(evt);
MockasyncStorage.getItem('gaia.system.isDataConnectionWarningDialogEnabled', function(value) {
assert.isFalse(value);
});
assert.isFalse(UpdateManager._isDataConnectionWarningDialogEnabled);
assert.equal(UpdateManager.downloadDialog.dataset.dataConnectionInlineWarning, 'true');
MockasyncStorage.mTeardown();
});
test('should handle clicking download when using data connection in the first time', function() {
UpdateManager.downloadDialog.dataset.nowifi = true;
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, true);
UpdateManager.requestDownloads(evt);
var css = UpdateManager.downloadViaDataConnectionDialog.classList;
assert.isTrue(css.contains('visible'));
});
test('should handle clicking download when using wifi', function() {
UpdateManager._isDataConnectionWarningDialogEnabled = false;
var calledToMockStartDownloads = false;
var realStartDownloadsFunc = UpdateManager.startDownloads;
UpdateManager.startDownloads = function() {
calledToMockStartDownloads = true;
};
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, true);
UpdateManager.requestDownloads(evt);
assert.isTrue(calledToMockStartDownloads);
UpdateManager.startDownloads = realStartDownloadsFunc;
});
test('should handle cancellation on the data connection warning dialog', function() {
UpdateManager.cancelDataConnectionUpdatesPrompt();
var css = UpdateManager.downloadViaDataConnectionDialog.classList;
assert.isFalse(css.contains('visible'));
css = UpdateManager.downloadDialog.classList;
assert.isFalse(css.contains('visible'));
});
test('should handle cancellation', function() {
UpdateManager.cancelPrompt();
var css = UpdateManager.downloadDialog.classList;
assert.isFalse(css.contains('visible'));
});
test('should handle confirmation', function() {
UpdateManager._isDataConnectionWarningDialogEnabled = false;
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, true);
UpdateManager.requestDownloads(evt);
var css = UpdateManager.downloadDialog.classList;
assert.isFalse(css.contains('visible'));
css = UpdateManager.downloadViaDataConnectionDialog.classList;
assert.isFalse(css.contains('visible'));
assert.isTrue(MockUtilityTray.mShown);
assert.isTrue(evt.defaultPrevented);
});
});
suite('cancel prompt', function() {
setup(function() {
UpdateManager._downloading = true;
MockUtilityTray.show();
UpdateManager.containerClicked();
});
test('should show the cancel', function() {
assert.isTrue(MockCustomDialog.mShown);
assert.isFalse(MockUtilityTray.mShown);
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('check for updates', function() {
setup(function() {
UpdateManager.init();
});
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('queues support', function() {
suite('updates queue', function() {
suite('addToUpdatesQueue', function() {
setup(function() {
var installedApp = new MockApp();
var updatableApp = new MockAppUpdatable(installedApp);
var pendingApp = new MockApp({ installState: 'pending' }),
uPendingApp = new MockAppUpdatable(pendingApp);
UpdateManager.updatableApps = [updatableApp, uPendingApp];
UpdateManager.init();
});
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);
assert.equal('updateAvailableInfo{"n":1}',
UpdateManager.message.textContent);
});
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() {
var installedApp = new MockApp();
updatableApp = new MockAppUpdatable(installedApp);
UpdateManager.updatableApps = [updatableApp];
UpdateManager.updatesQueue = [updatableApp];
UpdateManager.init();
});
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);
assert.equal('updateAvailableInfo{"n":0}',
UpdateManager.message.textContent);
});
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() {
var installedApp = new MockApp();
updatableApp = new MockAppUpdatable(installedApp);
UpdateManager.updatableApps = [updatableApp];
UpdateManager.init();
});
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 = 'incSystemDownloads';
assert.ok(MockStatusBar.wasMethodCalled[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() {
var installedApp = new MockApp();
updatableApp = new MockAppUpdatable(installedApp);
UpdateManager.init();
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 = 'decSystemDownloads';
assert.ok(MockStatusBar.wasMethodCalled[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);
});
});
});
});
});