import * as vscode from 'vscode' ; import { ExtensionUtil } from '../../extension/util/ExtensionUtil' ; import { VSCodeBlockchainOutputAdapter } from '../../extension/logging/VSCodeBlockchainOutputAdapter' ; import { BlockchainEnvironmentExplorerProvider } from '../../extension/explorer/environmentExplorer' ; import { BlockchainTreeItem } from '../../extension/explorer/model/BlockchainTreeItem' ; import { RuntimeTreeItem } from '../../extension/explorer/runtimeOps/disconnectedTree/RuntimeTreeItem' ; import { TestUtil } from '../TestUtil' ; import * as chai from 'chai' ; import * as sinon from 'sinon' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { FabricEnvironmentRegistry , FabricRuntimeUtil , LogType , FabricEnvironmentRegistryEntry , FabricGatewayRegistry , EnvironmentFlags } from 'ibm-blockchain-platform-common' ; import { UserInputUtil } from '../../extension/commands/UserInputUtil' ; import { EnvironmentFactory } from '../../extension/fabric/environments/EnvironmentFactory' ; import { ExtensionsInteractionUtil } from '../../extension/util/ExtensionsInteractionUtil' ; import { LocalMicroEnvironment } from '../../extension/fabric/environments/LocalMicroEnvironment' ; chai . should ( ) ; describe ( 'startFabricRuntime' , ( ) => { const sandbox = sinon . createSandbox ( ) ; const connectionRegistry = FabricGatewayRegistry . instance ( ) ; let mockLocalRuntime ; let runtimeTreeItem ; let blockchainLogsOutputSpy ; let commandStub ; let logSpy ; let popupStub ; let localRegistryEntry ; let showFabricEnvironmentQuickPickBoxStub ; let getEnvironmentStub ; before ( async ( ) => { await TestUtil . setupTests ( sandbox ) ; } ) ; beforeEach ( async ( ) => { await connectionRegistry . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await TestUtil . setupLocalFabric ( ) ; mockLocalRuntime = sandbox . createStubInstance ( LocalMicroEnvironment ) ; mockLocalRuntime . isCreated . resolves ( true ) ; mockLocalRuntime . numberOfOrgs = 1 ; mockLocalRuntime . create . resolves ( ) ; mockLocalRuntime . start . resolves ( ) ; mockLocalRuntime . startLogs . resolves ( ) ; mockLocalRuntime . getName . returns ( FabricRuntimeUtil . LOCAL_FABRIC ) ; mockLocalRuntime . start . resolves ( ) ; mockLocalRuntime . waitFor . resolves ( true ) ; blockchainLogsOutputSpy = sandbox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'show' ) ; sandbox . stub ( ExtensionsInteractionUtil , 'cloudAccountIsLoggedIn' ) . resolves ( false ) ; sandbox . stub ( ExtensionsInteractionUtil , 'cloudAccountHasSelectedAccount' ) . resolves ( false ) ; const provider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const children = await provider . getChildren ( ) ; const groupChildren = await provider . getChildren ( children [ 0 ] ) ; runtimeTreeItem = groupChildren . find ( ( child ) => child instanceof RuntimeTreeItem ) as RuntimeTreeItem ; commandStub = sandbox . stub ( vscode . commands , 'executeCommand' ) . callThrough ( ) ; commandStub . withArgs ( ExtensionCommands . CONNECT_TO_ENVIRONMENT ) . resolves ( ) ; logSpy = sandbox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; popupStub = sandbox . stub ( UserInputUtil , 'failedNetworkStart' ) . resolves ( ) ; localRegistryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( FabricRuntimeUtil . LOCAL_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub = sandbox . stub ( UserInputUtil , 'showFabricEnvironmentQuickPickBox' ) ; showFabricEnvironmentQuickPickBoxStub . resolves ( { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localRegistryEntry } ) ; getEnvironmentStub = sandbox . stub ( EnvironmentFactory , 'getEnvironment' ) ; } ) ; afterEach ( async ( ) => { sandbox . restore ( ) ; await connectionRegistry . clear ( ) ; } ) ; it ( 'should do nothing and report a warning on Eclipse Che' , async ( ) => { sandbox . stub ( ExtensionUtil , 'isChe' ) . returns ( true ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC ) ; logSpy . should . have . been . calledWithExactly ( LogType . ERROR , sinon . match ( /not supported/ ) ) ; } ) ; it ( 'should start a Fabric runtime specified by clicking the tree' , async ( ) => { await vscode . commands . executeCommand ( runtimeTreeItem . command . command ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . CONNECT_TO_ENVIRONMENT ) ; } ) ; it ( 'should start a Local environment from the command palette if created' , async ( ) => { mockLocalRuntime . isCreated . resolves ( true ) ; getEnvironmentStub . returns ( mockLocalRuntime ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Select an environment to start' , false , true , [ EnvironmentFlags . LOCAL ] , [ ] , false ) ; mockLocalRuntime . create . should . not . have . been . called ; mockLocalRuntime . start . should . have . been . called . calledOnceWithExactly ( VSCodeBlockchainOutputAdapter . instance ( ) ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_GATEWAYS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_WALLETS ) ; blockchainLogsOutputSpy . should . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , 'startFabricRuntime' ) ; } ) ; it ( 'should return if user doesnt select an environment to start' , async ( ) => { showFabricEnvironmentQuickPickBoxStub . resolves ( undefined ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Select an environment to start' , false , true , [ EnvironmentFlags . LOCAL ] , [ ] , false ) ; getEnvironmentStub . should . not . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , 'startFabricRuntime' ) ; } ) ; it ( 'should create and start a local microfab environment' , async ( ) => { mockLocalRuntime . isCreated . resolves ( false ) ; getEnvironmentStub . returns ( mockLocalRuntime ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Select an environment to start' , false , true , [ EnvironmentFlags . LOCAL ] , [ ] , false ) ; mockLocalRuntime . create . should . have . been . calledOnce ; mockLocalRuntime . start . should . have . been . called . calledOnceWithExactly ( VSCodeBlockchainOutputAdapter . instance ( ) ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_GATEWAYS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_WALLETS ) ; blockchainLogsOutputSpy . should . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , 'startFabricRuntime' ) ; } ) ; it ( 'should error if environment fails to come alive' , async ( ) => { const error = new Error ( 'Environment failed to become available. Please check the Docker container logs for more details.' ) ; mockLocalRuntime . isCreated . resolves ( false ) ; mockLocalRuntime . waitFor . resolves ( false ) ; getEnvironmentStub . returns ( mockLocalRuntime ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Select an environment to start' , false , true , [ EnvironmentFlags . LOCAL ] , [ ] , false ) ; mockLocalRuntime . create . should . have . been . calledOnce ; mockLocalRuntime . start . should . have . been . called . calledOnceWithExactly ( VSCodeBlockchainOutputAdapter . instance ( ) ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_GATEWAYS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_WALLETS ) ; blockchainLogsOutputSpy . should . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , 'startFabricRuntime' ) ; popupStub . should . have . been . calledWithExactly ( `Failed to start ${ mockLocalRuntime . getName ( ) }: ${ error . message }` , `Failed to start ${ mockLocalRuntime . getName ( ) }: ${ error . toString ( ) }` ) ; } ) ; it ( 'should be able to pass in an environment registry' , async ( ) => { mockLocalRuntime . isCreated . resolves ( false ) ; getEnvironmentStub . returns ( mockLocalRuntime ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC , localRegistryEntry ) ; showFabricEnvironmentQuickPickBoxStub . should . not . have . been . called ; mockLocalRuntime . create . should . have . been . calledOnce ; mockLocalRuntime . start . should . have . been . called . calledOnceWithExactly ( VSCodeBlockchainOutputAdapter . instance ( ) ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_GATEWAYS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_WALLETS ) ; blockchainLogsOutputSpy . should . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , 'startFabricRuntime' ) ; } ) ; it ( 'should display an error if the environment fails to start' , async ( ) => { const error = new Error ( 'who ate all the cakes?' ) ; mockLocalRuntime . start . rejects ( error ) ; getEnvironmentStub . returns ( mockLocalRuntime ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC ) ; mockLocalRuntime . start . should . have . been . called . calledOnceWithExactly ( VSCodeBlockchainOutputAdapter . instance ( ) ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_GATEWAYS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_WALLETS ) ; blockchainLogsOutputSpy . should . have . been . called ; popupStub . should . have . been . calledWithExactly ( `Failed to start ${ mockLocalRuntime . getName ( ) }: ${ error . message }` , `Failed to start ${ mockLocalRuntime . getName ( ) }: ${ error . toString ( ) }` ) ; } ) ; it ( 'should start a local microfab environment by right-clicking the tree item (emulating)' , async ( ) => { mockLocalRuntime . isCreated . resolves ( true ) ; getEnvironmentStub . returns ( mockLocalRuntime ) ; await vscode . commands . executeCommand ( ExtensionCommands . START_FABRIC_SHORT , runtimeTreeItem ) ; showFabricEnvironmentQuickPickBoxStub . should . not . have . been . called ; mockLocalRuntime . create . should . not . have . been . called ; mockLocalRuntime . start . should . have . been . called . calledOnceWithExactly ( VSCodeBlockchainOutputAdapter . instance ( ) ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_GATEWAYS ) ; commandStub . should . have . been . calledWith ( ExtensionCommands . REFRESH_WALLETS ) ; blockchainLogsOutputSpy . should . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , 'startFabricRuntime' ) ; } ) ; } ) ;