refactor(GUI): turn the update notifier modal into a native dialog (#1359)

Electron v1.6.1 introduced checkbox support to the native message
dialog, giving us everything that was needed to implement the update
notifier modal using a native dialog.

This change allows us to get rid of a lot code.

See: https://github.com/electron/electron/pull/8590
Change-Type: patch
Changelog-Entry: Turn the update notifier modal into a native dialog.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
Juan Cruz Viotti 2017-05-23 19:06:35 -04:00 committed by GitHub
parent 3df6cd07d0
commit 1e169315fd
15 changed files with 597 additions and 404 deletions

View File

@ -1,3 +1,4 @@
boolen->boolean
aknowledge->acknowledge
seleted->selected
reming->remind

View File

@ -39,6 +39,7 @@ const flashState = require('./models/flash-state');
const settings = require('./models/settings');
const windowProgress = require('./os/window-progress');
const analytics = require('./modules/analytics');
const updateNotifier = require('./components/update-notifier');
const Store = require('./models/store');
@ -57,7 +58,6 @@ const app = angular.module('Etcher', [
// Components
require('./components/svg-icon/svg-icon'),
require('./components/update-notifier/update-notifier'),
require('./components/warning-modal/warning-modal'),
require('./components/safe-webview/safe-webview'),
@ -89,19 +89,21 @@ app.run(() => {
].join('\n'));
});
app.run((ErrorService, UpdateNotifierService, SelectionStateModel) => {
app.run((ErrorService, SelectionStateModel) => {
analytics.logEvent('Application start');
const currentVersion = packageJSON.version;
const currentReleaseType = release.getReleaseType(currentVersion);
const shouldCheckForUpdates = UpdateNotifierService.shouldCheckForUpdates({
ignoreSleepUpdateCheck: currentReleaseType !== release.RELEASE_TYPE.PRODUCTION
const shouldCheckForUpdates = updateNotifier.shouldCheckForUpdates({
currentVersion: packageJSON.version,
lastSleptUpdateNotifier: settings.get('lastSleptUpdateNotifier'),
lastSleptUpdateNotifierVersion: settings.get('lastSleptUpdateNotifierVersion')
});
const currentReleaseType = release.getReleaseType(currentVersion);
if (_.some([
!shouldCheckForUpdates,
process.env.ETCHER_DISABLE_UPDATES,
currentReleaseType === release.RELEASE_TYPE.UNKNOWN
process.env.ETCHER_DISABLE_UPDATES
])) {
analytics.logEvent('Not checking for updates', {
shouldCheckForUpdates,
@ -148,7 +150,7 @@ app.run((ErrorService, UpdateNotifierService, SelectionStateModel) => {
latestVersion
});
return UpdateNotifierService.notify(latestVersion, {
return updateNotifier.notify(latestVersion, {
allowSleepUpdateCheck: currentReleaseType === release.RELEASE_TYPE.PRODUCTION
});
}).catch(ErrorService.reportException);

View File

@ -0,0 +1,148 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const electron = require('electron');
const Bluebird = require('bluebird');
const _ = require('lodash');
const settings = require('../models/settings');
const analytics = require('../modules/analytics');
const units = require('../../shared/units');
const release = require('../../shared/release');
const packageJSON = require('../../../package.json');
/**
* @summary The number of days the update notifier can be put to sleep
* @constant
* @private
* @type {Number}
*/
exports.UPDATE_NOTIFIER_SLEEP_DAYS = packageJSON.updates.sleepDays;
/**
* @summary The current Electron browser window
* @constant
* @private
* @type {Object}
*/
const currentWindow = electron.remote.getCurrentWindow();
/**
* @summary Determine if it's time to check for updates
* @function
* @public
*
* @param {Object} options - options
* @param {Number} [options.lastSleptUpdateNotifier] - last slept update notifier time
* @param {String} [options.lastSleptUpdateNotifierVersion] - last slept update notifier version
* @param {String} options.currentVersion - current version
* @returns {Boolean} should check for updates
*
* @example
* if (updateNotifier.shouldCheckForUpdates({
* lastSleptUpdateNotifier: Date.now(),
* lastSleptUpdateNotifierVersion: '1.0.0',
* currentVersion: '1.0.0'
* })) {
* console.log('We should check for updates!');
* }
*/
exports.shouldCheckForUpdates = (options) => {
_.defaults(options, {
lastSleptUpdateNotifierVersion: options.currentVersion
});
if (_.some([
!options.lastSleptUpdateNotifier,
release.getReleaseType(options.currentVersion) !== release.RELEASE_TYPE.PRODUCTION,
options.currentVersion !== options.lastSleptUpdateNotifierVersion
])) {
return true;
}
return Date.now() - options.lastSleptUpdateNotifier > units.daysToMilliseconds(this.UPDATE_NOTIFIER_SLEEP_DAYS);
};
/**
* @summary Open the update notifier widget
* @function
* @public
*
* @param {String} version - version
* @param {Object} [options] - options
* @param {Boolean} [options.allowSleepUpdateCheck=true] - allow sleeping the update check
* @returns {Promise}
*
* @example
* updateNotifier.notify('1.0.0-beta.16', {
* allowSleepUpdateCheck: true
* });
*/
exports.notify = (version, options = {}) => {
const BUTTONS = [
'Download',
'Skip'
];
const BUTTON_CONFIRMATION_INDEX = _.indexOf(BUTTONS, _.first(BUTTONS));
const BUTTON_REJECTION_INDEX = _.indexOf(BUTTONS, _.last(BUTTONS));
const dialogOptions = {
type: 'info',
buttons: BUTTONS,
defaultId: BUTTON_CONFIRMATION_INDEX,
cancelId: BUTTON_REJECTION_INDEX,
title: 'New Update Available!',
message: `Etcher ${version} is available for download`
};
if (_.get(options, [ 'allowSleepUpdateCheck' ], true)) {
_.merge(dialogOptions, {
checkboxLabel: `Remind me again in ${this.UPDATE_NOTIFIER_SLEEP_DAYS} days`,
checkboxChecked: false
});
}
return new Bluebird((resolve) => {
electron.remote.dialog.showMessageBox(currentWindow, dialogOptions, (response, checkboxChecked) => {
return resolve({
agreed: response === BUTTON_CONFIRMATION_INDEX,
sleepUpdateCheck: checkboxChecked || false
});
});
}).then((results) => {
// Only update the last slept update timestamp if the
// user ticked the "Remind me again in ..." checkbox,
// but didn't agree.
if (results.sleepUpdateCheck && !results.agreed) {
settings.set('lastSleptUpdateNotifier', Date.now());
settings.set('lastSleptUpdateNotifierVersion', packageJSON.version);
}
analytics.logEvent('Close update modal', {
sleepUpdateCheck: results.sleepUpdateCheck,
notifyVersion: version,
currentVersion: packageJSON.version,
agreed: results.agreed
});
if (results.agreed) {
electron.shell.openExternal('https://etcher.io?ref=etcher_update');
}
});
};

View File

@ -1,70 +0,0 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const settings = require('../../../models/settings');
const analytics = require('../../../modules/analytics');
module.exports = function($uibModalInstance, UPDATE_NOTIFIER_SLEEP_DAYS, options) {
// We update this value in this controller since its the only place
// where we can be sure the modal was really presented to the user.
// If the controller is instantiated, means the modal was shown.
// Compare that to `UpdateNotifierService.notify()`, which could
// have been called, but the modal could have failed to be shown.
settings.set('lastUpdateNotify', Date.now());
/**
* @summary The number of days the update notified can be put to sleep
* @constant
* @public
* @type {Number}
*/
this.sleepDays = UPDATE_NOTIFIER_SLEEP_DAYS;
/**
* @summary Settings model
* @type {Object}
* @public
*/
this.settings = settings;
/**
* @summary Modal options
* @type {Object}
* @public
*/
this.options = options;
/**
* @summary Close the modal
* @function
* @public
*
* @example
* UpdateNotifierController.closeModal();
*/
this.closeModal = () => {
analytics.logEvent('Close update modal', {
sleepUpdateCheck: this.sleepUpdateCheck,
notifyVersion: options.version
});
$uibModalInstance.dismiss();
};
};

View File

@ -1,89 +0,0 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const _ = require('lodash');
const units = require('../../../../shared/units');
const settings = require('../../../models/settings');
module.exports = function(ModalService, UPDATE_NOTIFIER_SLEEP_DAYS) {
/**
* @summary Determine if it's time to check for updates
* @function
* @public
*
* @param {Object} [options] - options
* @param {Boolean} [options.ignoreSleepUpdateCheck] - ignore sleep update check
* @returns {Boolean} should check for updates
*
* @example
* if (UpdateNotifierService.shouldCheckForUpdates({
* ignoreSleepUpdateCheck: false
* })) {
* console.log('We should check for updates!');
* }
*/
this.shouldCheckForUpdates = (options = {}) => {
const lastUpdateNotify = settings.get('lastUpdateNotify');
if (_.some([
!settings.get('sleepUpdateCheck'),
!lastUpdateNotify,
_.get(options, [ 'ignoreSleepUpdateCheck' ], false)
])) {
return true;
}
if (lastUpdateNotify - Date.now() > units.daysToMilliseconds(UPDATE_NOTIFIER_SLEEP_DAYS)) {
settings.set('sleepUpdateCheck', false);
return true;
}
return false;
};
/**
* @summary Open the update notifier widget
* @function
* @public
*
* @param {String} version - version
* @param {Object} [options] - options
* @param {Boolean} [options.allowSleepUpdateCheck=true] - allow sleeping the update check
* @returns {Promise}
*
* @example
* UpdateNotifierService.notify('1.0.0-beta.16', {
* allowSleepUpdateCheck: true
* });
*/
this.notify = (version, options = {}) => {
return ModalService.open({
template: './components/update-notifier/templates/update-notifier-modal.tpl.html',
controller: 'UpdateNotifierController as modal',
size: 'update-notifier',
resolve: {
options: _.constant({
version,
allowSleepUpdateCheck: _.get(options, [ 'allowSleepUpdateCheck' ], true)
})
}
}).result;
};
};

View File

@ -1,22 +0,0 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.modal-update-notifier .checkbox {
color: $palette-theme-light-soft-foreground;
font-size: 11px;
margin-bottom: 0;
}

View File

@ -1,26 +0,0 @@
<div class="modal-header">
<h4 class="modal-title">New Update Available!</h4>
<button class="close" ng-click="modal.closeModal()">&times;</button>
</div>
<div class="modal-body">
<p>Etcher {{ ::modal.options.version }} is available for download</p>
<div class="checkbox" ng-if="modal.options.allowSleepUpdateCheck">
<label>
<input type="checkbox"
ng-model="modal.sleepUpdateCheck"
ng-change="modal.settings.set('sleepUpdateCheck', modal.sleepUpdateCheck)">
<span>Remind me again in {{::modal.sleepDays}} days</span>
</label>
</div>
</div>
<div class="modal-footer">
<div class="modal-menu">
<button class="button button-primary button-block"
os-open-external="https://etcher.io?ref=etcher_update">Download</button>
<button class="button button-default button-block"
ng-click="modal.closeModal()">Skip</button>
</div>
</div>

View File

@ -1,42 +0,0 @@
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
/**
* @module Etcher.Components.UpdateNotifier
*/
const angular = require('angular');
const MODULE_NAME = 'Etcher.Components.UpdateNotifier';
const UpdateNotifier = angular.module(MODULE_NAME, [
require('../modal/modal'),
require('../../os/open-external/open-external')
]);
/**
* @summary The number of days the update notifier can be put to sleep
* @constant
* @private
* @type {Number}
*/
const UPDATE_NOTIFIER_SLEEP_DAYS = 7;
UpdateNotifier.constant('UPDATE_NOTIFIER_SLEEP_DAYS', UPDATE_NOTIFIER_SLEEP_DAYS);
UpdateNotifier.controller('UpdateNotifierController', require('./controllers/update-notifier'));
UpdateNotifier.service('UpdateNotifierService', require('./services/update-notifier'));
module.exports = MODULE_NAME;

View File

@ -6274,26 +6274,6 @@ body {
position: initial;
max-width: 50%; }
/*
* Copyright 2016 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.modal-update-notifier .checkbox {
color: #b3b3b3;
font-size: 11px;
margin-bottom: 0; }
/*
* Copyright 2016 resin.io
*

View File

@ -49,9 +49,9 @@ const DEFAULT_STATE = Immutable.fromJS({
errorReporting: true,
unmountOnSuccess: true,
validateWriteOnSuccess: true,
sleepUpdateCheck: false,
includeUnstableUpdateChannel: !release.isStableRelease(packageJSON.version),
lastUpdateNotify: null
lastSleptUpdateNotifier: null,
lastSleptUpdateNotifierVersion: null
}
});

View File

@ -55,6 +55,13 @@ module.exports = function(WarningModalService, ErrorService) {
*/
this.model = settings;
/**
* @summary Environment
* @type {Object}
* @public
*/
this.disableUpdates = Boolean(process.env.ETCHER_DISABLE_UPDATES);
/**
* @summary Toggle setting
* @function

View File

@ -40,7 +40,7 @@
</label>
</div>
<div class="checkbox">
<div class="checkbox" ng-hide="settings.disableUpdates">
<label>
<input type="checkbox"
ng-model="settings.currentData.includeUnstableUpdateChannel"

View File

@ -31,7 +31,6 @@ $link-color: #ddd;
@import "./components/button";
@import "./components/tick";
@import "../components/modal/styles/modal";
@import "../components/update-notifier/styles/update-notifier";
@import "../components/progress-button/styles/progress-button";
@import "../components/drive-selector/styles/drive-selector";
@import "../components/tooltip-modal/styles/tooltip-modal";

View File

@ -3,6 +3,7 @@
"displayName": "Etcher",
"version": "1.0.0",
"updates": {
"sleepDays": 7,
"semverRange": "<2.0.0"
},
"main": "lib/start.js",

View File

@ -1,150 +1,454 @@
/*
* Copyright 2017 resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const m = require('mochainon');
const angular = require('angular');
const _ = require('lodash');
const units = require('../../../lib/shared/units');
const settings = require('../../../lib/gui/models/settings');
require('angular-mocks');
const updateNotifier = require('../../../lib/gui/components/update-notifier');
describe('Browser: UpdateNotifier', function() {
describe('Browser: updateNotifier', function() {
beforeEach(angular.mock.module(
require('../../../lib/gui/components/update-notifier/update-notifier')
));
describe('.UPDATE_NOTIFIER_SLEEP_DAYS', function() {
describe('UpdateNotifierService', function() {
it('should be an integer', function() {
m.chai.expect(_.isInteger(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS)).to.be.true;
});
describe('.shouldCheckForUpdates()', function() {
it('should be greater than 0', function() {
m.chai.expect(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS > 0).to.be.true;
});
let UpdateNotifierService;
let UPDATE_NOTIFIER_SLEEP_DAYS;
});
beforeEach(angular.mock.inject(function(_UpdateNotifierService_, _UPDATE_NOTIFIER_SLEEP_DAYS_) {
UpdateNotifierService = _UpdateNotifierService_;
UPDATE_NOTIFIER_SLEEP_DAYS = _UPDATE_NOTIFIER_SLEEP_DAYS_;
}));
describe('.shouldCheckForUpdates()', function() {
describe('given ignoreSleepUpdateCheck is false', function() {
const UPDATE_NOTIFIER_SLEEP_MS = units.daysToMilliseconds(updateNotifier.UPDATE_NOTIFIER_SLEEP_DAYS);
beforeEach(function() {
this.ignoreSleepUpdateCheck = false;
});
_.each([
describe('given the `sleepUpdateCheck` is disabled', function() {
// Given the `lastSleptUpdateNotifier` was never updated
beforeEach(function() {
settings.set('sleepUpdateCheck', false);
});
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: undefined,
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: undefined,
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: undefined,
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '1.0.0',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '1.0.0+6374412',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '1.0.0+foo',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: undefined,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+foo'
},
expected: true
},
it('should return true', function() {
const result = UpdateNotifierService.shouldCheckForUpdates({
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
});
// Given the `lastSleptUpdateNotifier` was very recently updated
m.chai.expect(result).to.be.true;
});
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '1.0.0',
currentVersion: '1.0.0'
},
expected: false
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '1.0.0+6374412',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '1.0.0+foo',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+foo'
},
expected: true
},
});
// Given the `lastSleptUpdateNotifier` was updated in the future
describe('given the `sleepUpdateCheck` is enabled', function() {
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '1.0.0',
currentVersion: '1.0.0'
},
expected: false
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '1.0.0+6374412',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '1.0.0+foo',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+foo'
},
expected: true
},
beforeEach(function() {
settings.set('sleepUpdateCheck', true);
});
// Given the `lastSleptUpdateNotifier` was updated far in the future
describe('given the `lastUpdateNotify` was never updated', function() {
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '1.0.0',
currentVersion: '1.0.0'
},
expected: false
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '1.0.0+6374412',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '1.0.0+foo',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() + UPDATE_NOTIFIER_SLEEP_MS + 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+foo'
},
expected: true
},
beforeEach(function() {
settings.set('lastUpdateNotify', undefined);
});
// Given the `lastSleptUpdateNotifier` was updated long ago
it('should return true', function() {
const result = UpdateNotifierService.shouldCheckForUpdates({
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
});
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '1.0.0',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '1.0.0+6374412',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '1.0.0+foo',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '0.0.0',
currentVersion: '1.0.0+foo'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+6374412'
},
expected: true
},
{
options: {
lastSleptUpdateNotifier: Date.now() - UPDATE_NOTIFIER_SLEEP_MS - 1000,
lastSleptUpdateNotifierVersion: '99.9.9',
currentVersion: '1.0.0+foo'
},
expected: true
}
m.chai.expect(result).to.be.true;
});
});
describe('given the `lastUpdateNotify` was very recently updated', function() {
beforeEach(function() {
settings.set('lastUpdateNotify', Date.now() + 1000);
});
it('should return false', function() {
const result = UpdateNotifierService.shouldCheckForUpdates({
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
});
m.chai.expect(result).to.be.false;
});
});
describe('given the `lastUpdateNotify` was updated long ago', function() {
beforeEach(function() {
const SLEEP_MS = units.daysToMilliseconds(UPDATE_NOTIFIER_SLEEP_DAYS);
settings.set('lastUpdateNotify', Date.now() + SLEEP_MS + 1000);
});
it('should return true', function() {
const result = UpdateNotifierService.shouldCheckForUpdates({
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
});
m.chai.expect(result).to.be.true;
});
it('should unset the `sleepUpdateCheck` setting', function() {
m.chai.expect(settings.get('sleepUpdateCheck')).to.be.true;
UpdateNotifierService.shouldCheckForUpdates({
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
});
m.chai.expect(settings.get('sleepUpdateCheck')).to.be.false;
});
});
});
});
describe('given ignoreSleepUpdateCheck is true', function() {
beforeEach(function() {
this.ignoreSleepUpdateCheck = true;
});
describe('given the `sleepUpdateCheck` is enabled', function() {
beforeEach(function() {
settings.set('sleepUpdateCheck', true);
});
describe('given the `lastUpdateNotify` was very recently updated', function() {
beforeEach(function() {
settings.set('lastUpdateNotify', Date.now() + 1000);
});
it('should return true', function() {
const result = UpdateNotifierService.shouldCheckForUpdates({
ignoreSleepUpdateCheck: this.ignoreSleepUpdateCheck
});
m.chai.expect(result).to.be.true;
});
});
});
], (testCase) => {
it(_.join([
`should return ${testCase.expected} if`,
`lastSleptUpdateNotifier=${testCase.options.lastSleptUpdateNotifier},`,
`lastSleptUpdateNotifierVersion=${testCase.options.lastSleptUpdateNotifierVersion}, and`,
`currentVersion=${testCase.options.currentVersion}`
], ' '), function() {
m.chai.expect(updateNotifier.shouldCheckForUpdates(testCase.options)).to.equal(testCase.expected);
});
});