@adobe/aio-cli-lib-console
Version:
Adobe I/O Console CLI library
1,123 lines (1,064 loc) • 64.7 kB
JavaScript
/*
Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
const dataMocks = require('../data-mocks')
const path = require('path')
const validators = require('../../lib/validate')
// console sdk mock setup
jest.mock('@adobe/aio-lib-console')
const consoleSDK = require('@adobe/aio-lib-console')
const mockConsoleSDKInstance = {
getOrganizations: jest.fn(),
getProjectsForOrg: jest.fn(),
getWorkspacesForProject: jest.fn(),
getServicesForOrg: jest.fn(),
createWorkspace: jest.fn(),
createProject: jest.fn(),
getWorkspace: jest.fn(),
getProject: jest.fn(),
createRuntimeNamespace: jest.fn(),
downloadWorkspaceJson: jest.fn(),
subscribeCredentialToServices: jest.fn(),
getSDKProperties: jest.fn(),
getIntegration: jest.fn(),
createEnterpriseCredential: jest.fn(),
createOAuthServerToServerCredential: jest.fn(),
getCredentials: jest.fn(),
getEndPointsInWorkspace: jest.fn(),
updateEndPointsInWorkspace: jest.fn(),
getAllExtensionPoints: jest.fn(),
getApplicationExtensions: jest.fn(),
checkOrgDevTerms: jest.fn(),
getDevTerms: jest.fn(),
acceptOrgDevTerms: jest.fn(),
getBindingsForIntegration: jest.fn(),
uploadAndBindCertificate: jest.fn(),
deleteBinding: jest.fn()
}
consoleSDK.init.mockResolvedValue(mockConsoleSDKInstance)
/** @private */
function resetMockConsoleSDK () {
Object.keys(mockConsoleSDKInstance).forEach(
k => mockConsoleSDKInstance[k].mockClear()
)
consoleSDK.init.mockClear()
}
/** @private */
function setDefaultMockConsoleSdk () {
mockConsoleSDKInstance.getOrganizations.mockResolvedValue({ body: dataMocks.organizations })
mockConsoleSDKInstance.getProjectsForOrg.mockResolvedValue({ body: dataMocks.projects })
mockConsoleSDKInstance.getWorkspacesForProject.mockResolvedValue({ body: dataMocks.workspaces })
mockConsoleSDKInstance.getServicesForOrg.mockResolvedValue({ body: dataMocks.services })
mockConsoleSDKInstance.getProject.mockResolvedValue({ body: dataMocks.project })
mockConsoleSDKInstance.getWorkspace.mockResolvedValue({ body: dataMocks.workspace })
mockConsoleSDKInstance.createProject.mockResolvedValue({ body: { projectId: dataMocks.project.id } })
mockConsoleSDKInstance.createWorkspace.mockResolvedValue({ body: { workspaceId: dataMocks.workspace.id } })
mockConsoleSDKInstance.downloadWorkspaceJson.mockResolvedValue({ body: dataMocks.workspaceJson })
mockConsoleSDKInstance.createRuntimeNamespace.mockResolvedValue({ body: {} })
mockConsoleSDKInstance.subscribeCredentialToServices.mockResolvedValue({ body: dataMocks.subscribeServicesResponse })
mockConsoleSDKInstance.getSDKProperties.mockResolvedValue({ body: {} })
mockConsoleSDKInstance.getIntegration.mockResolvedValue({ body: dataMocks.integration })
mockConsoleSDKInstance.createEnterpriseCredential.mockResolvedValue({ body: dataMocks.integrationCreateResponse })
mockConsoleSDKInstance.createOAuthServerToServerCredential.mockResolvedValue({ body: dataMocks.integrationCreateResponseOAuthServerToServer })
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: dataMocks.integrations })
mockConsoleSDKInstance.getEndPointsInWorkspace.mockResolvedValue({ body: dataMocks.baseWorkspaceEndPoints })
mockConsoleSDKInstance.updateEndPointsInWorkspace.mockResolvedValue({ body: dataMocks.multipleWorkspaceEndPoints })
mockConsoleSDKInstance.getAllExtensionPoints.mockResolvedValue({ body: dataMocks.allExtensionPoints })
mockConsoleSDKInstance.getApplicationExtensions.mockResolvedValue({ body: dataMocks.applicationExtensions })
mockConsoleSDKInstance.getDevTerms.mockResolvedValue({ body: { tc: [{ text: 'some dev terms', locale: 'en' }] } })
mockConsoleSDKInstance.checkOrgDevTerms.mockResolvedValue({ body: { accepted: true, current: true } })
mockConsoleSDKInstance.acceptOrgDevTerms.mockResolvedValue({ body: { accepted: true, current: true } })
mockConsoleSDKInstance.getBindingsForIntegration.mockResolvedValue({ body: [] })
mockConsoleSDKInstance.uploadAndBindCertificate.mockResolvedValue({ body: {} })
}
// mock prompts
const mockPrompt = {
promptChoice: jest.fn(),
promptConfirm: jest.fn(),
promptInput: jest.fn(),
promptMultiSelect: jest.fn(),
promptSelect: jest.fn(),
promptSelectOrCreate: jest.fn()
}
jest.mock('../../lib/prompt.js', () => () => mockPrompt)
/** @private */
function resetMockPrompt () {
mockPrompt.promptChoice.mockReset()
mockPrompt.promptConfirm.mockReset()
mockPrompt.promptInput.mockReset()
mockPrompt.promptMultiSelect.mockReset()
mockPrompt.promptSelect.mockReset()
mockPrompt.promptSelectOrCreate.mockReset()
}
// ora mocks setup before requiring LibConsoleCli
jest.mock('ora')
const mockOraObject = {
start: jest.fn(),
stop: jest.fn()
}
const ora = require('ora')
ora.mockReturnValue(mockOraObject)
/** @private */
function resetMockOraObject () {
mockOraObject.start.mockReset()
mockOraObject.stop.mockReset()
}
// mock certPlugin
jest.mock('@adobe/aio-cli-plugin-certificate')
const certPlugin = require('@adobe/aio-cli-plugin-certificate')
certPlugin.generate = jest.fn()
certPlugin.fingerprint = jest.fn()
/** @private */
function resetMockCertPlugin () {
certPlugin.generate.mockReset()
certPlugin.fingerprint.mockReset()
}
/** @private */
function setDefaultMockCertPlugin () {
certPlugin.generate.mockReturnValue({ cert: 'fake public key', privateKey: 'fake private key' })
certPlugin.fingerprint.mockReturnValue({ certificateFingerprint: 'fake fingerprint' })
}
// mock fs
jest.mock('fs-extra')
const fs = require('fs-extra')
/** @private */
function resetMockFs () {
fs.createReadStream.mockReset()
fs.ensureDirSync.mockReset()
fs.writeFileSync.mockReset()
}
/** @private */
function setDefaultMockFs () {
fs.createReadStream.mockReturnValue('fake read stream')
}
// fake credentials
const consoleCredentials = {
env: 'env',
accessToken: 'accessToken',
apiKey: 'apiKey'
}
// reset and set mocks before each test
beforeEach(() => {
resetMockConsoleSDK()
setDefaultMockConsoleSdk()
resetMockOraObject()
resetMockCertPlugin()
setDefaultMockCertPlugin()
resetMockFs()
setDefaultMockFs()
resetMockPrompt()
})
// require lib after setting up mocks
const LibConsoleCli = require('../../')
test('init', async () => {
await LibConsoleCli.init(consoleCredentials, {})
expect(consoleSDK.init).toHaveBeenCalledWith(
consoleCredentials.accessToken,
consoleCredentials.apiKey,
consoleCredentials.env
)
})
test('cleanStdOut', async () => {
LibConsoleCli.cleanStdOut()
expect(mockOraObject.stop).toHaveBeenCalled()
})
test('instance methods definitions', async () => {
const consoleCli = await LibConsoleCli.init(consoleCredentials, {})
// rd console api methods
expect(typeof consoleCli.getEnabledServicesForOrg).toBe('function')
expect(typeof consoleCli.getFirstEntpCredentials).toBe('function')
expect(typeof consoleCli.getFirstOAuthServerToServerCredentials).toBe('function')
expect(typeof consoleCli.getOrganizations).toBe('function')
expect(typeof consoleCli.getProjects).toBe('function')
expect(typeof consoleCli.getProject).toBe('function')
expect(typeof consoleCli.getApplicationExtensions).toBe('function')
expect(typeof consoleCli.getWorkspaces).toBe('function')
expect(typeof consoleCli.getServicePropertiesFromWorkspace).toBe('function')
expect(typeof consoleCli.getServicePropertiesFromWorkspaceWithCredentialType).toBe('function')
expect(typeof consoleCli.getWorkspaceConfig).toBe('function')
expect(typeof consoleCli.getBindingsForWorkspace).toBe('function')
expect(typeof consoleCli.getCertificateFingerprint).toBe('function')
expect(typeof consoleCli.getFirstWorkspaceCredential).toBe('function')
// wr console api methods
expect(typeof consoleCli.subscribeToServices).toBe('function')
expect(typeof consoleCli.subscribeToServicesWithCredentialType).toBe('function')
expect(typeof consoleCli.createEnterpriseCredentials).toBe('function')
expect(typeof consoleCli.createOAuthServerToServerCredentials).toBe('function')
expect(typeof consoleCli.createProject).toBe('function')
expect(typeof consoleCli.createWorkspace).toBe('function')
expect(typeof consoleCli.uploadAndBindCertificateToWorkspace).toBe('function')
expect(typeof consoleCli.deleteBindingFromWorkspace).toBe('function')
// prompt methods
expect(typeof consoleCli.promptForSelectServiceProperties).toBe('function')
expect(typeof consoleCli.promptForServiceSubscriptionsOperation).toBe('function')
expect(typeof consoleCli.promptForRemoveServiceSubscriptions).toBe('function')
expect(typeof consoleCli.promptForCreateProjectDetails).toBe('function')
expect(typeof consoleCli.promptForCreateWorkspaceDetails).toBe('function')
expect(typeof consoleCli.promptForSelectOrganization).toBe('function')
expect(typeof consoleCli.promptForSelectProject).toBe('function')
expect(typeof consoleCli.promptForSelectWorkspace).toBe('function')
expect(typeof consoleCli.confirmNewServiceSubscriptions).toBe('function')
})
describe('instance methods tests', () => {
/** @type {LibConsoleCli} */
let consoleCli
beforeEach(async () => {
consoleCli = await LibConsoleCli.init(consoleCredentials)
})
test('getOrganizations', async () => {
const organizations = await consoleCli.getOrganizations()
expect(organizations).toEqual(dataMocks.organizations)
expect(mockConsoleSDKInstance.getOrganizations).toHaveBeenCalled()
expect(mockOraObject.start).toHaveBeenCalled()
expect(mockOraObject.stop).toHaveBeenCalled()
})
test('getProjects', async () => {
const projects = await consoleCli.getProjects('orgid')
expect(projects).toEqual(dataMocks.projects)
expect(mockConsoleSDKInstance.getProjectsForOrg).toHaveBeenCalledWith('orgid')
expect(mockOraObject.start).toHaveBeenCalled()
expect(mockOraObject.stop).toHaveBeenCalled()
})
test('getProject', async () => {
const project = await consoleCli.getProject('orgid', dataMocks.project.id)
expect(project).toEqual(dataMocks.project)
expect(mockConsoleSDKInstance.getProject).toHaveBeenCalledWith('orgid', dataMocks.project.id)
expect(mockOraObject.start).toHaveBeenCalled()
expect(mockOraObject.stop).toHaveBeenCalled()
})
test('getApplicationExtensions', async () => {
const applicationExtensions = await consoleCli.getApplicationExtensions('orgid', 'appid')
expect(applicationExtensions).toEqual(dataMocks.applicationExtensions.data)
expect(mockConsoleSDKInstance.getApplicationExtensions).toHaveBeenCalledWith('orgid', 'appid')
expect(mockOraObject.start).toHaveBeenCalled()
expect(mockOraObject.stop).toHaveBeenCalled()
})
test('getWorkspaces', async () => {
const workspace = await consoleCli.getWorkspaces('orgid', 'projectid')
expect(workspace).toEqual(dataMocks.workspaces)
expect(mockConsoleSDKInstance.getWorkspacesForProject).toHaveBeenCalledWith('orgid', 'projectid')
expect(mockOraObject.start).toHaveBeenCalled()
expect(mockOraObject.stop).toHaveBeenCalled()
})
test('getEnabledServicesForOrg', async () => {
const services = await consoleCli.getEnabledServicesForOrg('orgid')
expect(services).toEqual(dataMocks.enabledServices)
expect(mockConsoleSDKInstance.getServicesForOrg).toHaveBeenCalledWith('orgid')
expect(mockOraObject.start).toHaveBeenCalled()
expect(mockOraObject.stop).toHaveBeenCalled()
})
test('createProject', async () => {
// fresh project, mock workspaces to be only prod and stage
mockConsoleSDKInstance.getWorkspacesForProject.mockResolvedValue({
body: [
dataMocks.workspaces[0],
dataMocks.workspaces[1]
]
})
// project details can be whatever, in the end the returned project is mocked from getProject
const project = await consoleCli.createProject(dataMocks.org.id, { name: 'name', title: 'title', description: 'description' })
expect(project).toEqual(dataMocks.project)
expect(mockConsoleSDKInstance.createProject).toHaveBeenCalledWith(
dataMocks.org.id,
{ name: 'name', title: 'title', description: 'description', type: 'jaeger' }
)
// create additional needed resources
expect(mockConsoleSDKInstance.createWorkspace).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
{ name: 'Stage' }
)
expect(mockConsoleSDKInstance.createRuntimeNamespace).toHaveBeenCalledTimes(2)
expect(mockConsoleSDKInstance.createRuntimeNamespace).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspaces[0].id
)
expect(mockConsoleSDKInstance.createRuntimeNamespace).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspaces[1].id
)
})
test('createWorkspace', async () => {
// workspace details can be whatever, in the end the returned workspace is mocked from getWorkspace
const workspace = await consoleCli.createWorkspace(dataMocks.org.id, dataMocks.project.id, { name: 'name', title: 'title' })
expect(workspace).toEqual(dataMocks.workspace)
expect(mockConsoleSDKInstance.createWorkspace).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
{ name: 'name', title: 'title' }
)
expect(mockConsoleSDKInstance.createRuntimeNamespace).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
describe('subscribeToServicesWithCredentialType', () => {
const orgId = 'org-123'
const projectId = 'project-456'
const workspaceId = 'workspace-789'
describe('both OAuth and JWT creds exist - no new creds created', () => {
// one oauths2s, and one jwt credential, don't create (Oauth has precedent, use OAuth)
const integrations = [
{
id_integration: '121212',
id_workspace: workspaceId,
integration_type: 'oauth_server_to_server',
flow_type: 'entp'
},
{
id_integration: '232323',
id_workspace: workspaceId,
integration_type: 'service',
flow_type: 'entp'
}
]
beforeEach(() => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: integrations })
})
test('select JWT, use existing OAuth (precedent)', async () => {
const ret = await consoleCli.subscribeToServices(
orgId,
{ id: projectId },
{ id: workspaceId },
'certdir',
dataMocks.serviceProperties
)
expect(ret).toEqual(dataMocks.subscribeServicesResponse)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId
)
expect(mockConsoleSDKInstance.createEnterpriseCredential).not.toHaveBeenCalled()
expect(mockConsoleSDKInstance.createOAuthServerToServerCredential).not.toHaveBeenCalled()
// since OAuth cred available, we use that cred
expect(mockConsoleSDKInstance.subscribeCredentialToServices).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
integrations[0].integration_type,
integrations[0].id_integration,
dataMocks.subscribeServicesPayload
)
})
test('select OAuth, use existing OAuth (precedent)', async () => {
const ret = await consoleCli.subscribeToServicesWithCredentialType({
orgId,
project: { id: projectId },
workspace: { id: workspaceId },
credentialType: LibConsoleCli.OAUTH_SERVER_TO_SERVER_CREDENTIAL,
serviceProperties: dataMocks.serviceProperties
})
expect(ret).toEqual(dataMocks.subscribeServicesResponseOAuthServerToServer)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId
)
expect(mockConsoleSDKInstance.createEnterpriseCredential).not.toHaveBeenCalled()
expect(mockConsoleSDKInstance.createOAuthServerToServerCredential).not.toHaveBeenCalled()
// existing OAuth creds take precedence
expect(mockConsoleSDKInstance.subscribeCredentialToServices).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
integrations[0].integration_type,
integrations[0].id_integration,
dataMocks.subscribeServicesPayload
)
})
})
describe('only one JWT cred exists - no new creds created', () => {
// only one jwt credential
const integrations = [
{
id_integration: '232323',
id_workspace: dataMocks.workspace.id,
integration_type: 'service',
flow_type: 'entp'
}
]
beforeEach(() => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: integrations })
})
test('select JWT, use existing JWT', async () => {
const ret = await consoleCli.subscribeToServices(
orgId,
{ id: projectId },
{ id: workspaceId },
'certdir',
dataMocks.serviceProperties
)
expect(ret).toEqual(dataMocks.subscribeServicesResponse)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId
)
expect(mockConsoleSDKInstance.createEnterpriseCredential).not.toHaveBeenCalled()
expect(mockConsoleSDKInstance.createOAuthServerToServerCredential).not.toHaveBeenCalled()
// only JWT cred is available, we use that cred
expect(mockConsoleSDKInstance.subscribeCredentialToServices).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
integrations[0].flow_type,
integrations[0].id_integration,
dataMocks.subscribeServicesPayload
)
})
test('select OAuth, use existing JWT', async () => {
const ret = await consoleCli.subscribeToServicesWithCredentialType({
orgId,
project: { id: projectId },
workspace: { id: workspaceId },
credentialType: LibConsoleCli.OAUTH_SERVER_TO_SERVER_CREDENTIAL,
serviceProperties: dataMocks.serviceProperties
})
expect(ret).toEqual(dataMocks.subscribeServicesResponseOAuthServerToServer)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId
)
expect(mockConsoleSDKInstance.createEnterpriseCredential).not.toHaveBeenCalled()
expect(mockConsoleSDKInstance.createOAuthServerToServerCredential).not.toHaveBeenCalled()
// only JWT creds exist, use existing cred
expect(mockConsoleSDKInstance.subscribeCredentialToServices).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
integrations[0].flow_type,
integrations[0].id_integration,
dataMocks.subscribeServicesPayload
)
})
})
describe('no credentials exist - will create', () => {
const jwtCredential = {
id_integration: '232323',
id_workspace: workspaceId,
integration_type: 'service',
flow_type: 'entp'
}
const oauthS2SCredential = {
id_integration: '121212',
id_workspace: workspaceId,
integration_type: 'oauth_server_to_server',
flow_type: 'entp'
}
beforeEach(() => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: [] })
mockConsoleSDKInstance.createEnterpriseCredential.mockResolvedValue({
body: {
id: jwtCredential.id_integration
}
})
mockConsoleSDKInstance.createOAuthServerToServerCredential.mockResolvedValue({
body: {
id: oauthS2SCredential.id_integration
}
})
})
test('select JWT, create JWT', async () => {
const ret = await consoleCli.subscribeToServices(
orgId,
{ id: projectId },
{ id: workspaceId },
'certdir',
dataMocks.serviceProperties
)
expect(ret).toEqual(dataMocks.subscribeServicesResponse)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId
)
expect(mockConsoleSDKInstance.createOAuthServerToServerCredential).not.toHaveBeenCalled()
expect(mockConsoleSDKInstance.createEnterpriseCredential).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
'fake read stream',
`aio-${workspaceId}`,
'Auto generated enterprise credentials from aio CLI'
)
expect(mockConsoleSDKInstance.subscribeCredentialToServices).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
jwtCredential.flow_type,
jwtCredential.id_integration,
dataMocks.subscribeServicesPayload
)
})
test('select OAuth, create OAuth', async () => {
const ret = await consoleCli.subscribeToServicesWithCredentialType({
orgId,
project: { id: projectId },
workspace: { id: workspaceId },
credentialType: LibConsoleCli.OAUTH_SERVER_TO_SERVER_CREDENTIAL,
serviceProperties: dataMocks.serviceProperties
})
expect(ret).toEqual(dataMocks.subscribeServicesResponseOAuthServerToServer)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId
)
expect(mockConsoleSDKInstance.createEnterpriseCredential).not.toHaveBeenCalled()
expect(mockConsoleSDKInstance.createOAuthServerToServerCredential).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
`aio-${workspaceId}`,
'Auto generated enterprise credentials from aio CLI'
)
expect(mockConsoleSDKInstance.subscribeCredentialToServices).toHaveBeenCalledWith(
orgId,
projectId,
workspaceId,
oauthS2SCredential.integration_type,
oauthS2SCredential.id_integration,
dataMocks.subscribeServicesPayload
)
})
})
})
describe('getServicesProperties', () => {
test('no integration in workspace', async () => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: [] })
const ret = await consoleCli.getServicePropertiesFromWorkspace(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace,
dataMocks.services
)
expect(ret).toEqual([])
expect(mockConsoleSDKInstance.getIntegration).not.toHaveBeenCalled()
})
test('no integration in workspace (no services)', async () => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: [] })
const ret = await consoleCli.getServicePropertiesFromWorkspace(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace
)
expect(ret).toEqual([])
expect(mockConsoleSDKInstance.getIntegration).not.toHaveBeenCalled()
})
test('(oauth-server-to-server) no integration in workspace', async () => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: [] })
const ret = await consoleCli.getServicePropertiesFromWorkspaceWithCredentialType({
orgId: dataMocks.org.id,
projectId: dataMocks.project.id,
workspace: dataMocks.workspace,
supportedServices: dataMocks.services,
credentialType: LibConsoleCli.OAUTH_SERVER_TO_SERVER_CREDENTIAL
}
)
expect(ret).toEqual([])
expect(mockConsoleSDKInstance.getIntegration).not.toHaveBeenCalled()
})
test('no services attached to integration in workspace', async () => {
mockConsoleSDKInstance.getIntegration.mockResolvedValue({ body: { serviceProperties: [] } })
const ret = await consoleCli.getServicePropertiesFromWorkspace(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id,
dataMocks.services
)
expect(ret).toEqual([])
expect(mockConsoleSDKInstance.getIntegration).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.integration.id
)
})
test('no support services', async () => {
// default getIntegration mock returns dataMocks.integration
const ret = await consoleCli.getServicePropertiesFromWorkspace(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
expect(ret).toEqual(dataMocks.serviceProperties)
expect(mockConsoleSDKInstance.getIntegration).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.integration.id
)
})
test('some services attached to integration in workspace', async () => {
// default getIntegration mock returns dataMocks.integration
const ret = await consoleCli.getServicePropertiesFromWorkspace(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id,
dataMocks.services
)
expect(ret).toEqual(dataMocks.serviceProperties)
expect(mockConsoleSDKInstance.getIntegration).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.integration.id
)
})
test('some services attached to integration in workspace - test console workarounds', async () => {
const allLicenseConfigs = dataMocks.serviceProperties
.filter(sp => !!sp.licenseConfigs)
.map(sp => sp.licenseConfigs)
// flatten the array
.reduce((flat, arr) => flat.concat(arr), [])
const brokenServiceProperties = dataMocks.serviceProperties
.map(sp => ({ ...sp, licenseConfigs: allLicenseConfigs }))
mockConsoleSDKInstance.getIntegration.mockResolvedValue({ body: { serviceProperties: brokenServiceProperties } })
const ret = await consoleCli.getServicePropertiesFromWorkspace(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id,
dataMocks.services
)
// 1. make sure serviceProperties are fixed
expect(ret).toEqual(dataMocks.serviceProperties)
expect(mockConsoleSDKInstance.getIntegration).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.integration.id
)
// 2. make sure getSDKProperties is called to fix caching bug
expect(mockConsoleSDKInstance.getSDKProperties).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.integration.id,
expect.any(String)
)
})
})
test('createEnterpriseCredentials', async () => {
const ret = await consoleCli.createEnterpriseCredentials(
dataMocks.org.id,
dataMocks.project,
dataMocks.workspace,
'certdir'
)
expect(ret).toEqual(dataMocks.integrationCreateResponse)
expect(mockConsoleSDKInstance.createEnterpriseCredential).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id,
'fake read stream',
`aio-${dataMocks.workspace.id}`,
'Auto generated enterprise credentials from aio CLI'
)
// make sure keys are written at the right place
expect(fs.writeFileSync).toHaveBeenCalledTimes(2)
const dir = `certdir${path.sep}${dataMocks.org.id}-${dataMocks.project.name}`
expect(fs.ensureDirSync).toHaveBeenCalledWith(dir)
expect(fs.writeFileSync).toHaveBeenCalledWith(
`${dir}${path.sep}${dataMocks.workspace.name}.pem`,
'fake public key'
)
expect(fs.writeFileSync).toHaveBeenCalledWith(
`${dir}${path.sep}${dataMocks.workspace.name}.key`,
'fake private key'
)
})
describe('getFirstEntpCredentials', () => {
test('when there is one', async () => {
// relies on default mock for getCredentials
const ret = await consoleCli.getFirstEntpCredentials(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace
)
expect(ret).toEqual(dataMocks.integrations[2])
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
test('when there are none', async () => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: [] })
const ret = await consoleCli.getFirstEntpCredentials(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace
)
expect(ret).toEqual(undefined)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
})
describe('getFirstWorkspaceCredential', () => {
test('returns OAuth credentials when available', async () => {
const ret = await consoleCli.getFirstWorkspaceCredential(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace
)
expect(ret).toEqual(dataMocks.integrations[4])
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
test('returns JWT credentials when OAuth credentials are not available', async () => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: dataMocks.integrations.slice(0, 3) })
const ret = await consoleCli.getFirstWorkspaceCredential(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace
)
expect(ret).toEqual(dataMocks.integrations[2])
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
test('returns undefined when no credentials are available', async () => {
mockConsoleSDKInstance.getCredentials.mockResolvedValue({ body: [] })
const ret = await consoleCli.getFirstWorkspaceCredential(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace
)
expect(ret).toEqual(undefined)
expect(mockConsoleSDKInstance.getCredentials).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
})
describe('getWorkspaceConfig', () => {
test('with supported services', async () => {
// relies on default mock for getCredentials
const ret = await consoleCli.getWorkspaceConfig(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id,
dataMocks.services
)
expect(ret).toEqual(dataMocks.enhancedWorkspaceJson)
expect(mockConsoleSDKInstance.downloadWorkspaceJson).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
test('without supported services', async () => {
// relies on default mock for getCredentials
const ret = await consoleCli.getWorkspaceConfig(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
expect(ret).toEqual(dataMocks.workspaceJson)
expect(mockConsoleSDKInstance.downloadWorkspaceJson).toHaveBeenCalledWith(
dataMocks.org.id,
dataMocks.project.id,
dataMocks.workspace.id
)
})
})
describe('promptForSelectOrganization', () => {
test('prompts with list of orgs', async () => {
mockPrompt.promptSelect.mockResolvedValue(dataMocks.org)
const res = await consoleCli.promptForSelectOrganization(dataMocks.organizations)
expect(res).toEqual(dataMocks.org)
expect(mockPrompt.promptSelect).toHaveBeenCalledWith('Org', dataMocks.promptChoices.orgs)
})
test('with preselected org id that matches an entity', async () => {
const res = await consoleCli.promptForSelectOrganization(dataMocks.organizations, { orgId: dataMocks.org.id })
expect(res).toEqual(dataMocks.org)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
})
test('with preselected org code that matches an entity', async () => {
const res = await consoleCli.promptForSelectOrganization(dataMocks.organizations, { orgCode: dataMocks.org.code })
expect(res).toEqual(dataMocks.org)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
})
test('with preselected id and org code that match same entity', async () => {
const res = await consoleCli.promptForSelectOrganization(dataMocks.organizations, { orgId: dataMocks.org.id, orgCode: dataMocks.org.code })
expect(res).toEqual(dataMocks.org)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
})
test('with preselected id that could be org code that matches an entity', async () => {
const res = await consoleCli.promptForSelectOrganization(dataMocks.organizations, { orgId: dataMocks.org.id, orgCode: dataMocks.org.id })
expect(res).toEqual(dataMocks.org)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
})
test('with preselected org code that could be id that matches an entity', async () => {
const res = await consoleCli.promptForSelectOrganization(dataMocks.organizations, { orgId: dataMocks.org.code, orgCode: dataMocks.org.code })
expect(res).toEqual(dataMocks.org)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
})
test('with preselected org code that does not match an entity', async () => {
await expect(consoleCli.promptForSelectOrganization(dataMocks.organizations, { orgId: 'idontexist' }))
.rejects.toThrow('Organization \'idontexist\' not found.')
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
})
test('with preselected org id and org code that match two different orgs', async () => {
await expect(consoleCli.promptForSelectOrganization(dataMocks.organizations, { orgId: dataMocks.organizations[0].id, orgCode: dataMocks.organizations[1].code }))
.rejects.toThrow("Organization code '22222222226666666666DDDD@AdobeOrg' and id '12345' do not refer to the same Organization.")
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
})
})
describe('promptForSelectProject', () => {
test('prompts with list of projects', async () => {
mockPrompt.promptSelect.mockResolvedValue(dataMocks.project)
const res = await consoleCli.promptForSelectProject(dataMocks.projects)
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).toHaveBeenCalledWith('Project', dataMocks.promptChoices.projects)
})
test('prompts with list of projects allowCreate', async () => {
mockPrompt.promptSelectOrCreate.mockResolvedValue(dataMocks.project)
const res = await consoleCli.promptForSelectProject(dataMocks.projects, {}, { allowCreate: true })
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).toHaveBeenCalledWith('Project', dataMocks.promptChoices.projects)
})
test('prompts with list of projects allowCreate and escape selection', async () => {
mockPrompt.promptSelectOrCreate.mockResolvedValue(null)
const res = await consoleCli.promptForSelectProject(dataMocks.projects, {}, { allowCreate: true })
expect(res).toEqual(null)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).toHaveBeenCalledWith('Project', dataMocks.promptChoices.projects)
})
test('with preselected id that matches an entity', async () => {
const res = await consoleCli.promptForSelectProject(dataMocks.projects, { projectId: dataMocks.project.id })
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected name that matches an entity', async () => {
const res = await consoleCli.promptForSelectProject(dataMocks.projects, { projectName: dataMocks.project.name })
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id and name that match the same entity', async () => {
const res = await consoleCli.promptForSelectProject(dataMocks.projects, { projectId: dataMocks.project.id, projectName: dataMocks.project.name })
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id that could be name that matches an entity', async () => {
const res = await consoleCli.promptForSelectProject(dataMocks.projects, { projectId: dataMocks.project.id, projectName: dataMocks.project.id })
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected name that could be id that matches an entity', async () => {
const res = await consoleCli.promptForSelectProject(dataMocks.projects, { projectId: dataMocks.project.id, projectName: dataMocks.project.id })
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id that does not match an entity, allowCreate = false', async () => {
await expect(consoleCli.promptForSelectProject(dataMocks.projects, { projectId: 'idontexist' }, { allowCreate: false }))
.rejects.toThrow('Project \'idontexist\' not found')
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id that does not match an entity, allowCreate = true', async () => {
await expect(consoleCli.promptForSelectProject(dataMocks.projects, { projectId: 'idontexist' }, { allowCreate: true }))
.resolves.toEqual(undefined)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id and preselected name that exists but point to two different projects', async () => {
await expect(consoleCli.promptForSelectProject(dataMocks.projects, { projectId: dataMocks.projects[0].id, projectName: dataMocks.projects[1].name }))
.rejects.toThrow("Project name 'mySecondProject' and id '1234567890123456789' do not refer to the same Project.")
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
})
describe('promptForSelectWorkspace', () => {
test('prompts with list of workspaces', async () => {
mockPrompt.promptSelect.mockResolvedValue(dataMocks.workspace)
const res = await consoleCli.promptForSelectWorkspace(dataMocks.workspaces)
expect(res).toEqual(dataMocks.workspace)
expect(mockPrompt.promptSelect).toHaveBeenCalledWith('Workspace', dataMocks.promptChoices.workspaces)
})
test('prompts with list of workspaces allowCreate', async () => {
mockPrompt.promptSelectOrCreate.mockResolvedValue(dataMocks.workspace)
const res = await consoleCli.promptForSelectWorkspace(dataMocks.workspaces, {}, { allowCreate: true })
expect(res).toEqual(dataMocks.workspace)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).toHaveBeenCalledWith('Workspace', dataMocks.promptChoices.workspaces)
})
test('prompts with list of workspaces allowCreate and escape selection', async () => {
mockPrompt.promptSelectOrCreate.mockResolvedValue(null)
const res = await consoleCli.promptForSelectWorkspace(dataMocks.workspaces, {}, { allowCreate: true })
expect(res).toEqual(null)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).toHaveBeenCalledWith('Workspace', dataMocks.promptChoices.workspaces)
})
test('with preselected id that matches an entity', async () => {
const res = await consoleCli.promptForSelectWorkspace(dataMocks.workspaces, { workspaceId: dataMocks.workspace.id })
expect(res).toEqual(dataMocks.workspace)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected name that matches an entity', async () => {
const res = await consoleCli.promptForSelectWorkspace(dataMocks.workspaces, { workspaceName: dataMocks.workspace.name })
expect(res).toEqual(dataMocks.workspace)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id and name that match the same entity', async () => {
const res = await consoleCli.promptForSelectWorkspace(dataMocks.workspaces, { workspaceId: dataMocks.workspace.id, workspaceName: dataMocks.workspace.name })
expect(res).toEqual(dataMocks.workspace)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id that could be name that matches an entity', async () => {
const res = await consoleCli.promptForSelectWorkspace(dataMocks.workspaces, { workspaceId: dataMocks.workspace.id, workspaceName: dataMocks.workspace.id })
expect(res).toEqual(dataMocks.workspace)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected name that could be id that matches an entity', async () => {
const res = await consoleCli.promptForSelectProject(dataMocks.projects, { projectId: dataMocks.project.name, projectName: dataMocks.project.name })
expect(res).toEqual(dataMocks.project)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id that does not match an entity, allowCreate = true', async () => {
await expect(consoleCli.promptForSelectWorkspace(dataMocks.workspaces, { workspaceId: 'idontexist' }, { allowCreate: true }))
.resolves.toEqual(undefined)
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id that does not match an entity, allowCreate = false', async () => {
await expect(consoleCli.promptForSelectWorkspace(dataMocks.workspaces, { workspaceId: 'idontexist' }, { allowCreate: false }))
.rejects.toThrow('Workspace \'idontexist\' not found')
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
test('with preselected id and preselected name that exists but point to two different workspaces', async () => {
await expect(consoleCli.promptForSelectWorkspace(dataMocks.workspaces, { workspaceId: dataMocks.workspaces[0].id, workspaceName: dataMocks.workspaces[1].name }))
.rejects.toThrow("Workspace name 'Stage' and id '1111111111111111111' do not refer to the same Workspace.")
expect(mockPrompt.promptSelect).not.toHaveBeenCalled()
expect(mockPrompt.promptSelectOrCreate).not.toHaveBeenCalled()
})
})
test('promptForCreateProjectDetails', async () => {
mockPrompt.promptInput.mockResolvedValueOnce('name')
mockPrompt.promptInput.mockResolvedValueOnce('title')
mockPrompt.promptInput.mockResolvedValueOnce('description')
const res = await consoleCli.promptForCreateProjectDetails()
expect(res).toEqual({
name: 'name', title: 'title', description: 'description'
})
expect(mockPrompt.promptInput).toHaveBeenCalledTimes(3)
expect(mockPrompt.promptInput.mock.calls[0])
.toEqual(['Name', { validate: validators.validateProjectName }])
expect(mockPrompt.promptInput.mock.calls[1])
.toEqual(['Title', { validate: validators.validateProjectTitle }])
expect(mockPrompt.promptInput.mock.calls[2])
.toEqual(['Description', { validate: validators.validateProjectDescription, default: '' }])
})
test('promptForCreateWorkspaceDetails', async () => {
mockPrompt.promptInput.mockResolvedValueOnce('name')
mockPrompt.promptInput.mockResolvedValueOnce('title')
const res = await consoleCli.promptForCreateWorkspaceDetails()
expect(res).toEqual({
name: 'name', title: 'title'
})
expect(mockPrompt.promptInput).toHaveBeenCalledTimes(2)
expect(mockPrompt.promptInput.mock.calls[0])
.toEqual(['Name', { validate: validators.validateWorkspaceName }])
expect(mockPrompt.promptInput.mock.calls[1])
.toEqual(['Title', { validate: validators.validateWorkspaceTitle, default: '' }])
})
describe('promptForSelectServiceProperties', () => {
test('select services', async () => {
// selected services
const selectedServices = dataMocks.services.filter(s => dataMocks.integration.sdkList.includes(s.code))
mockPrompt.promptMultiSelect.mockResolvedValueOnce(selectedServices)
// for each service select some licenseConfigs
dataMocks.integration.serviceProperties.forEach(s => {
mockPrompt.promptMultiSelect.mockResolvedValueOnce(s.licenseConfigs)
})
const res = await consoleCli.promptForSelectServiceProperties(dataMocks.workspace.name, dataMocks.services)
expect(res).toEqual(dataMocks.integration.serviceProperties)
expect(mockPrompt.promptMultiSelect).toHaveBeenCalledWith(
`Add Services to Workspace ${dataMocks.workspace.name}`,
dataMocks.promptChoices.services,
{ validate: validators.atLeastOne }
)
dataMocks.integration.serviceProperties.forEach((s, i) => {
if (s.licenseConfigs) {
// eslint-disable-next-line jest/no-conditional-expect
expect(mockPrompt.promptMultiSelect).toHaveBeenCalledWith(
`Select Product Profiles for the service '${s.name}'`,
dataMocks.promptChoices.licenseConfigs[i],
{ validate: validators.atLeastOne }
)
}
})
})
test('no selection + workspace name is an array', async () => {
// selected services
mockPrompt.promptMultiSelect.mockResolvedValueOnce([])
const res = await consoleCli.promptForSelectServiceProperties(['wname1', 'wname2'], dataMocks.services)
expect(res).toEqual([])
expect(mockPrompt.promptMultiSelect).toHaveBeenCalledWith(
'Add Services to Workspaces wname1 and wname2',
dataMocks.promptChoices.services,
{ validate: validators.atLeastOne }
)
expect(mockPrompt.promptMultiSelect).toHaveBeenCalledTimes(1) // no licenseConfigs selections
})
})
describe('confirmNewServiceSubscriptions', () => {
test('yes', async () => {
mockPrompt.promptConfirm.mockResolvedValue(true)
const res = await consoleCli.confirmNewServiceSubscriptions('workspacename', dataMocks.serviceProperties)
expect(res).toBe(true)
expect(mockPrompt.promptConfirm).toHaveBeenCalledTimes(1)
// make sure user sees a list of services and workspacename before confirming
expect(mockPrompt.promptConfirm.mock.calls[0][0]).toEqual(expect.stringContaining('Workspace workspacename'))
expect(mockPrompt.promptConfirm.mock.calls[0][0]).toEqual(expect.stringContaining(JSON.stringify(dataMocks.serviceProperties.map(s => s.name), null, 4)))
})
test('no', async () => {
mockPrompt.promptConfirm.mockResolvedValue(false)
const res = await consoleCli.confirmNewServiceSubscriptions('workspacename', dataMocks.serviceProperties)
expect(res).toBe(false)
expect(mockPrompt.promptConfirm).toHaveBeenCalledTimes(1)
})
test('with array input', async () => {
mockPrompt.promptConfirm.mockResolvedValue(true)
const res = await consoleCli.confirmNewServiceSubscriptions(['w1', 'w2'], dataMocks.serviceProperties)
expect(res).toBe(true)
expect(mockPrompt.promptConfirm.mock.calls[0][0]).toEqual(expect.stringContaining('Workspaces w1 and w2'))
})
})
describe('promptForServiceSubscriptionsOperation', () => {
test('cloneChoice=false and nopChoice=false', async () => {
const res = await consoleCli.promptForServiceSubscriptionsOperation('workspacename', { cloneChoice: false, nopChoice: false })
expect(res).toEqual('select')
expect(mockPrompt.promptChoice).not.toHaveBeenCalled()
})
test('cloneChoice=false (by default) and nopChoice=false', async () => {
const res = await consoleCli.promptForServiceSubscriptionsOperation('workspacename', { nopChoice: false })
expect(res).toEqual('select')
expect(mockPrompt.promptChoice).not.toHaveBeenCalled()
})
test('nopChoice=true', async () => {
mockPrompt.promptChoice.mockReturnValue('avalidchoice')
const res = await consoleCli.promptForServiceSubscriptionsOperation('work