Skip to content

Commit

Permalink
feat(gui): Display image size when drive too small
Browse files Browse the repository at this point in the history
This adds a display of the determined image size to the
drive label when the drive has been determined to be too small.

Change-Type: patch
Changelog-Entry: Display image size for comparison if drive is too small
  • Loading branch information
jhermsmeier committed Mar 21, 2018
1 parent e01aec7 commit 4108979
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 87 deletions.
82 changes: 10 additions & 72 deletions lib/shared/drive-constraints.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

const _ = require('lodash')
const pathIsInside = require('path-is-inside')
const prettyBytes = require('pretty-bytes')
const messages = require('./messages')

/**
* @summary The default unknown size for things such as images and drives
Expand Down Expand Up @@ -299,72 +301,6 @@ exports.isDriveSizeLarge = (drive) => {
return _.get(drive, [ 'size' ], UNKNOWN_SIZE) > exports.LARGE_DRIVE_SIZE
}

/**
* @summary Drive/image compatibility status messages.
* @public
* @type {Object}
*
* @description
* Status messages intended to be shown to the user.
*/
exports.COMPATIBILITY_STATUS_MESSAGES = {

/**
* @property {String} SIZE_NOT_RECOMMENDED
* @memberof COMPATIBILITY_STATUS_MESSAGES
*
* @description
* The image and drive compatibility is not recommended; happens when the
* actual drive size is smaller than the image's recommended drive size.
*/
SIZE_NOT_RECOMMENDED: 'Not Recommended',

/**
* @property {String} TOO_SMALL
* @memberof COMPATIBILITY_STATUS_MESSAGES
*
* @description
* The drive is too small for the image.
*/
TOO_SMALL: 'Too Small For Image',

/**
* @property {String} LOCKED
* @memberof COMPATIBILITY_STATUS_MESSAGES
*
* @description
* The drive is locked (e.g. the lock-tab on SD cards) and cannot be written to.
*/
LOCKED: 'Locked',

/**
* @property {String} SYSTEM
* @memberof COMPATIBILITY_STATUS_MESSAGES
*
* @description
* The drive is a system drive and should not be written to.
*/
SYSTEM: 'System Drive',

/**
* @property {String} CONTAINS_IMAGE
* @memberof COMPATIBILITY_STATUS_MESSAGES
*
* @description
* The drive contains the image and therefore cannot be written to.
*/
CONTAINS_IMAGE: 'Drive Contains Image',

/**
* @property {String} LARGE_DRIVE
* @memberof COMPATIBILITY_STATUS_MESSAGES
*
* @description
* The drive is large and therefore likely not a medium you want to write to.
*/
LARGE_DRIVE: 'Large Drive'
}

/**
* @summary Drive/image compatibility status types.
* @public
Expand Down Expand Up @@ -428,37 +364,39 @@ exports.getDriveImageCompatibilityStatuses = (drive, image) => {
if (exports.isSourceDrive(drive, image)) {
statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.ERROR,
message: exports.COMPATIBILITY_STATUS_MESSAGES.CONTAINS_IMAGE
message: messages.compatibility.containsImage()
})
} else if (exports.isDriveLocked(drive)) {
statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.ERROR,
message: exports.COMPATIBILITY_STATUS_MESSAGES.LOCKED
message: messages.compatibility.locked()
})
} else if (!_.isNil(drive) && !_.isNil(drive.size) && !exports.isDriveLargeEnough(drive, image)) {
const imageSize = _.get(image, [ 'size', 'final', 'estimation' ]) ? image.size.original : image.size.final.value
const relativeBytes = imageSize - drive.size
statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.ERROR,
message: exports.COMPATIBILITY_STATUS_MESSAGES.TOO_SMALL
message: messages.compatibility.tooSmall(prettyBytes(relativeBytes))
})
} else {
if (exports.isSystemDrive(drive)) {
statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.WARNING,
message: exports.COMPATIBILITY_STATUS_MESSAGES.SYSTEM
message: messages.compatibility.system()
})
}

if (exports.isDriveSizeLarge(drive)) {
statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.WARNING,
message: exports.COMPATIBILITY_STATUS_MESSAGES.LARGE_DRIVE
message: messages.compatibility.largeDrive()
})
}

if (!_.isNil(drive) && !exports.isDriveSizeRecommended(drive, image)) {
statusList.push({
type: exports.COMPATIBILITY_STATUS_TYPES.WARNING,
message: exports.COMPATIBILITY_STATUS_MESSAGES.SIZE_NOT_RECOMMENDED
message: messages.compatibility.sizeNotRecommended()
})
}
}
Expand Down
35 changes: 35 additions & 0 deletions lib/shared/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,41 @@ module.exports = {
`${drive.description} (${drive.displayName})`
].join(' ')
}

},

/**
* @summary Drive compatibility messages
* @namespace compatibility
* @memberof messages
*/
compatibility: {

sizeNotRecommended () {
return 'Not Recommended'
},

tooSmall (additionalSpace) {
return `Insufficient space, additional ${additionalSpace} required`
},

locked () {
return 'Locked'
},

system () {
return 'System Drive'
},

containsImage () {
return 'Drive Contains Image'
},

// The drive is large and therefore likely not a medium you want to write to.
largeDrive () {
return 'Large Drive'
}

},

/**
Expand Down
41 changes: 26 additions & 15 deletions tests/shared/drive-constraints.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const m = require('mochainon')
const _ = require('lodash')
const path = require('path')
const constraints = require('../../lib/shared/drive-constraints')
const messages = require('../../lib/shared/messages')

describe('Shared: DriveConstraints', function () {
describe('.isDriveLocked()', function () {
Expand Down Expand Up @@ -1029,7 +1030,7 @@ describe('Shared: DriveConstraints', function () {
const expectedTuplesSorted = _.sortBy(_.map(expectedTuples, (tuple) => {
return {
type: constraints.COMPATIBILITY_STATUS_TYPES[tuple[0]],
message: constraints.COMPATIBILITY_STATUS_MESSAGES[tuple[1]]
message: messages.compatibility[tuple[1]]()
}
}), [ 'message' ])
const resultTuplesSorted = _.sortBy(resultList, [ 'message' ])
Expand Down Expand Up @@ -1060,7 +1061,7 @@ describe('Shared: DriveConstraints', function () {
this.image.path = path.join(this.mountpoint, 'rpi.img')

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'ERROR', 'CONTAINS_IMAGE' ] ]
const expectedTuples = [ [ 'ERROR', 'containsImage' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1071,7 +1072,7 @@ describe('Shared: DriveConstraints', function () {
this.drive.isSystem = true

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'WARNING', 'SYSTEM' ] ]
const expectedTuples = [ [ 'WARNING', 'system' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1082,9 +1083,14 @@ describe('Shared: DriveConstraints', function () {
this.image.size.final.value = this.drive.size + 1

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'ERROR', 'TOO_SMALL' ] ]
const expected = [
{
message: messages.compatibility.tooSmall('1 B'),
type: constraints.COMPATIBILITY_STATUS_TYPES.ERROR
}
]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
m.chai.expect(result).to.deep.equal(expected)
})
})

Expand All @@ -1105,7 +1111,7 @@ describe('Shared: DriveConstraints', function () {
this.drive.isReadOnly = true

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'ERROR', 'LOCKED' ] ]
const expectedTuples = [ [ 'ERROR', 'locked' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1116,7 +1122,7 @@ describe('Shared: DriveConstraints', function () {
this.image.recommendedDriveSize = this.drive.size + 1

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'WARNING', 'SIZE_NOT_RECOMMENDED' ] ]
const expectedTuples = [ [ 'WARNING', 'sizeNotRecommended' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1127,7 +1133,7 @@ describe('Shared: DriveConstraints', function () {
this.drive.size = constraints.LARGE_DRIVE_SIZE + 1

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'WARNING', 'LARGE_DRIVE' ] ]
const expectedTuples = [ [ 'WARNING', 'largeDrive' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1154,7 +1160,7 @@ describe('Shared: DriveConstraints', function () {
this.drive.isReadOnly = true

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null)
const expectedTuples = [ [ 'ERROR', 'LOCKED' ] ]
const expectedTuples = [ [ 'ERROR', 'locked' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1165,7 +1171,7 @@ describe('Shared: DriveConstraints', function () {
this.drive.isSystem = true

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, null)
const expectedTuples = [ [ 'WARNING', 'SYSTEM' ] ]
const expectedTuples = [ [ 'WARNING', 'system' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1177,7 +1183,7 @@ describe('Shared: DriveConstraints', function () {
this.image.path = path.join(this.mountpoint, 'rpi.img')

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'ERROR', 'CONTAINS_IMAGE' ] ]
const expectedTuples = [ [ 'ERROR', 'containsImage' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1188,7 +1194,7 @@ describe('Shared: DriveConstraints', function () {
this.drive.isReadOnly = true

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'ERROR', 'LOCKED' ] ]
const expectedTuples = [ [ 'ERROR', 'locked' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand All @@ -1200,9 +1206,14 @@ describe('Shared: DriveConstraints', function () {
this.drive.isSystem = true

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'ERROR', 'TOO_SMALL' ] ]
const expected = [
{
message: messages.compatibility.tooSmall('1 B'),
type: constraints.COMPATIBILITY_STATUS_TYPES.ERROR
}
]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
m.chai.expect(result).to.deep.equal(expected)
})
})

Expand All @@ -1212,7 +1223,7 @@ describe('Shared: DriveConstraints', function () {
this.image.recommendedDriveSize = this.drive.size + 1

const result = constraints.getDriveImageCompatibilityStatuses(this.drive, this.image)
const expectedTuples = [ [ 'WARNING', 'SIZE_NOT_RECOMMENDED' ], [ 'WARNING', 'SYSTEM' ] ]
const expectedTuples = [ [ 'WARNING', 'sizeNotRecommended' ], [ 'WARNING', 'system' ] ]

expectStatusTypesAndMessagesToBe(result, expectedTuples)
})
Expand Down

0 comments on commit 4108979

Please sign in to comment.