VulpesOS/gaia/apps/system/test/unit/updatable_test.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

1091 lines
35 KiB
JavaScript
Executable file

'use strict';
/* global
AppUpdatable,
asyncStorage,
MocksHelper,
MockApp,
MockAppsMgmt,
MockChromeEvent,
MockCustomDialog,
MockNavigatorBattery,
MockNavigatorSettings,
MockNotificationHelper,
MockService,
MockUpdateManager,
MockUtilityTray,
SystemUpdatable
*/
requireApp('system/js/updatable.js');
requireApp('system/test/unit/mock_app.js');
requireApp('system/test/unit/mock_asyncStorage.js');
requireApp('system/test/unit/mock_update_manager.js');
requireApp('system/test/unit/mock_app_window_manager.js');
requireApp('system/test/unit/mock_apps_mgmt.js');
requireApp('system/test/unit/mock_chrome_event.js');
requireApp('system/test/unit/mock_utility_tray.js');
requireApp('system/test/unit/mock_navigator_battery.js');
requireApp('system/shared/test/unit/mocks/mock_service.js');
requireApp('system/shared/test/unit/mocks/mock_custom_dialog.js');
requireApp('system/shared/test/unit/mocks/mock_manifest_helper.js');
requireApp('system/shared/test/unit/mocks/mock_navigator_moz_settings.js');
require('/shared/test/unit/mocks/mock_notification_helper.js');
require('/shared/test/unit/mocks/mock_notification.js');
var mocksHelperForUpdatable = new MocksHelper([
'CustomDialog',
'UpdateManager',
'AppWindowManager',
'UtilityTray',
'ManifestHelper',
'Notification',
'NotificationHelper',
'asyncStorage',
'Service'
]).init();
suite('system/Updatable', function() {
var subject;
var mockApp;
var realDispatchEvent;
var realL10n;
var realMozApps;
var realMozSettings;
var lastDispatchedEvent = null;
var fakeDispatchEvent;
var MID_CHARGE = 50;
var BATTERY_THRESHOLD_PLUGGED = 'app.update.battery-threshold.plugged';
var BATTERY_THRESHOLD_UNPLUGGED = 'app.update.battery-threshold.unplugged';
var SYSTEM_LOW_BATTERY_L10N_KEY = 'systemUpdateLowBatteryThreshold';
mocksHelperForUpdatable.attachTestHelpers();
suiteSetup(function() {
realMozSettings = window.navigator.mozSettings;
navigator.mozSettings = MockNavigatorSettings;
realL10n = navigator.mozL10n;
navigator.mozL10n = {
get: function get(key) {
return key;
}
};
var getSpy = sinon.spy(navigator.mozL10n, 'get');
getSpy.withArgs(SYSTEM_LOW_BATTERY_L10N_KEY);
// we used to set subject._mgmt in setup
// but now, this seems to work and feels cleaner
realMozApps = navigator.mozApps;
navigator.mozApps = { mgmt: MockAppsMgmt };
});
suiteTeardown(function() {
navigator.mozL10n = realL10n;
navigator.mozApps = realMozApps;
navigator.mozSettings = realMozSettings;
});
setup(function() {
this.sinon.stub(MockService, 'request', function(action) {
if (action === 'showCustomDialog') {
MockCustomDialog.show(
arguments[1],
arguments[2],
arguments[3],
arguments[4]);
} else {
MockCustomDialog.hide(
arguments[1],
arguments[2],
arguments[3],
arguments[4]);
}
});
mockApp = new MockApp();
subject = new AppUpdatable(mockApp);
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_UNPLUGGED] = 25;
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_PLUGGED] = 10;
navigator.mozL10n.get.withArgs(SYSTEM_LOW_BATTERY_L10N_KEY).reset();
fakeDispatchEvent = function(type, value) {
lastDispatchedEvent = {
type: type,
value: value
};
};
subject._dispatchEvent = fakeDispatchEvent;
var fakeScreen = document.createElement('div');
fakeScreen.id = 'screen';
document.body.appendChild(fakeScreen);
});
teardown(function() {
MockAppsMgmt.mTeardown();
subject._dispatchEvent = realDispatchEvent;
lastDispatchedEvent = null;
});
function downloadAvailableSuite(name, setupFunc) {
suite(name, function() {
setup(setupFunc);
test('should add self to the available downloads', function() {
assert.isNotNull(MockUpdateManager.mLastUpdatesAdd);
assert.equal(MockUpdateManager.mLastUpdatesAdd.app.mId,
mockApp.mId);
});
suite('first progress', function() {
setup(function() {
mockApp.mTriggerDownloadProgress(42);
});
test('should add self to active downloads', function() {
assert.isNotNull(MockUpdateManager.mLastDownloadsAdd);
assert.equal(MockUpdateManager.mLastDownloadsAdd.app.mId,
mockApp.mId);
});
test('should start with first progress value', function() {
assert.equal(42, subject.progress);
});
});
});
}
suite('init', function() {
test('should keep a reference to the app', function() {
assert.equal(mockApp, subject.app);
});
test('should handle fresh app with just an updateManifest', function() {
var freshApp = new MockApp();
freshApp.manifest = undefined;
subject = new AppUpdatable(freshApp);
assert.equal(freshApp, subject.app);
});
test('should add itself to updatable apps', function() {
assert.equal(MockUpdateManager.mLastUpdatableAdd, subject);
});
test('should remember about the update on startup', function() {
asyncStorage.mItems[SystemUpdatable.KNOWN_UPDATE_FLAG] = true;
var systemUpdatable = new SystemUpdatable(); // jshint ignore:line
assert.equal(MockUpdateManager.mCheckForUpdatesCalledWith, true);
});
downloadAvailableSuite('app has a download available', function() {
mockApp.downloadAvailable = true;
subject = new AppUpdatable(mockApp);
});
suite('applyDownload', function() {
setup(function() {
mockApp.readyToApplyDownload = true;
subject = new AppUpdatable(mockApp);
});
test('should apply update if downloaded', function() {
assert.equal(MockAppsMgmt.mLastAppApplied, mockApp);
});
test('should kill the app if downloaded', function() {
assert.isTrue(MockService.request.calledWith('kill', mockApp.origin));
});
});
});
suite('infos', function() {
suite('name', function() {
test('should give a name for app updates', function() {
assert.equal('Mock app', subject.name);
});
});
suite('size', function() {
test('should give packaged app update size', function() {
assert.equal(null, subject.size);
});
test('should return null for hosted apps', function() {
mockApp.updateManifest = null;
subject = new AppUpdatable(mockApp);
assert.isNull(subject.size);
});
test('should update size on download available', function() {
mockApp.updateManifest = null;
subject = new AppUpdatable(mockApp);
assert.isNull(subject.size);
mockApp.mTriggerDownloadAvailable(45678);
assert.equal(45678, subject.size);
});
});
});
suite('actions', function() {
suite('ask for download', function() {
setup(function() {
mockApp.mTriggerDownloadAvailable();
subject.download();
});
test('should call download on the app', function() {
assert.isTrue(mockApp.mDownloadCalled);
});
});
suite('download system update', function() {
setup(function() {
subject = new SystemUpdatable(42);
subject._dispatchEvent = fakeDispatchEvent;
subject.progress = 42;
subject.download();
});
test('should send download message for system updates', function() {
assert.equal('update-available-result', lastDispatchedEvent.type);
assert.equal('download', lastDispatchedEvent.value);
});
test('should add system updates to active downloads too', function() {
assert.isNotNull(MockUpdateManager.mLastDownloadsAdd);
assert.equal(subject, MockUpdateManager.mLastDownloadsAdd);
});
test('should start system updates with progress 0 too', function() {
assert.equal(subject.progress, 0);
});
test('should do nothing if already downloading', function() {
lastDispatchedEvent = null;
subject.progress = 42;
subject.download();
assert.equal(subject.progress, 42);
assert.isNull(lastDispatchedEvent);
});
});
suite('cancel app update download', function() {
setup(function() {
subject.cancelDownload();
});
test('should call cancelDownload on the app', function() {
assert.isTrue(mockApp.mCancelCalled);
});
});
suite('cancel system update download', function() {
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
subject = new SystemUpdatable(42);
subject.download();
subject._dispatchEvent = fakeDispatchEvent;
subject.cancelDownload();
});
test('should send cancel message', function() {
assert.equal('update-download-cancel', lastDispatchedEvent.type);
});
test('should remove the downloading flag', function() {
assert.isFalse(subject.downloading);
});
});
suite('signal system update ready', function() {
var addEventListenerSpy, dispatchEventSpy;
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
dispatchEventSpy = this.sinon.spy(SystemUpdatable.prototype,
'_dispatchEvent');
addEventListenerSpy = this.sinon.spy(window, 'addEventListener');
subject = new SystemUpdatable(42);
});
test('should add event listener', function() {
sinon.assert.calledOnce(addEventListenerSpy);
sinon.assert.calledWith(addEventListenerSpy, 'mozChromeEvent');
});
test('should send ready message', function() {
sinon.assert.calledOnce(dispatchEventSpy);
sinon.assert.calledWith(dispatchEventSpy, 'update-prompt-ready');
});
test('should have proper ordering', function() {
sinon.assert.callOrder(addEventListenerSpy, dispatchEventSpy);
});
});
});
suite('events', function() {
suite('apps events', function() {
// This function checks that we release the callbacks properly
// at the end of a download. Assumes subject.download() was called.
function testCleanup() {
test('should stop responding to progress', function() {
mockApp.mTriggerDownloadProgress(42);
assert.notEqual(subject.progress, 42);
});
test('should stop responding to error', function() {
MockUpdateManager.mErrorBannerRequested = false;
mockApp.mTriggerDownloadError();
assert.isFalse(MockUpdateManager.mErrorBannerRequested);
});
test('progress should be reset', function() {
assert.isNull(subject.progress);
});
}
downloadAvailableSuite('ondownloadavailable', function() {
mockApp.mTriggerDownloadAvailable();
});
suite('ondownloadavailable when not installed', function() {
setup(function() {
mockApp.installState = 'pending';
mockApp.mTriggerDownloadAvailable();
});
test('should not add self to the available downloads', function() {
assert.isNull(MockUpdateManager.mLastUpdatesAdd);
});
test('should not answer to progress', function() {
mockApp.mTriggerDownloadSuccess();
assert.isNull(MockUpdateManager.mLastDownloadsRemoval);
});
});
suite('downloadavailable at init when not installed', function() {
setup(function() {
mockApp.installState = 'pending';
subject = new AppUpdatable(mockApp);
mockApp.mTriggerDownloadAvailable();
});
test('should not add self to the available downloads', function() {
assert.isNull(MockUpdateManager.mLastUpdatesAdd);
});
test('should not answer to progress', function() {
mockApp.mTriggerDownloadSuccess();
assert.isNull(MockUpdateManager.mLastDownloadsRemoval);
});
});
suite('ondownloadsuccess', function() {
test('should remove self from active downloads', function() {
mockApp.mTriggerDownloadAvailable();
mockApp.mTriggerDownloadProgress(42);
mockApp.mTriggerDownloadSuccess();
assert.isNotNull(MockUpdateManager.mLastDownloadsRemoval);
assert.equal(MockUpdateManager.mLastDownloadsRemoval.app.mId,
mockApp.mId);
});
test('should call downloaded of UpdateManager', function() {
mockApp.mTriggerDownloadAvailable();
mockApp.mTriggerDownloadProgress(42);
mockApp.mTriggerDownloadSuccess();
assert.isTrue(MockUpdateManager.mDownloadedCalled);
});
test('should not remove self if not downloading', function() {
mockApp.mTriggerDownloadSuccess();
assert.isNull(MockUpdateManager.mLastDownloadsRemoval);
});
test('should remove self from available downloads', function() {
mockApp.mTriggerDownloadAvailable();
mockApp.mTriggerDownloadProgress(42);
mockApp.mTriggerDownloadSuccess();
assert.isNotNull(MockUpdateManager.mLastUpdatesRemoval);
assert.equal(MockUpdateManager.mLastUpdatesRemoval.app.mId,
mockApp.mId);
});
suite('application of the download', function() {
test('should apply if the app is not in foreground', function() {
mockApp.mTriggerDownloadAvailable();
MockService.mockQueryWith('AppWindowManager.getActiveWindow',
{ origin: 'homescreen' });
mockApp.mTriggerDownloadSuccess();
assert.isNotNull(MockAppsMgmt.mLastAppApplied);
assert.equal(MockAppsMgmt.mLastAppApplied.mId, mockApp.mId);
});
test('should wait for appwillclose if it is', function() {
var origin = 'http://testapp.gaiamobile.org';
mockApp.origin = origin;
MockService.mockQueryWith('AppWindowManager.getActiveWindow',
mockApp);
mockApp.mTriggerDownloadAvailable();
mockApp.mTriggerDownloadSuccess();
assert.isNull(MockAppsMgmt.mLastAppApplied);
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('appwillclose', true, false,
{ origin: origin });
window.dispatchEvent(evt);
assert.isNotNull(MockAppsMgmt.mLastAppApplied);
assert.equal(MockAppsMgmt.mLastAppApplied.mId, mockApp.mId);
});
test('should kill the app before applying the update', function() {
MockService.mockQueryWith('AppWindowManager.getActiveWindow',
{ origin: 'test' });
mockApp.mTriggerDownloadAvailable();
mockApp.mTriggerDownloadSuccess();
assert.isTrue(MockService.request.calledWith('kill',
'https://testapp.gaiamobile.org'));
});
});
});
suite('ondownloaderror', function() {
setup(function() {
mockApp.mTriggerDownloadAvailable();
mockApp.mTriggerDownloadError();
});
test('should request error banner', function() {
assert.isTrue(MockUpdateManager.mErrorBannerRequested);
});
test('should remove self from active downloads', function() {
assert.isNotNull(MockUpdateManager.mLastDownloadsRemoval);
assert.equal(MockUpdateManager.mLastDownloadsRemoval.app.mId,
mockApp.mId);
});
test('progress should be reset', function() {
assert.isNull(subject.progress);
});
test('should still answer to progress events', function() {
mockApp.mTriggerDownloadProgress(42);
assert.equal(42, subject.progress);
});
});
suite('ondownloaderror, downloadAvailable = false', function() {
setup(function() {
mockApp.mTriggerDownloadAvailable();
mockApp.downloadAvailable = false;
mockApp.mTriggerDownloadError();
});
test('should remove self from available updates', function() {
assert.equal(MockUpdateManager.mLastUpdatesRemoval, subject);
});
});
suite('onprogress', function() {
setup(function() {
mockApp.mTriggerDownloadAvailable();
});
test('should send progress to update manager', function() {
mockApp.mTriggerDownloadProgress(1234);
assert.equal(1234, MockUpdateManager.mProgressCalledWith);
});
test('should send progress delta to update manager', function() {
mockApp.mTriggerDownloadProgress(1234);
mockApp.mTriggerDownloadProgress(2234);
assert.equal(1000, MockUpdateManager.mProgressCalledWith);
});
});
suite('ondownloadapplied', function() {
setup(function() {
mockApp.mTriggerDownloadAvailable();
mockApp.mTriggerDownloadApplied();
});
testCleanup();
});
});
suite('system update events', function() {
var errorObject = {
appVersion: '99.0',
buildID: '20151008155421',
detailsURL: 'http://www.mozilla.com/test/sample-details.html',
displayVersion: '99.0',
errorCode: '80',
isOSUpdate: true,
platformVersion: null,
previousAppVersion: '44.0a1',
state: 'failed',
statusText: 'Install Failed',
size: 225860143,
updateType: 'complete',
type: 'update-error'
};
function forceBatteryThresholdToMidCharge() {
return {
then: function(callback) {
callback(MID_CHARGE);
}
};
}
setup(function() {
subject = new SystemUpdatable(42);
sinon.stub(subject, 'getBatteryPercentageThreshold',
forceBatteryThresholdToMidCharge);
subject._dispatchEvent = fakeDispatchEvent;
subject.download();
});
suite('update-downloaded', function() {
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
var event = new MockChromeEvent({
type: 'update-downloaded'
});
subject.handleEvent(event);
});
test('should reset the downloading flag', function() {
assert.isFalse(subject.downloading);
});
test('should signal the UpdateManager', function() {
assert.isTrue(MockUpdateManager.mDownloadedCalled);
});
test('should remove the system download from the queue', function() {
assert.isNotNull(MockUpdateManager.mLastDownloadsRemoval);
assert.equal(subject, MockUpdateManager.mLastDownloadsRemoval);
assert.equal(MockUpdateManager.mDownloads.length, 0);
});
test('should reset SystemUpdatable.KNOWN_UPDATE_FLAG', function() {
assert.isUndefined(
asyncStorage.mItems[SystemUpdatable.KNOWN_UPDATE_FLAG]);
});
testSystemApplyPrompt();
});
suite('update-prompt-apply', function() {
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
MockUtilityTray.show();
var event = new MockChromeEvent({
type: 'update-prompt-apply'
});
subject.handleEvent(event);
});
test('should reset SystemUpdatable.KNOWN_UPDATE_FLAG', function() {
assert.isUndefined(
asyncStorage.mItems[SystemUpdatable.KNOWN_UPDATE_FLAG]);
});
testSystemApplyPrompt();
});
suite('update-error', function() {
setup(function() {
subject = new SystemUpdatable(42);
var event = new MockChromeEvent(errorObject);
subject.handleEvent(event);
});
test('should send error notification', function() {
assert.equal(MockNotificationHelper.mTitleL10n,
'systemUpdateError');
assert.equal(MockNotificationHelper.mOptions.bodyL10n,
'systemUpdateErrorDetails');
assert.equal(MockNotificationHelper.mOptions.tag,
'systemUpdateError');
assert.equal(MockNotificationHelper.mOptions.mozbehavior.showOnlyOnce,
true);
assert.equal(MockNotificationHelper.mOptions.closeOnClick, false);
});
test('should remove self from active downloads', function() {
assert.isNotNull(MockUpdateManager.mLastDownloadsRemoval);
assert.equal(subject, MockUpdateManager.mLastDownloadsRemoval);
});
test('should remove the downloading flag', function() {
assert.isFalse(subject.downloading);
});
});
suite('update error notification details', function() {
setup(function() {
subject = new SystemUpdatable(42);
var event = new MockChromeEvent(errorObject);
subject.showUpdateErrorDetails(event);
});
test('utility tray hidden', function() {
assert.isTrue(MockService.request.calledWith('UtilityTray:hide'));
});
test('show custom dialog', function() {
assert.isTrue(MockService.request.calledWith(
'showCustomDialog', 'systemUpdateError'));
assert.equal(MockService.request.lastCall.args[2].id,
'wantToReportNow');
assert.equal(MockService.request.lastCall.args[3].title,
'later');
assert.equal(MockService.request.lastCall.args[4].title,
'report');
});
test('custom dialog cancel callback', function() {
var cancel = MockService.request.lastCall.args[3].callback;
cancel();
assert.isTrue(MockService.request.calledWith('hideCustomDialog'));
});
test('custom dialog report callback', function() {
var dispatchSpy = this.sinon.spy(window, 'dispatchEvent');
var report = MockService.request.lastCall.args[4].callback;
report();
assert.isTrue(MockService.request.calledWith('hideCustomDialog'));
sinon.assert.calledOnce(dispatchSpy);
var contentEvent = dispatchSpy.lastCall.args[0];
assert.equal(contentEvent.type, 'requestSystemLogs');
});
});
suite('update download events', function() {
var event;
setup(function() {
subject = new SystemUpdatable(98734);
subject.download();
});
suite('when the download starts', function() {
setup(function() {
event = new MockChromeEvent({
type: 'update-download-started',
total: 98734
});
});
test('should clear paused flag', function() {
subject.paused = true;
subject.handleEvent(event);
assert.isFalse(subject.paused);
});
});
suite('when the download receives progress', function() {
setup(function() {
event = new MockChromeEvent({
type: 'update-download-progress',
progress: 1234,
total: 98734
});
});
test('should send progress to update manager', function() {
subject.handleEvent(event);
assert.equal(1234, MockUpdateManager.mProgressCalledWith);
});
test('should send progress delta to update manager', function() {
subject.handleEvent(event);
event.detail.progress = 2234;
subject.handleEvent(event);
assert.equal(1000, MockUpdateManager.mProgressCalledWith);
});
});
suite('when the download is paused', function() {
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
event = new MockChromeEvent({
type: 'update-download-stopped',
paused: true
});
subject.handleEvent(event);
});
test('should set the paused flag', function() {
assert.isTrue(subject.paused);
});
test('shouldn\'t signal "started uncompressing"', function() {
assert.isFalse(MockUpdateManager.mStartedUncompressingCalled);
});
test('should not reset SystemUpdatable.KNOWN_UPDATE_FLAG',
function() {
assert.isTrue(
asyncStorage.mItems[SystemUpdatable.KNOWN_UPDATE_FLAG]);
});
});
suite('when the download is complete', function() {
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
event = new MockChromeEvent({
type: 'update-download-stopped',
paused: false
});
subject.handleEvent(event);
});
test('should clear the paused flag', function() {
assert.isFalse(subject.paused);
});
test('should signal the UpdateManager', function() {
assert.isTrue(MockUpdateManager.mStartedUncompressingCalled);
});
test('should not reset SystemUpdatable.KNOWN_UPDATE_FLAG',
function() {
assert.isTrue(
asyncStorage.mItems[SystemUpdatable.KNOWN_UPDATE_FLAG]);
});
});
suite('when an error occurs', function() {
setup(function() {
MockUpdateManager.mTeardown();
subject = new SystemUpdatable(98734);
subject._dispatchEvent =
function errorDuringDispatch(type, result) {
fakeDispatchEvent.call(subject, type, result);
subject.handleEvent(new MockChromeEvent({
type: 'update-error'
}));
};
subject.download();
subject._dispatchEvent = fakeDispatchEvent;
});
test('should request error banner', function() {
assert.isTrue(MockUpdateManager.mErrorBannerRequested);
});
test('should remove self from active downloads', function() {
assert.isNotNull(MockUpdateManager.mLastDownloadsRemoval);
assert.equal(subject, MockUpdateManager.mLastDownloadsRemoval);
assert.equal(MockUpdateManager.mDownloads.length, 0);
});
test('should remove the downloading flag', function() {
assert.isFalse(subject.downloading);
});
});
});
});
});
function testSystemApplyPrompt() {
function testSystemApplyPromptBatteryOk() {
test('apply prompt shown', function() {
assert.isTrue(MockCustomDialog.mShown);
assert.equal('systemUpdateReady', MockCustomDialog.mShowedTitle);
assert.equal('wantToInstallNow', MockCustomDialog.mShowedMsg);
assert.equal(
'later',
MockCustomDialog.mShowedCancel.title
);
assert.equal(
'installNow',
MockCustomDialog.mShowedConfirm.title);
});
}
function testSystemApplyPromptBatteryNok(expectedThreshold) {
test('battery prompt shown', function() {
assert.isTrue(MockCustomDialog.mShown);
assert.equal('systemUpdateReady', MockCustomDialog.mShowedTitle);
assert.deepEqual(
MockCustomDialog.mShowedMsg,
{
id: SYSTEM_LOW_BATTERY_L10N_KEY,
args: { threshold: expectedThreshold }
}
);
assert.equal('ok', MockCustomDialog.mShowedCancel.title);
});
test('battery prompt callback', function() {
assert.equal(subject.declineInstallBattery.name,
MockCustomDialog.mShowedCancel.callback.name);
subject.declineInstallBattery();
assert.isFalse(MockCustomDialog.mShown);
assert.equal('update-prompt-apply-result', lastDispatchedEvent.type);
assert.equal('low-battery', lastDispatchedEvent.value);
});
}
testSystemApplyPromptBatteryOk();
test('utility tray hidden', function() {
assert.isTrue(MockService.request.calledWith('UtilityTray:hide'));
});
test('apply prompt cancel callback', function() {
assert.equal(subject.declineInstall.name,
MockCustomDialog.mShowedCancel.callback.name);
subject.declineInstallWait();
assert.isFalse(MockCustomDialog.mShown);
assert.equal('update-prompt-apply-result', lastDispatchedEvent.type);
assert.equal('wait', lastDispatchedEvent.value);
});
test('apply prompt confirm callback', function() {
assert.equal(subject.acceptInstall.name,
MockCustomDialog.mShowedConfirm.callback.name);
subject.acceptInstall();
assert.isFalse(MockCustomDialog.mShown);
assert.equal('update-prompt-apply-result', lastDispatchedEvent.type);
assert.equal('restart', lastDispatchedEvent.value);
});
suite('battery level', function() {
var realNavigatorBattery;
setup(function() {
realNavigatorBattery = window.navigator.battery;
Object.defineProperty(window.navigator, 'battery', {
configurable: true,
value: MockNavigatorBattery
});
});
teardown(function() {
Object.defineProperty(window.navigator, 'battery', {
configurable: true,
value: realNavigatorBattery
});
});
suite('get threshold depending on charging state', function() {
setup(function() {
subject.getBatteryPercentageThreshold =
subject.constructor.prototype.getBatteryPercentageThreshold;
});
test('threshold while charging', function(done) {
MockNavigatorBattery.charging = true;
subject.getBatteryPercentageThreshold().then(
function(threshold) {
assert.equal(
threshold,
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_PLUGGED]
);
done();
},
function() {
assert.ok(false);
done();
}
);
});
test('threshold while not charging', function(done) {
MockNavigatorBattery.charging = false;
subject.getBatteryPercentageThreshold().then(
function(threshold) {
assert.equal(
threshold,
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_UNPLUGGED]
);
done();
},
function() {
assert.ok(false);
done();
}
);
});
test('threshold has a default value if not defined', function(done) {
delete MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_PLUGGED];
delete MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_UNPLUGGED];
subject.getBatteryPercentageThreshold().then(
function(threshold) {
assert.equal(
threshold,
subject.BATTERY_FALLBACK_THRESHOLD
);
done();
},
function() {
assert.ok(false);
done();
}
);
});
test('threshold has a default value if over the range. ',
function(done) {
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_PLUGGED] = 105;
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_UNPLUGGED] = 105;
subject.getBatteryPercentageThreshold().then(
function(threshold) {
assert.equal(
threshold,
subject.BATTERY_FALLBACK_THRESHOLD
);
done();
},
function() {
assert.ok(false);
done();
}
);
}
);
test('threshold has a default value if under the range. ',
function(done) {
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_PLUGGED] = -10;
MockNavigatorSettings.mSettings[BATTERY_THRESHOLD_UNPLUGGED] = -10;
subject.getBatteryPercentageThreshold().then(
function(threshold) {
assert.equal(
threshold,
subject.BATTERY_FALLBACK_THRESHOLD
);
done();
},
function() {
assert.ok(false);
done();
}
);
}
);
test('threshold has a default even if Settings fails', function(done) {
// Current MockSettings can not be forced to fail, so preparing our
// own stub.
navigator.mozSettings = {
createLock: function() {
return {
get: function(key) {
var fakedFailingRequest = {};
setTimeout(function() {
fakedFailingRequest.onerror('error');
});
return fakedFailingRequest;
}
};
}
};
subject.getBatteryPercentageThreshold().then(
function(threshold) {
assert.equal(
threshold,
subject.BATTERY_FALLBACK_THRESHOLD
);
done();
},
function() {
assert.ok(false);
done();
}
);
navigator.mozSettings = MockNavigatorSettings;
});
});
suite('low battery', function() {
var event;
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
MockUtilityTray.show();
MockNavigatorBattery.level = 0.1;
event = new MockChromeEvent({
type: 'update-prompt-apply'
});
});
suite('ota update package', function() {
setup(function() {
event.detail.isOSUpdate = false;
subject.handleEvent(event);
});
testSystemApplyPromptBatteryOk();
});
suite('fota update package', function() {
setup(function() {
event.detail.isOSUpdate = true;
subject.handleEvent(event);
});
testSystemApplyPromptBatteryNok(MID_CHARGE);
});
});
suite('high battery', function() {
var event;
setup(function() {
asyncStorage.setItem(SystemUpdatable.KNOWN_UPDATE_FLAG, true);
MockUtilityTray.show();
MockNavigatorBattery.level = 0.9;
event = new MockChromeEvent({
type: 'update-prompt-apply'
});
subject.handleEvent(event);
});
suite('ota update package', function() {
setup(function() {
event.detail.isOSUpdate = false;
subject.handleEvent(event);
});
testSystemApplyPromptBatteryOk();
});
suite('fota update package', function() {
setup(function() {
event.detail.isOSUpdate = true;
subject.handleEvent(event);
});
testSystemApplyPromptBatteryOk();
});
});
});
}
});