Detect removal of selected drive (#264)

Suppose you plug a device, select it in Etcher, but then eject it from
your computer. Etcher will keep the selection thinking the drive is
still there.

With this PR, the selected drive, if any, is ensured its still inside
the array of available drives, otherwise the selected is cleared.

Fixes: https://github.com/resin-io/etcher/issues/254
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This commit is contained in:
Juan Cruz Viotti 2016-04-08 12:17:36 -04:00
parent 3a04b5ccaa
commit 67daf086a2
3 changed files with 114 additions and 0 deletions

View File

@ -124,6 +124,11 @@ app.controller('AppController', function(
this.scanner.start(2000).on('error', dialog.showError).on('scan', function(drives) {
// Cover the case where you select a drive, but then eject it.
if (self.selection.hasDrive() && !_.find(drives, self.selection.isCurrentDrive)) {
self.selection.removeDrive();
}
// Notice we only autoselect the drive if there is an image,
// which means that the first step was completed successfully,
// otherwise the drive is selected while the drive step is disabled

View File

@ -166,4 +166,28 @@ SelectionStateModel.service('SelectionStateModel', function() {
}
};
/**
* @summary Check if a drive is the current drive
* @function
* @public
*
* @param {Object} drive - drive
* @returns {Boolean} whether the drive is the current drive
*
* @example
* if (SelectionStateModel.isCurrentDrive({
* device: '/dev/sdb',
* description: 'DataTraveler 2.0',
* size: '7.3G',
* mountpoint: '/media/UNTITLED',
* name: '/dev/sdb',
* system: false
* })) {
* console.log('This is the current drive!');
* }
*/
this.isCurrentDrive = function(drive) {
return angular.equals(self.getDrive(), drive);
};
});

View File

@ -218,6 +218,91 @@ describe('Browser: SelectionState', function() {
});
describe('.isCurrentDrive()', function() {
describe('given a selected drive', function() {
beforeEach(function() {
SelectionStateModel.setDrive({
device: '/dev/sdb',
description: 'DataTraveler 2.0',
size: '7.3G',
mountpoint: '/media/UNTITLED',
name: '/dev/sdb',
system: false
});
});
it('should return true given the exact same drive', function() {
m.chai.expect(SelectionStateModel.isCurrentDrive({
device: '/dev/sdb',
description: 'DataTraveler 2.0',
size: '7.3G',
mountpoint: '/media/UNTITLED',
name: '/dev/sdb',
system: false
})).to.be.true;
});
it('should return true given the exact same drive with a $$hashKey', function() {
m.chai.expect(SelectionStateModel.isCurrentDrive({
device: '/dev/sdb',
description: 'DataTraveler 2.0',
size: '7.3G',
mountpoint: '/media/UNTITLED',
name: '/dev/sdb',
system: false,
$$hashKey: 1234
})).to.be.true;
});
it('should return false if the device changes', function() {
m.chai.expect(SelectionStateModel.isCurrentDrive({
device: '/dev/sdc',
description: 'DataTraveler 2.0',
size: '7.3G',
mountpoint: '/media/UNTITLED',
name: '/dev/sdb',
system: false
})).to.be.false;
});
it('should return false if the description changes', function() {
m.chai.expect(SelectionStateModel.isCurrentDrive({
device: '/dev/sdb',
description: 'DataTraveler 3.0',
size: '7.3G',
mountpoint: '/media/UNTITLED',
name: '/dev/sdb',
system: false
})).to.be.false;
});
});
describe('given no selected drive', function() {
beforeEach(function() {
SelectionStateModel.removeDrive();
});
it('should return false for anything', function() {
m.chai.expect(SelectionStateModel.isCurrentDrive({
device: '/dev/sdb',
description: 'DataTraveler 2.0',
size: '7.3G',
mountpoint: '/media/UNTITLED',
name: '/dev/sdb',
system: false
})).to.be.false;
});
});
});
});
});