From d5bc167b58c704287535f3028abe05a1740e25b6 Mon Sep 17 00:00:00 2001 From: keeramis Date: Thu, 15 Aug 2024 16:04:11 -0700 Subject: [PATCH 1/2] Add a -d option to select device in device-protection module --- src/cli/device-protection.js | 25 ++++++++++++++++++++----- src/cmd/device-protection.js | 9 ++++++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/cli/device-protection.js b/src/cli/device-protection.js index 1a1b93c6d..1f6d28f7c 100644 --- a/src/cli/device-protection.js +++ b/src/cli/device-protection.js @@ -2,9 +2,15 @@ module.exports = ({ commandProcessor, root }) => { const deviceProtection = commandProcessor.createCategory(root, 'device-protection', 'Manage Device Protection'); commandProcessor.createCommand(deviceProtection, 'status', 'Gets the current Device Protection status', { - handler: () => { + options: { + device: { + description: 'Device ID or name', + alias: 'd' + } + }, + handler: (args) => { const DeviceProtectionCommands = require('../cmd/device-protection'); - return new DeviceProtectionCommands().getStatus(); + return new DeviceProtectionCommands().getStatus(args); }, examples: { '$0 $command': 'Gets the current Device Protection status' @@ -12,10 +18,15 @@ module.exports = ({ commandProcessor, root }) => { }); commandProcessor.createCommand(deviceProtection, 'disable', 'Disables Device Protection', { - - handler: () => { + options: { + d: { + description: 'Device ID or name', + alias: 'device' + } + }, + handler: (args) => { const DeviceProtectionCommands = require('../cmd/device-protection'); - return new DeviceProtectionCommands().disableProtection(); + return new DeviceProtectionCommands().disableProtection(args); }, examples: { '$0 $command': 'Puts a Protected Device to Service Mode', @@ -27,6 +38,10 @@ module.exports = ({ commandProcessor, root }) => { options: { file: { description: 'File to use for Device Protection' + }, + d: { + description: 'Device ID or name', + alias: 'device' } }, handler: (args) => { diff --git a/src/cmd/device-protection.js b/src/cmd/device-protection.js index de57b461c..0e4528d2a 100644 --- a/src/cmd/device-protection.js +++ b/src/cmd/device-protection.js @@ -39,7 +39,8 @@ module.exports = class DeviceProtectionCommands extends CLICommandBase { * @returns {Promise} The protection state of the device. * @throws {Error} Throws an error if any of the async operations fail. */ - async getStatus() { + async getStatus({ device } = {}) { + this.deviceId = device; let addToOutput = []; let s; try { @@ -87,7 +88,8 @@ module.exports = class DeviceProtectionCommands extends CLICommandBase { * @returns {Promise} * @throws {Error} - Throws an error if any of the async operations fail. */ - async disableProtection() { + async disableProtection({ device } = {}) { + this.deviceId = device; let addToOutput = []; try { await this._withDevice({ spinner: 'Disabling Device Protection' }, async () => { @@ -132,7 +134,8 @@ module.exports = class DeviceProtectionCommands extends CLICommandBase { * @returns {Promise} * @throws {Error} Throws an error if any of the asynchronous operations fail. */ - async enableProtection({ file } = {}) { + async enableProtection({ file, device } = {}) { + this.deviceId = device; let addToOutput = []; try { await this._withDevice({ spinner: 'Enabling Device Protection' }, async () => { From ee13660b3adefd78b9792aaef5e49b6dcbe09a3d Mon Sep 17 00:00:00 2001 From: keeramis Date: Sun, 18 Aug 2024 23:16:44 -0700 Subject: [PATCH 2/2] [test] fix unit tests --- src/cli/device-protection.test.js | 153 ++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/cli/device-protection.test.js diff --git a/src/cli/device-protection.test.js b/src/cli/device-protection.test.js new file mode 100644 index 000000000..00b16df1e --- /dev/null +++ b/src/cli/device-protection.test.js @@ -0,0 +1,153 @@ +const { expect } = require('../../test/setup'); +const commandProcessor = require('../app/command-processor'); +const deviceProtection = require('./device-protection'); + +describe('Device Protection Command-Line Interface', () => { + let root; + + beforeEach(() => { + root = commandProcessor.createAppCategory(); + deviceProtection({ root, commandProcessor }); + }); + + describe('`Device Protection` Namespace', () => { + it('Handles `device-protection` command', () => { + const argv = commandProcessor.parse(root, ['device-protection']); + expect(argv.clierror).to.equal(undefined); + expect(argv.params).to.equal(undefined); + }); + + it('Includes help', () => { + const termWidth = null; // don't right-align option type labels so testing is easier + commandProcessor.parse(root, ['device-protection', '--help'], termWidth); + commandProcessor.showHelp((helpText) => { + expect(helpText).to.equal([ + 'Manage Device Protection', + 'Usage: particle device-protection ', + 'Help: particle help device-protection ', + '', + 'Commands:', + ' status Gets the current Device Protection status', + ' disable Disables Device Protection', + ' enable Enables Device Protection', + '' + ].join('\n')); + }); + }); + + describe('`device-protection status` command', () => { + it('Handles `status` command', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'status']); + expect(argv.clierror).to.equal(undefined); + expect(argv.params).to.eql({}); + }); + + it('Handles `status` command with a device', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'status', '--device', '0123456789abcdef']); + expect(argv.clierror).to.equal(undefined); + expect(argv.device).to.eql('0123456789abcdef'); + }); + + it('Includes help', () => { + const termWidth = null; // don't right-align option type labels so testing is easier + commandProcessor.parse(root, ['device-protection', 'status', '--help'], termWidth); + commandProcessor.showHelp((helpText) => { + expect(helpText).to.equal([ + 'Gets the current Device Protection status', + 'Usage: particle device-protection status [options]', + '', + 'Options:', + ' --device, -d Device ID or name [string]', + '', + 'Examples:', + ' particle device-protection status Gets the current Device Protection status', + '' + ].join('\n')); + }); + }); + }); + + describe('`device-protection disable` command', () => { + it('Handles `disable` command', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'disable']); + expect(argv.clierror).to.equal(undefined); + expect(argv.device).to.eql(undefined); + }); + + it('Handles `disable` command with a device', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'disable', '-d', '0123456789abcdef']); + expect(argv.clierror).to.equal(undefined); + expect(argv.device).to.eql('0123456789abcdef'); + }); + + it('Includes help', () => { + const termWidth = null; // don't right-align option type labels so testing is easier + commandProcessor.parse(root, ['device-protection', 'disable', '--help'], termWidth); + commandProcessor.showHelp((helpText) => { + expect(helpText).to.equal([ + 'Disables Device Protection', + 'Usage: particle device-protection disable [options]', + '', + 'Options:', + ' -d, --device Device ID or name [string]', + '', + 'Examples:', + ' particle device-protection disable Puts a Protected Device to Service Mode', + '', + 'A Protected Device in Service Mode allows any command to be performed on it that can be performed on an Open Device like flashing firmware or serial monitor.', + '' + ].join('\n')); + }); + }); + }); + + describe('`device-protection enable` command', () => { + it('Handles `enable` command', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'enable']); + expect(argv.clierror).to.equal(undefined); + expect(argv.device).to.eql(undefined); + }); + + it('Handles `enable` command with a device', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'enable', '-d', '0123456789abcdef']); + expect(argv.clierror).to.equal(undefined); + expect(argv.device).to.eql('0123456789abcdef'); + expect(argv.file).to.eql(undefined); + }); + + it('Handles `enable` command with a filename', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'enable', '--file', 'file.txt']); + expect(argv.clierror).to.equal(undefined); + expect(argv.device).to.eql(undefined); + expect(argv.file).to.eql('file.txt'); + }); + + it('Handles `enable` command with a device and a filename', () => { + const argv = commandProcessor.parse(root, ['device-protection', 'enable', '-d', '0123456789abcdef', '--file', 'file.txt']); + expect(argv.clierror).to.equal(undefined); + expect(argv.device).to.eql('0123456789abcdef'); + expect(argv.file).to.eql('file.txt'); + }); + + it('Includes help', () => { + const termWidth = null; // don't right-align option type labels so testing is easier + commandProcessor.parse(root, ['device-protection', 'enable', '--help'], termWidth); + commandProcessor.showHelp((helpText) => { + expect(helpText).to.equal([ + 'Enables Device Protection', + 'Usage: particle device-protection enable [options]', + '', + 'Options:', + ' --file File to use for Device Protection [string]', + ' -d, --device Device ID or name [string]', + '', + 'Examples:', + ' particle device-protection enable Turns an Open Device into a Protected Device', + '' + ].join('\n')); + }); + }); + }); + }); +}); +