-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: convert installedapps:delete command to yargs
- Loading branch information
Showing
7 changed files
with
150 additions
and
101 deletions.
There are no files selected for viewing
41 changes: 0 additions & 41 deletions
41
packages/cli/src/__tests__/commands/installedapps/delete.test.ts
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { jest } from '@jest/globals' | ||
|
||
import type { ArgumentsCamelCase, Argv } from 'yargs' | ||
|
||
import { InstalledApp, type InstalledAppsEndpoint, type SmartThingsClient } from '@smartthings/core-sdk' | ||
|
||
import type { CommandArgs } from '../../../commands/installedapps/delete.js' | ||
import type { chooseInstalledAppFn } from '../../../lib/command/util/installedapps-util.js' | ||
import type { ChooseFunction } from '../../../lib/command/util/util-util.js' | ||
import { apiCommandMocks } from '../../test-lib/api-command-mock.js' | ||
import { buildArgvMock } from '../../test-lib/builder-mock.js' | ||
import { APICommand } from '../../../lib/command/api-command.js' | ||
|
||
|
||
const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../..') | ||
|
||
const chooseInstalledAppMock = jest.fn<ChooseFunction<InstalledApp>>() | ||
const chooseInstalledAppFnMock = jest.fn<typeof chooseInstalledAppFn>() | ||
.mockReturnValue(chooseInstalledAppMock) | ||
jest.unstable_mockModule('../../../lib/command/util/installedapps-util.js', () => ({ | ||
chooseInstalledAppFn: chooseInstalledAppFnMock, | ||
})) | ||
|
||
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => { /*no-op*/ }) | ||
|
||
|
||
const { default: cmd } = await import('../../../commands/installedapps/delete.js') | ||
|
||
|
||
test('builder', () => { | ||
const { | ||
yargsMock, | ||
positionalMock, | ||
exampleMock, | ||
epilogMock, | ||
argvMock, | ||
} = buildArgvMock<object, CommandArgs>() | ||
|
||
apiCommandBuilderMock.mockReturnValue(argvMock) | ||
|
||
const builder = cmd.builder as (yargs: Argv<object>) => Argv<CommandArgs> | ||
expect(builder(yargsMock)).toBe(argvMock) | ||
|
||
expect(apiCommandBuilderMock).toHaveBeenCalledTimes(1) | ||
expect(apiCommandBuilderMock).toHaveBeenCalledWith(yargsMock) | ||
|
||
expect(positionalMock).toHaveBeenCalledTimes(1) | ||
expect(exampleMock).toHaveBeenCalledTimes(1) | ||
expect(apiDocsURLMock).toHaveBeenCalledTimes(1) | ||
expect(epilogMock).toHaveBeenCalledTimes(1) | ||
}) | ||
|
||
test('handler', async () => { | ||
const apiInstalledAppsDeleteMock = jest.fn<typeof InstalledAppsEndpoint.prototype.delete>() | ||
chooseInstalledAppMock.mockResolvedValueOnce('chosen-installed-app-id') | ||
const clientMock = { | ||
installedApps: { | ||
delete: apiInstalledAppsDeleteMock, | ||
}, | ||
} as unknown as SmartThingsClient | ||
const command = { | ||
client: clientMock, | ||
} as APICommand<CommandArgs> | ||
apiCommandMock.mockResolvedValue(command) | ||
const inputArgv = { | ||
profile: 'default', | ||
id: 'command-line-id', | ||
verbose: true, | ||
location: ['location-id-1'], | ||
} as ArgumentsCamelCase<CommandArgs> | ||
|
||
await expect(cmd.handler(inputArgv)).resolves.not.toThrow() | ||
|
||
expect(apiCommandMock).toHaveBeenCalledExactlyOnceWith(inputArgv) | ||
expect(chooseInstalledAppFnMock).toHaveBeenCalledExactlyOnceWith({ | ||
listOptions: { | ||
locationId: ['location-id-1'], | ||
}, | ||
verbose: true, | ||
}) | ||
expect(chooseInstalledAppMock).toHaveBeenCalledExactlyOnceWith( | ||
command, | ||
'command-line-id', | ||
{ promptMessage: 'Select an installed app to delete.' }, | ||
) | ||
expect(apiInstalledAppsDeleteMock).toHaveBeenCalledExactlyOnceWith('chosen-installed-app-id') | ||
|
||
expect(consoleLogSpy).toHaveBeenLastCalledWith('Installed app chosen-installed-app-id deleted.') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { type ArgumentsCamelCase, type Argv, type CommandModule } from 'yargs' | ||
|
||
import { type InstalledAppListOptions } from '@smartthings/core-sdk' | ||
|
||
import { apiCommand, apiCommandBuilder, type APICommandFlags, apiDocsURL } from '../../lib/command/api-command.js' | ||
import { chooseInstalledAppFn } from '../../lib/command/util/installedapps-util.js' | ||
|
||
|
||
export type CommandArgs = | ||
& APICommandFlags | ||
& { | ||
location?: string[] | ||
verbose: boolean | ||
id?: string | ||
} | ||
|
||
const command = 'installedapps:delete [id]' | ||
|
||
const describe = 'delete an installed app' | ||
|
||
const builder = (yargs: Argv): Argv<CommandArgs> => | ||
apiCommandBuilder(yargs) | ||
.option('location', { | ||
alias: 'l', | ||
describe: 'if prompting for an installed app, include only installed apps in the specified location(s)', | ||
type: 'string', | ||
array: true, | ||
}) | ||
.option('verbose', | ||
{ alias: 'v', describe: 'include location name in output', type: 'boolean', default: false }) | ||
.positional('id', { describe: 'installed app id', type: 'string' }) | ||
.example([ | ||
['$0 installedapps:delete', 'choose the installed app to delete from a list'], | ||
[ | ||
'$0 installedapps:delete 5dfd6626-ab1d-42da-bb76-90def3153998', | ||
'delete the installed app with the specified id', | ||
], | ||
]) | ||
.epilog(apiDocsURL('deleteInstallation')) | ||
|
||
|
||
const handler = async (argv: ArgumentsCamelCase<CommandArgs>): Promise<void> => { | ||
const command = await apiCommand(argv) | ||
|
||
const listOptions: InstalledAppListOptions = { | ||
locationId: argv.location, | ||
} | ||
const chooseFunction = chooseInstalledAppFn({ listOptions, verbose: argv.verbose }) | ||
const id = await chooseFunction(command, argv.id, { promptMessage: 'Select an installed app to delete.' }) | ||
|
||
await command.client.installedApps.delete(id) | ||
console.log(`Installed app ${id} deleted.`) | ||
} | ||
|
||
const cmd: CommandModule<object, CommandArgs> = { command, describe, builder, handler } | ||
export default cmd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters