Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

30 changes: 0 additions & 30 deletions packages/edge/src/__tests__/lib/commands/drivers-util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,33 +195,3 @@ test('chooseDriverFromChannel presents user with list of drivers with names', as
expect(listAssignedDriversWithNamesSpy).toHaveBeenCalledTimes(1)
expect(listAssignedDriversWithNamesSpy).toHaveBeenCalledWith(client, 'channel-id')
})

test('chooseInstalledDriver presents user with list of drivers with names', async () => {
const command = { client } as APICommand<typeof APICommand.flags>
selectFromListMock.mockResolvedValueOnce('chosen-driver-id')
stringTranslateToIdMock.mockResolvedValueOnce('preselected-driver-id')

expect(await driversUtil.chooseInstalledDriver(command, 'hub-id', 'prompt message', 'command-line-driver-id'))
.toBe('chosen-driver-id')

expect(stringTranslateToIdMock).toHaveBeenCalledTimes(1)
expect(stringTranslateToIdMock).toHaveBeenCalledWith(
expect.objectContaining({ primaryKeyName: 'driverId', sortKeyName: 'name' }),
'command-line-driver-id', expect.any(Function))
expect(selectFromListMock).toHaveBeenCalledTimes(1)
expect(selectFromListMock).toHaveBeenCalledWith(command,
expect.objectContaining({ primaryKeyName: 'driverId', sortKeyName: 'name' }),
expect.objectContaining({
preselectedId: 'preselected-driver-id',
promptMessage: 'prompt message',
}))
expect(apiHubdevicesListInstalledMock).toHaveBeenCalledTimes(0)

const listItems = stringTranslateToIdMock.mock.calls[0][2]
apiHubdevicesListInstalledMock.mockResolvedValueOnce([installedDriver])

expect(await listItems()).toStrictEqual([installedDriver])

expect(apiHubdevicesListInstalledMock).toHaveBeenCalledTimes(1)
expect(apiHubdevicesListInstalledMock).toHaveBeenCalledWith('hub-id')
})
33 changes: 0 additions & 33 deletions packages/edge/src/commands/edge/drivers/uninstall.ts

This file was deleted.

12 changes: 0 additions & 12 deletions packages/edge/src/lib/commands/drivers-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,3 @@ export const listAllAvailableDrivers = async (client: SmartThingsClient, deviceI

export const listMatchingDrivers = async (client: SmartThingsClient, deviceId: string, hubId: string): Promise<DriverChoice[]> =>
withoutCurrentDriver(client, deviceId, await client.hubdevices.listInstalled(hubId, deviceId))

export const chooseInstalledDriver = async (command: APICommand<typeof APICommand.flags>, hubId: string, promptMessage: string, commandLineDriverId?: string): Promise<string> => {
const config: SelectFromListConfig<InstalledDriver> = {
itemName: 'driver',
primaryKeyName: 'driverId',
sortKeyName: 'name',
}

const listItems = (): Promise<InstalledDriver[]> => command.client.hubdevices.listInstalled(hubId)
const preselectedId = await stringTranslateToId(config, commandLineDriverId, listItems)
return selectFromList(command, config, { preselectedId, listItems, promptMessage })
}
2 changes: 1 addition & 1 deletion src/__tests__/commands/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ describe('handler', () => {
expect(outputListMock).toHaveBeenCalledTimes(1)
expect(outputListMock).toHaveBeenCalledWith(command,
expect.objectContaining({ primaryKeyName: 'name' }),
expect.any(Function), true)
expect.any(Function), { includeIndex: true })

const outputListConfig = outputListMock.mock.calls[0][1] as TableCommonListOutputProducer<object>
expect(outputListConfig.listTableFieldDefinitions?.length).toBe(2)
Expand Down
111 changes: 111 additions & 0 deletions src/__tests__/commands/edge/drivers/uninstall.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import { jest } from '@jest/globals'

import type { ArgumentsCamelCase, Argv } from 'yargs'

import type{ Device, HubdevicesEndpoint, InstalledDriver } from '@smartthings/core-sdk'

import type { CommandArgs } from '../../../../commands/edge/drivers/uninstall.js'
import type { APICommand, APICommandFlags } from '../../../../lib/command/api-command.js'
import type { chooseDriverFromChannelFn } from '../../../../lib/command/util/drivers-choose.js'
import type { DriverChannelDetailsWithName } from '../../../../lib/command/util/edge-drivers.js'
import type { chooseDriver } from '../../../../lib/command/util/drivers-choose.js'
import type { chooseHubFn } from '../../../../lib/command/util/hubs-choose.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'


const { apiCommandMock, apiCommandBuilderMock, apiDocsURLMock } = apiCommandMocks('../../../..')

const chooseDriverFromChannelMock = jest.fn<ChooseFunction<DriverChannelDetailsWithName>>()
.mockResolvedValue('driver-id-chosen-from-channel')
const chooseDriverFromChannelFnMock = jest.fn<typeof chooseDriverFromChannelFn>()
.mockReturnValue(chooseDriverFromChannelMock)
jest.unstable_mockModule('../../../../lib/command/util/drivers-choose.js', () => ({
chooseDriverFromChannelFn: chooseDriverFromChannelFnMock,
}))

const chooseDriverMock = jest.fn<typeof chooseDriver>().mockResolvedValue('chosen-driver-id')
jest.unstable_mockModule('../../../../lib/command/util/drivers-choose.js', () => ({
chooseDriver: chooseDriverMock,
}))

const chooseHubMock = jest.fn<ChooseFunction<Device>>().mockResolvedValue('chosen-hub-id')
const chooseHubFnMock = jest.fn<typeof chooseHubFn>().mockReturnValue(chooseHubMock)
jest.unstable_mockModule('../../../../lib/command/util/hubs-choose.js', () => ({
chooseHubFn: chooseHubFnMock,
}))

const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => { /* do nothing */ })


const { default: cmd } = await import('../../../../commands/edge/drivers/uninstall.js')


test('builder', () => {
const {
yargsMock,
positionalMock,
optionMock,
exampleMock,
epilogMock,
argvMock,
} = buildArgvMock<APICommandFlags, CommandArgs>()

apiCommandBuilderMock.mockReturnValue(argvMock)

const builder = cmd.builder as (yargs: Argv<object>) => Argv<CommandArgs>
expect(builder(yargsMock)).toBe(argvMock)

expect(apiCommandBuilderMock).toHaveBeenCalledExactlyOnceWith(yargsMock)

expect(positionalMock).toHaveBeenCalledTimes(1)
expect(optionMock).toHaveBeenCalledTimes(1)
expect(exampleMock).toHaveBeenCalledTimes(1)
expect(apiDocsURLMock).toHaveBeenCalledTimes(1)
expect(epilogMock).toHaveBeenCalledTimes(1)
})

test('handler', async () => {
const apiHubDevicesListInstalledMock = jest.fn<typeof HubdevicesEndpoint.prototype.listInstalled>()
const apiHubDevicesUninstallDriverMock = jest.fn<typeof HubdevicesEndpoint.prototype.uninstallDriver>()
const command = {
client: {
hubdevices: {
listInstalled: apiHubDevicesListInstalledMock,
uninstallDriver: apiHubDevicesUninstallDriverMock,
},
},
} as unknown as APICommand
apiCommandMock.mockResolvedValue(command)

const inputArgv = {
profile: 'default',
driverId: 'cmd-line-driver-id',
hub: 'cmd-line-hub-id',
} as ArgumentsCamelCase<CommandArgs>

await expect(cmd.handler(inputArgv)).resolves.not.toThrow()

expect(apiCommandMock).toHaveBeenCalledExactlyOnceWith(inputArgv)
expect(chooseHubFnMock).toHaveBeenCalledExactlyOnceWith({ withInstalledDriverId: 'cmd-line-driver-id' })
expect(chooseHubMock).toHaveBeenCalledExactlyOnceWith(
command,
'cmd-line-hub-id',
{ promptMessage: 'Select a hub to uninstall from.' },
)
expect(chooseDriverMock).toHaveBeenCalledExactlyOnceWith(
command,
'cmd-line-driver-id',
{ promptMessage: 'Select a driver to uninstall.', listItems: expect.any(Function) },
)
expect(apiHubDevicesUninstallDriverMock).toHaveBeenCalledExactlyOnceWith('chosen-driver-id', 'chosen-hub-id')
expect(consoleLogSpy).toHaveBeenCalledWith('Driver chosen-driver-id uninstalled from hub chosen-hub-id.')

const listInstalledDrivers = chooseDriverMock.mock.calls[0][2]?.listItems

const installedDrivers = [{ driverId: 'driver-id' } as InstalledDriver]
apiHubDevicesListInstalledMock.mockResolvedValueOnce(installedDrivers)

expect(await listInstalledDrivers?.(command)).toBe(installedDrivers)
})
35 changes: 27 additions & 8 deletions src/__tests__/lib/command/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ describe('formatAndWriteList', () => {
primaryKeyName: 'num',
}

await formatAndWriteList<SimpleType>(command, config, [], true)
await formatAndWriteList<SimpleType>(command, config, [], { includeIndex: true })

expect(listTableFormatterMock).toHaveBeenCalledTimes(0)
expect(listBuildOutputFormatterMock).toHaveBeenCalledTimes(1)
Expand All @@ -156,7 +156,7 @@ describe('formatAndWriteList', () => {
primaryKeyName: 'num',
}

await formatAndWriteList<SimpleType>(command, config, [], true)
await formatAndWriteList<SimpleType>(command, config, [], { includeIndex: true })

expect(listTableFormatterMock).toHaveBeenCalledTimes(0)
expect(listBuildOutputFormatterMock).toHaveBeenCalledTimes(1)
Expand All @@ -178,7 +178,7 @@ describe('formatAndWriteList', () => {
primaryKeyName: 'num',
}

await formatAndWriteList<SimpleType>(command, config, [], true)
await formatAndWriteList<SimpleType>(command, config, [], { includeIndex: true })

expect(listTableFormatterMock).toHaveBeenCalledTimes(0)
expect(listBuildOutputFormatterMock).toHaveBeenCalledTimes(1)
Expand All @@ -205,7 +205,8 @@ describe('formatAndWriteList', () => {
await formatAndWriteList(command, config, list)

expect(listTableFormatterMock).toHaveBeenCalledTimes(1)
expect(listTableFormatterMock).toHaveBeenCalledWith(command.tableGenerator, config.listTableFieldDefinitions, false)
expect(listTableFormatterMock)
.toHaveBeenCalledWith(command.tableGenerator, config.listTableFieldDefinitions, false)
expect(listBuildOutputFormatterMock).toHaveBeenCalledTimes(1)
expect(listBuildOutputFormatterMock).toHaveBeenCalledWith(flags, cliConfig, undefined, commonFormatter)
expect(outputFormatterMock).toHaveBeenCalledTimes(1)
Expand All @@ -220,7 +221,7 @@ describe('formatAndWriteList', () => {
primaryKeyName: 'num',
}

await formatAndWriteList<SimpleType>(command, config, list, true)
await formatAndWriteList<SimpleType>(command, config, list, { includeIndex: true })

expect(listTableFormatterMock).toHaveBeenCalledTimes(0)
expect(listBuildOutputFormatterMock).toHaveBeenCalledTimes(1)
Expand All @@ -244,7 +245,7 @@ describe('formatAndWriteList', () => {
primaryKeyName: 'num',
}

await formatAndWriteList<SimpleType>(command, config, list, true)
await formatAndWriteList<SimpleType>(command, config, list, { includeIndex: true })

expect(listTableFormatterMock).toHaveBeenCalledTimes(0)
expect(listBuildOutputFormatterMock).toHaveBeenCalledTimes(1)
Expand Down Expand Up @@ -282,6 +283,23 @@ describe('formatAndWriteList', () => {
expect(writeOutputMock).toHaveBeenCalledWith('output', 'output.yaml')
})

it('final fallback works with only `primaryKeyName`', async () => {
const config: CommonListOutputProducer<SimpleType> & Naming = {
primaryKeyName: 'num',
}

const commonFormatter = jest.fn<OutputFormatter<SimpleType[]>>()
listTableFormatterMock.mockReturnValue(commonFormatter)

await formatAndWriteList(command, config, list)

expect(listTableFormatterMock).toHaveBeenCalledExactlyOnceWith(command.tableGenerator, ['num'], false)
expect(listBuildOutputFormatterMock)
.toHaveBeenCalledExactlyOnceWith(flags, cliConfig, undefined, commonFormatter)
expect(outputFormatterMock).toHaveBeenCalledExactlyOnceWith(list)
expect(writeOutputMock).toHaveBeenCalledExactlyOnceWith('output', 'output.yaml')
})

it('writes common formatted output to stdout when forUserQuery specified', async () => {
const config: TableCommonListOutputProducer<SimpleType> = {
listTableFieldDefinitions: [],
Expand All @@ -291,10 +309,11 @@ describe('formatAndWriteList', () => {
const commonFormatter = jest.fn<OutputFormatter<SimpleType[]>>().mockReturnValue('common output')
listTableFormatterMock.mockReturnValue(commonFormatter)

await formatAndWriteList(command, config, list, false, true)
await formatAndWriteList(command, config, list, { forUserQuery: true })

expect(listTableFormatterMock).toHaveBeenCalledTimes(1)
expect(listTableFormatterMock).toHaveBeenCalledWith(command.tableGenerator, config.listTableFieldDefinitions, false)
expect(listTableFormatterMock)
.toHaveBeenCalledWith(command.tableGenerator, config.listTableFieldDefinitions, false)
expect(listBuildOutputFormatterMock).toHaveBeenCalledTimes(0)
expect(outputFormatterMock).toHaveBeenCalledTimes(0)
expect(commonFormatter).toHaveBeenCalledTimes(1)
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/lib/command/listing-io.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('outputItemOrListGeneric', () => {
await outputItemOrListGeneric<string, SimpleType, SimpleType>(command, config, undefined,
listFunction, getFunction, translateToId)

expect(outputListMock).toHaveBeenCalledExactlyOnceWith(command, config, listFunction, true)
expect(outputListMock).toHaveBeenCalledExactlyOnceWith(command, config, listFunction, { includeIndex: true })

expect(translateToId).not.toHaveBeenCalled()
expect(getFunction).not.toHaveBeenCalled()
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('outputItemOrList', () => {

await outputItemOrList(command, config, undefined, listFunction, getFunction, true)

expect(outputListMock).toHaveBeenCalledExactlyOnceWith(command, config, listFunction, true)
expect(outputListMock).toHaveBeenCalledExactlyOnceWith(command, config, listFunction, { includeIndex: true })

expect(stringTranslateToIdMock).not.toHaveBeenCalled()
expect(getFunction).not.toHaveBeenCalled()
Expand Down
14 changes: 7 additions & 7 deletions src/__tests__/lib/command/output-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,34 @@ describe('outputList', () => {

expect(sortMock).toHaveBeenCalledExactlyOnceWith(list, 'str')
expect(formatAndWriteListMock)
.toHaveBeenCalledExactlyOnceWith(command, config, sorted, false, false)
.toHaveBeenCalledExactlyOnceWith(command, config, sorted, undefined)
})

it('passes includeIndex value on to formatAndWriteList', async () => {
expect(await outputList<SimpleType>(command, config, getDataMock, true)).toBe(sorted)
expect(await outputList<SimpleType>(command, config, getDataMock, { includeIndex: true })).toBe(sorted)

expect(sortMock).toHaveBeenCalledExactlyOnceWith(list, 'str')
expect(formatAndWriteListMock)
.toHaveBeenCalledExactlyOnceWith(command, config, sorted, true, false)
.toHaveBeenCalledExactlyOnceWith(command, config, sorted, { includeIndex: true })
})

it('passes forUserQuery value on to formatAndWriteList', async () => {
expect(await outputList<SimpleType>(command, config, getDataMock, false, true)).toBe(sorted)
expect(await outputList<SimpleType>(command, config, getDataMock, { forUserQuery: true })).toBe(sorted)

expect(sortMock).toHaveBeenCalledExactlyOnceWith(list, 'str')
expect(formatAndWriteListMock)
.toHaveBeenCalledExactlyOnceWith(command, config, sorted, false, true)
.toHaveBeenCalledExactlyOnceWith(command, config, sorted, { forUserQuery: true })
})

it('skips sorting when no sort key is specified', async () => {
const config: OutputListConfig<SimpleType> = {
listTableFieldDefinitions: [],
primaryKeyName: 'num',
}
expect(await outputList<SimpleType>(command, config, getDataMock, false, true)).toBe(list)
expect(await outputList<SimpleType>(command, config, getDataMock, { forUserQuery: true })).toBe(list)

expect(sortMock).not.toHaveBeenCalled()
expect(formatAndWriteListMock)
.toHaveBeenCalledExactlyOnceWith(command, config, list, false, true)
.toHaveBeenCalledExactlyOnceWith(command, config, list, { forUserQuery: true })
})
})
Loading