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 Feb 16, 2018
1 parent 4fa0f99 commit 73c7b62
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 76 deletions.
71 changes: 9 additions & 62 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 @@ -276,63 +278,6 @@ exports.isDriveSizeRecommended = (drive, image) => {
return _.get(drive, [ 'size' ], UNKNOWN_SIZE) >= _.get(image, [ 'recommendedDriveSize' ], UNKNOWN_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'
}

/**
* @summary Drive/image compatibility status types.
* @public
Expand Down Expand Up @@ -396,30 +341,32 @@ 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 (!_.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
30 changes: 30 additions & 0 deletions lib/shared/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,36 @@ 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'
}

},

/**
Expand Down
39 changes: 25 additions & 14 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 @@ -987,7 +988,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 @@ -1018,7 +1019,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 @@ -1029,7 +1030,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 @@ -1040,9 +1041,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 @@ -1063,7 +1069,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 @@ -1074,7 +1080,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 @@ -1101,7 +1107,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 @@ -1112,7 +1118,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 @@ -1124,7 +1130,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 @@ -1135,7 +1141,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 @@ -1147,9 +1153,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 @@ -1159,7 +1170,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 73c7b62

Please sign in to comment.