refactor: address file-extensions review comments (#1347)

See: https://github.com/resin-io/etcher/pull/1343#pullrequestreview-34288142
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
This commit is contained in:
Juan Cruz Viotti 2017-04-26 23:53:03 -04:00 committed by GitHub
parent 59edd881e2
commit c9e410fcb1
4 changed files with 110 additions and 24 deletions

View File

@ -22,6 +22,7 @@ const redux = require('redux');
const persistState = require('redux-localstorage');
const uuidV4 = require('uuid/v4');
const constraints = require('../../shared/drive-constraints');
const supportedFormats = require('../../shared/supported-formats');
const errors = require('../../shared/errors');
const release = require('../../shared/release');
const fileExtensions = require('../../shared/file-extensions');
@ -341,24 +342,38 @@ const storeReducer = (state = DEFAULT_STATE, action) => {
});
}
if (!_.isString(action.data.extension)) {
if (_.some([
!_.isString(action.data.extension),
!_.includes(supportedFormats.getAllExtensions(), action.data.extension)
])) {
throw errors.createError({
title: `Invalid image extension: ${action.data.extension}`
});
}
if (fileExtensions.getLastFileExtension(action.data.path) !== action.data.extension) {
const lastImageExtension = fileExtensions.getLastFileExtension(action.data.path);
if (lastImageExtension !== action.data.extension) {
if (!action.data.archiveExtension) {
throw errors.createError({
title: 'Missing image archive extension'
});
}
if (!_.isString(action.data.archiveExtension)) {
if (_.some([
!_.isString(action.data.archiveExtension),
!_.includes(supportedFormats.getAllExtensions(), action.data.archiveExtension)
])) {
throw errors.createError({
title: `Invalid image archive extension: ${action.data.archiveExtension}`
});
}
if (lastImageExtension !== action.data.archiveExtension) {
throw errors.createError({
title: `Image archive extension mismatch: ${action.data.archiveExtension} and ${lastImageExtension}`
});
}
}
if (!action.data.size) {

View File

@ -31,13 +31,13 @@ const _ = require('lodash');
* console.log(extensions);
* > [ 'img', 'gz' ]
*/
exports.getFileExtensions = (filePath) => {
exports.getFileExtensions = _.memoize((filePath) => {
return _.chain(filePath)
.split('.')
.tail()
.map(_.toLower)
.value();
};
});
/**
* @summary Get the last file extension
@ -65,7 +65,7 @@ exports.getLastFileExtension = (filePath) => {
* @returns {(String|Undefined)} penultimate extension
*
* @example
* const extension = fileExtensions.getLastFileExtension('path/to/foo.img.gz');
* const extension = fileExtensions.getPenultimateFileExtension('path/to/foo.img.gz');
* console.log(extension);
* > [ 'img' ]
*/

View File

@ -512,6 +512,73 @@ describe('Browser: SelectionState', function() {
}).to.throw('Invalid image archive extension: 1');
});
it('should throw if the archive extension doesn\'t match the last path extension in a compressed image', function() {
m.chai.expect(function() {
SelectionStateModel.setImage({
path: 'foo.img.xz',
extension: 'img',
archiveExtension: 'gz',
size: {
original: 999999999,
final: {
estimation: false,
value: 999999999
}
}
});
}).to.throw('Image archive extension mismatch: gz and xz');
});
it('should throw if the extension is not recognised in an uncompressed image', function() {
m.chai.expect(function() {
SelectionStateModel.setImage({
path: 'foo.ifg',
extension: 'ifg',
size: {
original: 999999999,
final: {
estimation: false,
value: 999999999
}
}
});
}).to.throw('Invalid image extension: ifg');
});
it('should throw if the extension is not recognised in a compressed image', function() {
m.chai.expect(function() {
SelectionStateModel.setImage({
path: 'foo.ifg.gz',
extension: 'ifg',
archiveExtension: 'gz',
size: {
original: 999999999,
final: {
estimation: false,
value: 999999999
}
}
});
}).to.throw('Invalid image extension: ifg');
});
it('should throw if the archive extension is not recognised', function() {
m.chai.expect(function() {
SelectionStateModel.setImage({
path: 'foo.img.ifg',
extension: 'img',
archiveExtension: 'ifg',
size: {
original: 999999999,
final: {
estimation: false,
value: 999999999
}
}
});
}).to.throw('Invalid image archive extension: ifg');
});
it('should throw if no size', function() {
m.chai.expect(function() {
SelectionStateModel.setImage({

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016 resin.io
* 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.
@ -29,62 +29,66 @@ describe('Shared: fileExtensions', function() {
// No extension
{
file: 'path/to/filename',
extension: []
extensions: []
},
// Type: 'archive'
{
file: 'path/to/filename.zip',
extension: [ 'zip' ]
extensions: [ 'zip' ]
},
{
file: 'path/to/filename.etch',
extension: [ 'etch' ]
extensions: [ 'etch' ]
},
// Type: 'compressed'
{
file: 'path/to/filename.img.gz',
extension: [ 'img', 'gz' ]
extensions: [ 'img', 'gz' ]
},
{
file: 'path/to/filename.img.bz2',
extension: [ 'img', 'bz2' ]
extensions: [ 'img', 'bz2' ]
},
{
file: 'path/to/filename.img.xz',
extension: [ 'img', 'xz' ]
extensions: [ 'img', 'xz' ]
},
{
file: 'path/to/filename.img.xz.gz',
extensions: [ 'img', 'xz', 'gz' ]
},
// Type: 'image'
{
file: 'path/to/filename.img',
extension: [ 'img' ]
extensions: [ 'img' ]
},
{
file: 'path/to/filename.iso',
extension: [ 'iso' ]
extensions: [ 'iso' ]
},
{
file: 'path/to/filename.dsk',
extension: [ 'dsk' ]
extensions: [ 'dsk' ]
},
{
file: 'path/to/filename.hddimg',
extension: [ 'hddimg' ]
extensions: [ 'hddimg' ]
},
{
file: 'path/to/filename.raw',
extension: [ 'raw' ]
extensions: [ 'raw' ]
},
{
file: 'path/to/filename.dmg',
extension: [ 'dmg' ]
extensions: [ 'dmg' ]
}
], (testCase) => {
it(`should return ${testCase.extension} for ${testCase.file}`, function() {
m.chai.expect(fileExtensions.getFileExtensions(testCase.file)).to.deep.equal(testCase.extension);
it(`should return ${testCase.extensions} for ${testCase.file}`, function() {
m.chai.expect(fileExtensions.getFileExtensions(testCase.file)).to.deep.equal(testCase.extensions);
});
});
@ -100,7 +104,7 @@ describe('Shared: fileExtensions', function() {
describe('.getLastFileExtension()', function() {
it('should return undefined in the file path has no extension', function() {
it('should return undefined if the file path has no extension', function() {
m.chai.expect(fileExtensions.getLastFileExtension('foo')).to.be.undefined;
});
@ -108,7 +112,7 @@ describe('Shared: fileExtensions', function() {
m.chai.expect(fileExtensions.getLastFileExtension('foo.img')).to.equal('img');
});
it('should return the last extension if there two extensions', function() {
it('should return the last extension if there are two extensions', function() {
m.chai.expect(fileExtensions.getLastFileExtension('foo.img.gz')).to.equal('gz');
});
@ -128,7 +132,7 @@ describe('Shared: fileExtensions', function() {
m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.img')).to.be.undefined;
});
it('should return the first extension if there are two extensions', function() {
it('should return the penultimate extension if there are two extensions', function() {
m.chai.expect(fileExtensions.getPenultimateFileExtension('foo.img.gz')).to.equal('img');
});