Skip to content

Commit 2337cf3

Browse files
committed
refactor: convert schema utils functions to yargs
1 parent 32a8294 commit 2337cf3

File tree

9 files changed

+718
-548
lines changed

9 files changed

+718
-548
lines changed

packages/cli/src/__tests__/lib/commands/schema-util.test.ts

Lines changed: 0 additions & 466 deletions
This file was deleted.

packages/cli/src/commands/invites/schema/create.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export default class InvitesSchemaCreateCommand extends APICommand<typeof Invite
5454
const schemaAppsById = new Map<string, SchemaApp>()
5555

5656
const updateFromUserInput = async (): Promise<string | CancelAction> => {
57-
const schemaAppId = await chooseSchemaApp(this, this.flags['schema-app'])
57+
const schemaAppId = await chooseSchemaApp(this, this.flags['schema-app'], { autoChoose: true })
5858
if (!schemaAppsById.has(schemaAppId)) {
5959
const schemaApp = await this.client.schema.get(schemaAppId)
6060
schemaAppsById.set(schemaAppId, schemaApp)

packages/cli/src/lib/commands/invites-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const chooseSchemaInvitation = async (command: APICommand<typeof APIComma
2020
sortKeyName: 'description',
2121
}
2222
const listItems = async (): Promise<SchemaAppInvitation[]> => {
23-
const schemaAppId = await chooseSchemaApp(command, schemaAppFromArgs)
23+
const schemaAppId = await chooseSchemaApp(command, schemaAppFromArgs, { autoChoose: true })
2424
return command.client.invitesSchema.list(schemaAppId)
2525
}
2626
const preselectedId = opts.allowIndex
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { jest } from '@jest/globals'
2+
3+
import type {
4+
OrganizationResponse,
5+
} from '@smartthings/core-sdk'
6+
7+
import {
8+
InputDefinition,
9+
selectDef,
10+
staticDef,
11+
undefinedDef,
12+
} from '../../../../lib/item-input/index.js'
13+
14+
15+
const selectDefMock = jest.fn<typeof selectDef>()
16+
const staticDefMock = jest.fn<typeof staticDef>()
17+
const undefinedDefMock = {} as typeof undefinedDef
18+
jest.unstable_mockModule('../../../../lib/item-input/index.js', () => ({
19+
selectDef: selectDefMock,
20+
staticDef: staticDefMock,
21+
undefinedDef: undefinedDefMock,
22+
}))
23+
24+
25+
const { organizationDef } = await import('../../../../lib/command/util/organizations-util.js')
26+
27+
28+
describe('organizationDef', () => {
29+
const organization1 = { name: 'Organization 1', organizationId: 'organization-id-1' }
30+
31+
it('returns undefinedDef when given no organizations', () => {
32+
expect(organizationDef('organization-needing thing', [])).toBe(undefinedDefMock)
33+
})
34+
35+
it('returns staticDef for a single organization', () => {
36+
const mockDef = {} as InputDefinition<string | undefined>
37+
staticDefMock.mockReturnValueOnce(mockDef)
38+
39+
expect(organizationDef('organization-needing thing', [organization1])).toBe(mockDef)
40+
41+
expect(staticDefMock).toHaveBeenCalledExactlyOnceWith('organization-id-1')
42+
})
43+
44+
it('returns selectDef for multiple organizations', () => {
45+
const organization2 = { name: 'Organization 2', organizationId: 'organization-id-2' }
46+
const organizations = [organization1, organization2] as OrganizationResponse[]
47+
const mockDef = {} as InputDefinition<string | undefined>
48+
selectDefMock.mockReturnValueOnce(mockDef)
49+
50+
expect(organizationDef('organization-needing thing', organizations)).toBe(mockDef)
51+
52+
const helpText =
53+
'The organization with which the organization-needing thing should be associated.'
54+
expect(selectDefMock).toHaveBeenCalledExactlyOnceWith(
55+
'Organization',
56+
[
57+
{ name: 'Organization 1', value: 'organization-id-1' },
58+
{ name: 'Organization 2', value: 'organization-id-2' },
59+
],
60+
{ helpText },
61+
)
62+
})
63+
})
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import { jest } from '@jest/globals'
2+
3+
import type { SchemaAppRequest } from '@smartthings/core-sdk'
4+
5+
import { awsHelpText } from '../../../../lib/aws-util.js'
6+
import type {
7+
booleanDef,
8+
createFromUserInput,
9+
InputDefinition,
10+
listSelectionDef,
11+
objectDef,
12+
optionalDef,
13+
optionalStringDef,
14+
selectDef,
15+
staticDef,
16+
stringDef,
17+
undefinedDef,
18+
updateFromUserInput,
19+
} from '../../../../lib/item-input/index.js'
20+
21+
22+
const booleanDefMock = jest.fn<typeof booleanDef>()
23+
const createFromUserInputMock = jest.fn<typeof createFromUserInput>()
24+
const listSelectionDefMock = jest.fn<typeof listSelectionDef>()
25+
const objectDefMock = jest.fn<typeof objectDef>()
26+
const optionalDefMock = jest.fn<typeof optionalDef>()
27+
const optionalStringDefMock = jest.fn<typeof optionalStringDef>()
28+
const selectDefMock = jest.fn<typeof selectDef>()
29+
const staticDefMock = jest.fn<typeof staticDef>()
30+
const stringDefMock = jest.fn<typeof stringDef>()
31+
const undefinedDefMock = {} as typeof undefinedDef
32+
const updateFromUserInputMock = jest.fn<typeof updateFromUserInput>()
33+
jest.unstable_mockModule('../../../../lib/item-input/index.js', () => ({
34+
booleanDef: booleanDefMock,
35+
createFromUserInput: createFromUserInputMock,
36+
listSelectionDef: listSelectionDefMock,
37+
maxItemValueLength: 16,
38+
objectDef: objectDefMock,
39+
optionalDef: optionalDefMock,
40+
optionalStringDef: optionalStringDefMock,
41+
selectDef: selectDefMock,
42+
staticDef: staticDefMock,
43+
stringDef: stringDefMock,
44+
undefinedDef: undefinedDefMock,
45+
updateFromUserInput: updateFromUserInputMock,
46+
}))
47+
48+
49+
const {
50+
arnDef,
51+
webHookUrlDef,
52+
} = await import('../../../../lib/command/util/schema-util-input-primitives.js')
53+
54+
55+
const generatedStringDef = { name: 'Generated String Def' } as InputDefinition<string>
56+
const generatedARNDef = { name: 'Generated ARN Def' } as InputDefinition<string | undefined>
57+
const lambdaInitialValue = { appName: 'Schema App', hostingType: 'lambda' } as SchemaAppRequest
58+
const webhookInitialValue = { appName: 'Schema App', hostingType: 'webhook' } as SchemaAppRequest
59+
60+
describe('arnDef', () => {
61+
it('uses undefinedDef when in China but ARN is not for China', () => {
62+
expect(arnDef('ARN', true, undefined)).toBe(undefinedDefMock)
63+
expect(arnDef('ARN', true, undefined, { forChina: false })).toBe(undefinedDefMock)
64+
})
65+
66+
it('uses undefinedDef when not in China but for China', () => {
67+
expect(arnDef('ARN', false, undefined, { forChina: true })).toBe(undefinedDefMock)
68+
})
69+
70+
it('uses required stringDef in China', () => {
71+
stringDefMock.mockReturnValueOnce(generatedStringDef)
72+
optionalDefMock.mockReturnValueOnce(generatedARNDef)
73+
74+
expect(arnDef('ARN', true, lambdaInitialValue, { forChina: true })).toBe(generatedARNDef)
75+
76+
expect(stringDefMock).toHaveBeenCalledExactlyOnceWith('ARN', { helpText: awsHelpText })
77+
expect(optionalDefMock).toHaveBeenCalledExactlyOnceWith(
78+
generatedStringDef,
79+
expect.any(Function),
80+
{ initiallyActive: true },
81+
)
82+
83+
expect(optionalStringDefMock).not.toHaveBeenCalled()
84+
})
85+
86+
it('uses optional string def for global', () => {
87+
optionalStringDefMock.mockReturnValueOnce(generatedStringDef)
88+
optionalDefMock.mockReturnValueOnce(generatedARNDef)
89+
90+
expect(arnDef('ARN', false)).toBe(generatedARNDef)
91+
92+
expect(optionalStringDefMock)
93+
.toHaveBeenCalledExactlyOnceWith('ARN', { helpText: awsHelpText })
94+
expect(optionalDefMock).toHaveBeenCalledExactlyOnceWith(
95+
generatedStringDef,
96+
expect.any(Function),
97+
{ initiallyActive: false },
98+
)
99+
100+
expect(stringDefMock).not.toHaveBeenCalled()
101+
})
102+
103+
it.each`
104+
initialValue | initiallyActive
105+
${{ hostingType: 'lambda' }} | ${true}
106+
${{ hostingType: 'webhook' }} | ${false}
107+
${undefined} | ${false}
108+
`('uses initiallyActive $initiallyActive for initialValue $initialValue', ({ initialValue, initiallyActive }) => {
109+
optionalStringDefMock.mockReturnValueOnce(generatedStringDef)
110+
optionalDefMock.mockReturnValueOnce(generatedARNDef)
111+
112+
expect(arnDef('ARN', false, initialValue)).toBe(generatedARNDef)
113+
114+
expect(optionalDefMock).toHaveBeenCalledExactlyOnceWith(generatedStringDef, expect.any(Function), { initiallyActive })
115+
})
116+
117+
it('predicate function tests for hostingType of "lambda"', async () => {
118+
optionalStringDefMock.mockReturnValueOnce(generatedStringDef)
119+
optionalDefMock.mockReturnValueOnce(generatedARNDef)
120+
121+
expect(arnDef('ARN', false, lambdaInitialValue)).toBe(generatedARNDef)
122+
123+
const checkIfActiveFunction = optionalDefMock.mock.calls[0][1]
124+
125+
expect(checkIfActiveFunction([{ hostingType: 'lambda' }])).toBe(true)
126+
expect(checkIfActiveFunction([{ hostingType: 'webhook' }])).toBe(false)
127+
expect(checkIfActiveFunction()).toBe(false)
128+
})
129+
})
130+
131+
describe('webHookUrlDef', () => {
132+
it('uses undefinedDef when in China', () => {
133+
expect(webHookUrlDef(true, undefined)).toBe(undefinedDefMock)
134+
})
135+
136+
it('uses stringDef when not in China', () => {
137+
stringDefMock.mockReturnValueOnce(generatedStringDef)
138+
optionalDefMock.mockReturnValueOnce(generatedARNDef)
139+
140+
expect(webHookUrlDef(false, webhookInitialValue)).toBe(generatedARNDef)
141+
142+
expect(stringDefMock).toHaveBeenCalledExactlyOnceWith('Webhook URL')
143+
expect(optionalDefMock).toHaveBeenCalledExactlyOnceWith(
144+
generatedStringDef,
145+
expect.any(Function),
146+
{ initiallyActive: true },
147+
)
148+
149+
expect(optionalStringDefMock).not.toHaveBeenCalled()
150+
})
151+
152+
it.each`
153+
initialValue | initiallyActive
154+
${{ hostingType: 'webhook' }} | ${true}
155+
${{ hostingType: 'lambda' }} | ${false}
156+
${undefined} | ${false}
157+
`('uses initiallyActive $initiallyActive for initialValue $initialValue', ({ initialValue, initiallyActive }) => {
158+
stringDefMock.mockReturnValueOnce(generatedStringDef)
159+
optionalDefMock.mockReturnValueOnce(generatedARNDef)
160+
161+
expect(webHookUrlDef(false, initialValue)).toBe(generatedARNDef)
162+
163+
expect(optionalDefMock).toHaveBeenCalledExactlyOnceWith(generatedStringDef, expect.any(Function), { initiallyActive })
164+
})
165+
166+
it('predicate function tests for hostingType of "webhook"', async () => {
167+
optionalStringDefMock.mockReturnValueOnce(generatedStringDef)
168+
optionalDefMock.mockReturnValueOnce(generatedARNDef)
169+
170+
expect(webHookUrlDef(false, webhookInitialValue)).toBe(generatedARNDef)
171+
172+
const checkIfActiveFunction = optionalDefMock.mock.calls[0][1]
173+
174+
expect(checkIfActiveFunction([{ hostingType: 'lambda' }])).toBe(false)
175+
expect(checkIfActiveFunction([{ hostingType: 'webhook' }])).toBe(true)
176+
expect(checkIfActiveFunction()).toBe(false)
177+
})
178+
})

0 commit comments

Comments
 (0)