refactor: reset state when the flashing flag is set to false (#518)

Currently, we were taking care of resetting the flashing state manually
across several controllers. Now that data mutations live in a single
place, we trigger a flash state reset whenever the flashing flag is set
to false, which reliably handles every case and allows us to forget
about it.

Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
Juan Cruz Viotti 2016-06-23 15:12:57 -04:00 committed by GitHub
parent c845fe10b0
commit 2ecf9d32a7
6 changed files with 77 additions and 26 deletions

View File

@ -147,8 +147,6 @@ app.controller('AppController', function(
preserveImage: true
});
this.writer.resetState();
}
NotifierService.subscribe($scope, 'image-writer:state', function(state) {
@ -233,7 +231,6 @@ app.controller('AppController', function(
preserveImage: true
});
self.writer.resetState();
self.success = true;
AnalyticsService.logEvent('Restart after failure');
};
@ -256,7 +253,6 @@ app.controller('AppController', function(
return self.writer.flash(image, drive).then(function(results) {
if (results.cancelled) {
self.writer.resetState();
return;
}
@ -283,7 +279,6 @@ app.controller('AppController', function(
AnalyticsService.logEvent('Flash error');
}
self.writer.resetState();
self.handleError(error);
})
.finally(OSWindowProgressService.clear);

View File

@ -94,7 +94,16 @@ const store = function(state, action) {
}
case 'SET_FLASHING': {
return state.setIn([ 'flash', 'flashing' ], Boolean(action.data));
const value = Boolean(action.data);
const newState = state.setIn([ 'flash', 'flashing' ], value);
if (!value) {
return store(newState, {
type: 'RESET_FLASH_STATE'
});
}
return newState;
}
case 'SELECT_DRIVE': {

View File

@ -102,6 +102,40 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
});
};
/**
* @summary Set the flashing state
* @function
* @private
*
* @description
* This function is extracted for testing purposes.
*
* @param {Object} state - flashing state
*
* @example
* ImageWriterService.setProgressState({
* type: 'write',
* percentage: 50,
* eta: 15,
* speed: 100000000000
* });
*/
this.setProgressState = function(state) {
store.dispatch({
type: 'SET_FLASH_STATE',
data: {
type: state.type,
progress: state.percentage,
eta: state.eta,
// Transform bytes to megabytes preserving only two decimal places
speed: Math.floor(state.speed / 1e+6 * 100) / 100 || 0
}
});
NotifierService.emit('image-writer:state', self.state);
};
/**
* @summary Perform write operation
* @function
@ -161,23 +195,7 @@ imageWriter.service('ImageWriterService', function($q, $timeout, SettingsModel,
self.setFlashing(true);
return self.performWrite(image, drive, function(state) {
store.dispatch({
type: 'SET_FLASH_STATE',
data: {
type: state.type,
progress: state.percentage,
eta: state.eta,
// Transform bytes to megabytes preserving only two decimal places
speed: Math.floor(state.speed / 1e+6 * 100) / 100 || 0
}
});
NotifierService.emit('image-writer:state', self.state);
}).finally(function() {
return self.performWrite(image, drive, self.setProgressState).finally(function() {
self.setFlashing(false);
});
};

View File

@ -16,7 +16,7 @@
'use strict';
module.exports = function($state, $stateParams, SelectionStateModel, ImageWriterService, AnalyticsService, SettingsModel) {
module.exports = function($state, $stateParams, SelectionStateModel, AnalyticsService, SettingsModel) {
/**
* @summary Settings data
@ -45,7 +45,6 @@ module.exports = function($state, $stateParams, SelectionStateModel, ImageWriter
*/
this.restart = function(options) {
SelectionStateModel.clear(options);
ImageWriterService.resetState();
AnalyticsService.logEvent('Restart', options);
$state.go('main');
};

View File

@ -30,7 +30,6 @@ const angular = require('angular');
const MODULE_NAME = 'Etcher.Pages.Finish';
const FinishPage = angular.module(MODULE_NAME, [
require('angular-ui-router'),
require('../../modules/image-writer'),
require('../../modules/analytics'),
require('../../models/selection-state'),
require('../../models/settings')

View File

@ -87,6 +87,33 @@ describe('Browser: ImageWriter', function() {
m.chai.expect(ImageWriterService.isFlashing()).to.be.false;
});
it('should reset the flashing state if set to false', function() {
ImageWriterService.setFlashing(true);
ImageWriterService.setProgressState({
type: 'write',
percentage: 50,
eta: 15,
speed: 100000000000
});
$timeout.flush();
m.chai.expect(ImageWriterService.state).to.not.deep.equal({
progress: 0,
speed: 0
});
ImageWriterService.setFlashing(false);
$timeout.flush();
m.chai.expect(ImageWriterService.state).to.deep.equal({
progress: 0,
speed: 0
});
});
});
describe('.flash()', function() {
@ -103,12 +130,14 @@ describe('Browser: ImageWriter', function() {
});
it('should set flashing to false when done', function() {
ImageWriterService.setFlashing(false);
ImageWriterService.flash('foo.img', '/dev/disk2');
$rootScope.$apply();
m.chai.expect(ImageWriterService.isFlashing()).to.be.false;
});
it('should prevent writing more than once', function() {
ImageWriterService.setFlashing(false);
ImageWriterService.flash('foo.img', '/dev/disk2');
ImageWriterService.flash('foo.img', '/dev/disk2');
$rootScope.$apply();
@ -149,6 +178,8 @@ describe('Browser: ImageWriter', function() {
});
it('should be rejected with the error', function() {
ImageWriterService.setFlashing(false);
let rejection;
ImageWriterService.flash('foo.img', '/dev/disk2').catch(function(error) {
rejection = error;