Skip to content

Commit

Permalink
chore: consolidate all choose function stuff in util-utils.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
rossiam committed Sep 24, 2024
1 parent 039d439 commit e8ecd26
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 168 deletions.
50 changes: 7 additions & 43 deletions src/__tests__/lib/command/command-util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { jest } from '@jest/globals'

import inquirer from 'inquirer'

import { ChooseOptions } from '../../../lib/command/command-util.js'
import { sort } from '../../../lib/command/output.js'
import { ListDataFunction, Sorting } from '../../../lib/command/basic-io.js'
import { SimpleType } from '../../test-lib/simple-type.js'
Expand All @@ -22,8 +21,6 @@ jest.unstable_mockModule('../../../lib/command/output.js', () => ({


const {
chooseOptionsDefaults,
chooseOptionsWithDefaults,
convertToId,
isIndexArgument,
itemName,
Expand Down Expand Up @@ -103,8 +100,7 @@ describe('stringTranslateToId', () => {
expect(computedId).toBe('string-id-a')

expect(listFunction).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledWith(list, 'num')
expect(sortMock).toHaveBeenCalledExactlyOnceWith(list, 'num')
})

it('throws an error when item not found', async () => {
Expand All @@ -115,8 +111,7 @@ describe('stringTranslateToId', () => {
.rejects.toThrow('invalid index 4 (enter an id or index between 1 and 3 inclusive)')

expect(listFunction).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledWith(list, 'num')
expect(sortMock).toHaveBeenCalledExactlyOnceWith(list, 'num')
})

it('throws an error for missing primary key', async () => {
Expand All @@ -127,8 +122,7 @@ describe('stringTranslateToId', () => {
.rejects.toThrow('did not find key str in data')

expect(listFunction).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledWith(list, 'num')
expect(sortMock).toHaveBeenCalledExactlyOnceWith(list, 'num')
})

it('throws an error for invalid type for primary key', async () => {
Expand All @@ -139,8 +133,7 @@ describe('stringTranslateToId', () => {
.rejects.toThrow('invalid type number for primary key str in {"str":3,"num":5}')

expect(listFunction).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledTimes(1)
expect(sortMock).toHaveBeenCalledWith(list, 'num')
expect(sortMock).toHaveBeenCalledExactlyOnceWith(list, 'num')
})
})

Expand Down Expand Up @@ -175,8 +168,7 @@ describe('stringGetIdFromUser', () => {

expect(chosenId).toBe('string-id-a')

expect(promptMock).toHaveBeenCalledTimes(1)
expect(promptMock).toHaveBeenCalledWith({
expect(promptMock).toHaveBeenCalledExactlyOnceWith({
type: 'input', name: 'itemIdOrIndex',
message: 'Enter id or index', validate: expect.anything(),
})
Expand All @@ -192,8 +184,7 @@ describe('stringGetIdFromUser', () => {

expect(chosenId).toBe('string-id-a')

expect(promptMock).toHaveBeenCalledTimes(1)
expect(promptMock).toHaveBeenCalledWith({
expect(promptMock).toHaveBeenCalledExactlyOnceWith({
type: 'input', name: 'itemIdOrIndex',
message: 'Enter id or index', validate: expect.anything(),
})
Expand All @@ -215,8 +206,7 @@ describe('stringGetIdFromUser', () => {

expect(chosenId).toBe('string-id-a')

expect(promptMock).toHaveBeenCalledTimes(1)
expect(promptMock).toHaveBeenCalledWith({
expect(promptMock).toHaveBeenCalledExactlyOnceWith({
type: 'input', name: 'itemIdOrIndex',
message: 'give me an id', validate: expect.anything(),
})
Expand All @@ -225,29 +215,3 @@ describe('stringGetIdFromUser', () => {
expect(validateFunction('string-id-a')).toBe(true)
})
})

describe('chooseOptionsWithDefaults', () => {
it('uses defaults with undefined input', () => {
expect(chooseOptionsWithDefaults(undefined)).toStrictEqual(chooseOptionsDefaults())
})

it('uses defaults with empty input', () => {
expect(chooseOptionsWithDefaults({})).toStrictEqual(chooseOptionsDefaults())
})

it('input overrides default', () => {
const optionsDifferentThanDefault = {
allowIndex: true,
verbose: true,
useConfigDefault: true,
autoChoose: true,
}
expect(chooseOptionsWithDefaults(optionsDifferentThanDefault))
.toEqual(optionsDifferentThanDefault)
})

it('passes on other values unchanged', () => {
expect(chooseOptionsWithDefaults({ someOtherKey: 'some other value' } as Partial<ChooseOptions<{ someOtherKey: string }>>))
.toEqual(expect.objectContaining({ someOtherKey: 'some other value' }))
})
})
80 changes: 41 additions & 39 deletions src/__tests__/lib/command/util/apps-util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,36 @@ import { jest } from '@jest/globals'

import { AppResponse, AppsEndpoint, AppType, PagedApp, SmartThingsClient } from '@smartthings/core-sdk'

import { PropertyTableFieldDefinition, Table, TableGenerator, ValueTableFieldDefinition } from '../../../../lib/table-generator.js'
import { APICommand } from '../../../../lib/command/api-command.js'
import {
chooseOptionsDefaults,
PropertyTableFieldDefinition,
Table,
TableGenerator,
ValueTableFieldDefinition,
} from '../../../../lib/table-generator.js'
import { stringTranslateToId } from '../../../../lib/command/command-util.js'
import {
createChooseFn,
type ChooseFunction,
chooseOptionsWithDefaults,
stringTranslateToId,
} from '../../../../lib/command/command-util.js'
import { selectFromList, SelectFromListFlags } from '../../../../lib/command/select.js'
} from '../../../../lib/command/util/util-util.js'


const chooseOptionsWithDefaultsMock = jest.fn<typeof chooseOptionsWithDefaults>()
const stringTranslateToIdMock = jest.fn<typeof stringTranslateToId>()
jest.unstable_mockModule('../../../../lib/command/command-util.js', () => ({
chooseOptionsDefaults,
chooseOptionsWithDefaults: chooseOptionsWithDefaultsMock,
stringTranslateToId: stringTranslateToIdMock,
}))

const selectFromListMock = jest.fn<typeof selectFromList>()
jest.unstable_mockModule('../../../../lib/command/select.js', () => ({
selectFromList: selectFromListMock,
const createChooseFnMock = jest.fn<typeof createChooseFn<PagedApp>>()
const chooseOptionsWithDefaultsMock = jest.fn<typeof chooseOptionsWithDefaults>()
jest.unstable_mockModule('../../../../lib/command/util/util-util.js', () => ({
chooseOptionsWithDefaults: chooseOptionsWithDefaultsMock,
createChooseFn: createChooseFnMock,
}))


const {
buildTableOutput,
chooseApp,
chooseAppFn,
hasSubscription,
isWebhookSmartApp,
shortARNorURL,
Expand Down Expand Up @@ -139,29 +142,32 @@ describe('tableFieldDefinitions functions', () => {
})
})

test('chooseApp uses correct endpoint to list apps', async () => {
selectFromListMock.mockResolvedValue('selected-app-id')
chooseOptionsWithDefaultsMock.mockReturnValue(chooseOptionsDefaults())
test('chooseAppFn uses correct endpoint to list apps', async () => {
const chooseAppMock = jest.fn<ChooseFunction<PagedApp>>()
createChooseFnMock.mockReturnValueOnce(chooseAppMock)

const apiAppsListMock = jest.fn<typeof AppsEndpoint.prototype.list>()
const command = {
client: {
apps: {
list: apiAppsListMock,
},
},
} as unknown as APICommand<SelectFromListFlags>
const chooseApp = chooseAppFn()

expect(chooseApp).toBe(chooseAppMock)

expect(await chooseApp(command)).toBe('selected-app-id')
expect(createChooseFnMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ itemName: 'app' }),
expect.any(Function),
)

const listItems = selectFromListMock.mock.calls[0][2].listItems
const appsList = [{ appId: 'listed-app-id' } as PagedApp]
apiAppsListMock.mockResolvedValueOnce(appsList)
const appList = [{ appId: 'listed-app-id' } as PagedApp]
const apiAppsListMock = jest.fn<typeof AppsEndpoint.prototype.list>()
.mockResolvedValueOnce(appList)
const listItems = createChooseFnMock.mock.calls[0][1]
const client = {
apps: {
list: apiAppsListMock,
},
} as unknown as SmartThingsClient

expect(await listItems()).toBe(appsList)
expect(await listItems(client)).toBe(appList)

expect(apiAppsListMock).toHaveBeenCalledTimes(1)
expect(apiAppsListMock).toHaveBeenCalledWith()
expect(apiAppsListMock).toHaveBeenCalledExactlyOnceWith()
})

describe('buildTableOutput', () => {
Expand All @@ -183,10 +189,8 @@ describe('buildTableOutput', () => {
expect(newOutputTableMock).toHaveBeenCalledWith(
expect.objectContaining({ head: ['Key', 'Value'] }),
)
expect(pushMock).toHaveBeenCalledTimes(1)
expect(pushMock).toHaveBeenCalledWith(['setting', 'setting value'])
expect(toStringMock).toHaveBeenCalledTimes(1)
expect(toStringMock).toHaveBeenCalledWith()
expect(pushMock).toHaveBeenCalledExactlyOnceWith(['setting', 'setting value'])
expect(toStringMock).toHaveBeenCalledExactlyOnceWith()
})
})

Expand All @@ -202,8 +206,7 @@ describe('verboseApps', () => {

expect(await verboseApps(client, options))

expect(listMock).toHaveBeenCalledTimes(1)
expect(listMock).toHaveBeenCalledWith(options)
expect(listMock).toHaveBeenCalledExactlyOnceWith(options)
expect(getMock).toHaveBeenCalledTimes(0)
})

Expand All @@ -219,8 +222,7 @@ describe('verboseApps', () => {

expect(await verboseApps(client, {}))

expect(listMock).toHaveBeenCalledTimes(1)
expect(listMock).toHaveBeenCalledWith({})
expect(listMock).toHaveBeenCalledExactlyOnceWith({})
expect(getMock).toHaveBeenCalledTimes(2)
expect(getMock).toHaveBeenCalledWith('paged-app-1-id')
expect(getMock).toHaveBeenCalledWith('paged-app-2-id')
Expand Down
60 changes: 29 additions & 31 deletions src/__tests__/lib/command/util/locations-util.test.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,50 @@
import { jest } from '@jest/globals'

import { selectFromList, SelectFromListFlags } from '../../../../lib/command/select.js'
import { APICommand } from '../../../../lib/command/api-command.js'
import { LocationItem, LocationsEndpoint } from '@smartthings/core-sdk'
import { LocationItem, LocationsEndpoint, SmartThingsClient } from '@smartthings/core-sdk'
import { stringTranslateToId } from '../../../../lib/command/command-util.js'
import {
chooseOptionsDefaults,
chooseOptionsWithDefaults,
stringTranslateToId,
} from '../../../../lib/command/command-util.js'
createChooseFn,
type ChooseFunction,
} from '../../../../lib/command/util/util-util.js'


const chooseOptionsWithDefaultsMock = jest.fn<typeof chooseOptionsWithDefaults>()
const stringTranslateToIdMock = jest.fn<typeof stringTranslateToId>()
jest.unstable_mockModule('../../../../lib/command/command-util.js', () => ({
chooseOptionsDefaults,
chooseOptionsWithDefaults: chooseOptionsWithDefaultsMock,
stringTranslateToId: stringTranslateToIdMock,
}))

const selectFromListMock = jest.fn<typeof selectFromList>()
jest.unstable_mockModule('../../../../lib/command/select.js', () => ({
selectFromList: selectFromListMock,
const createChooseFnMock = jest.fn<typeof createChooseFn<LocationItem>>()
jest.unstable_mockModule('../../../../lib/command/util/util-util.js', () => ({
createChooseFn: createChooseFnMock,
}))


const { chooseLocation } = await import('../../../../lib/command/util/locations-util.js')
const { chooseLocationFn } = await import('../../../../lib/command/util/locations-util.js')

test('chooseLocation uses correct endpoint to list locations', async () => {
selectFromListMock.mockResolvedValue('selected-location-id')
chooseOptionsWithDefaultsMock.mockReturnValue(chooseOptionsDefaults())
test('chooseLocationFn uses correct endpoint to list locations', async () => {
const chooseLocationMock = jest.fn<ChooseFunction<LocationItem>>()
createChooseFnMock.mockReturnValueOnce(chooseLocationMock)

const apiLocationsListMock = jest.fn<typeof LocationsEndpoint.prototype.list>()
const command = {
client: {
locations: {
list: apiLocationsListMock,
},
},
} as unknown as APICommand<SelectFromListFlags>
const chooseLocation = chooseLocationFn()

expect(chooseLocation).toBe(chooseLocationMock)

expect(await chooseLocation(command)).toBe('selected-location-id')
expect(createChooseFnMock).toHaveBeenCalledExactlyOnceWith(
expect.objectContaining({ itemName: 'location' }),
expect.any(Function),
)

const listItems = selectFromListMock.mock.calls[0][2].listItems
const locationList = [{ locationId: 'listed-location-id' } as LocationItem]
apiLocationsListMock.mockResolvedValueOnce(locationList)
const apiLocationsListMock = jest.fn<typeof LocationsEndpoint.prototype.list>()
.mockResolvedValueOnce(locationList)
const listItems = createChooseFnMock.mock.calls[0][1]
const client = {
locations: {
list: apiLocationsListMock,
},
} as unknown as SmartThingsClient

expect(await listItems()).toBe(locationList)
expect(await listItems(client)).toBe(locationList)

expect(apiLocationsListMock).toHaveBeenCalledTimes(1)
expect(apiLocationsListMock).toHaveBeenCalledWith()
expect(apiLocationsListMock).toHaveBeenCalledExactlyOnceWith()
})
Loading

0 comments on commit e8ecd26

Please sign in to comment.