'use strict' ; import * as vscode from 'vscode' ; import * as chai from 'chai' ; import * as sinon from 'sinon' ; import * as sinonChai from 'sinon-chai' ; import { BlockchainTreeItem } from '../../extension/explorer/model/BlockchainTreeItem' ; import { BlockchainEnvironmentExplorerProvider } from '../../extension/explorer/environmentExplorer' ; import { ChannelTreeItem } from '../../extension/explorer/model/ChannelTreeItem' ; import { PeerTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/PeerTreeItem' ; import { ExtensionUtil } from '../../extension/util/ExtensionUtil' ; import { TestUtil } from '../TestUtil' ; import { RuntimeTreeItem } from '../../extension/explorer/runtimeOps/disconnectedTree/RuntimeTreeItem' ; import { LocalMicroEnvironmentManager } from '../../extension/fabric/environments/LocalMicroEnvironmentManager' ; import { VSCodeBlockchainOutputAdapter } from '../../extension/logging/VSCodeBlockchainOutputAdapter' ; import { NodesTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/NodesTreeItem' ; import { OrganizationsTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/OrganizationsTreeItem' ; import { OrgTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/OrgTreeItem' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { MetadataUtil } from '../../extension/util/MetadataUtil' ; import { CertificateAuthorityTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/CertificateAuthorityTreeItem' ; import { OrdererTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/OrdererTreeItem' ; import { FabricEnvironmentConnection } from 'ibm-blockchain-platform-environment-v1' ; import { FabricEnvironmentManager , ConnectedState } from '../../extension/fabric/environments/FabricEnvironmentManager' ; import { FabricEnvironmentRegistry , FabricEnvironmentRegistryEntry , FabricNode , FabricRuntimeUtil , LogType , EnvironmentType , FabricEnvironment , FabricInstalledSmartContract } from 'ibm-blockchain-platform-common' ; import { EnvironmentConnectedTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/EnvironmentConnectedTreeItem' ; import { ImportNodesTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/ImportNodesTreeItem' ; import { LocalMicroEnvironment } from '../../extension/fabric/environments/LocalMicroEnvironment' ; import { CommittedContractTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/CommittedSmartContractTreeItem' ; import { DeployTreeItem } from '../../extension/explorer/runtimeOps/connectedTree/DeployTreeItem' ; import { EnvironmentGroupTreeItem } from '../../extension/explorer/runtimeOps/EnvironmentGroupTreeItem' ; import { ExtensionsInteractionUtil } from '../../extension/util/ExtensionsInteractionUtil' ; import { SettingConfigurations } from '../../extension/configurations' ; import { UserInputUtil } from '../../extension/commands/UserInputUtil' ; chai . use ( sinonChai ) ; const should = chai . should ( ) ; describe ( 'environmentExplorer' , ( ) => { let mySandBox ; before ( async ( ) => { mySandBox = sinon . createSandbox ( ) ; await TestUtil . setupTests ( mySandBox ) ; } ) ; after ( ( ) => { mySandBox . restore ( ) ; } ) ; describe ( 'getChildren' , ( ) => { describe ( 'unconnected tree' , ( ) => { let executeCommandStub ; let loggedInStub ; let accountSelectedStub ; let logSpy ; let isIBMCloudExtensionInstalled ; beforeEach ( async ( ) => { mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getConnection' ) . returns ( undefined ) ; isIBMCloudExtensionInstalled = mySandBox . stub ( ExtensionsInteractionUtil , 'isIBMCloudExtensionInstalled' ) . returns ( true ) ; loggedInStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountIsLoggedIn' ) . resolves ( false ) ; accountSelectedStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountHasSelectedAccount' ) . resolves ( false ) ; logSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should correctly group local environments' , async ( ) => { await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await TestUtil . setupLocalFabric ( ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) ; const mockRuntime = mySandBox . createStubInstance ( LocalMicroEnvironment ) ; mySandBox . stub ( LocalMicroEnvironmentManager . instance ( ) , 'getRuntime' ) . returns ( mockRuntime ) ; mockRuntime . isRunning . resolves ( false ) ; mockRuntime . startLogs . resolves ( ) ; mockRuntime . getName . returns ( FabricRuntimeUtil . LOCAL_FABRIC ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 2 ) ; allChildren [ 0 ] . label . should . equal ( 'Simple local networks' ) ; allChildren [ 0 ] . tooltip . should . equal ( 'Simple local networks' ) ; allChildren [ 0 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; allChildren [ 1 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 1 ] . tooltip . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 1 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; const localEnvItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; localEnvItems . length . should . equal ( 1 ) ; localEnvItems [ 0 ] . label . should . equal ( `${ FabricRuntimeUtil . LOCAL_FABRIC }  ○ (click to start)` ) ; localEnvItems [ 0 ] . tooltip . should . equal ( 'Creates a local development runtime using Hyperledger Fabric Docker images' ) ; localEnvItems [ 0 ] . contextValue . should . equal ( 'blockchain-runtime-item' ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 1 ] ) ; ibmCloudItems . length . should . equal ( 1 ) ; ibmCloudItems [ 0 ] . label . should . equal ( `+ Log in to IBM Cloud` ) ; ibmCloudItems [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . LOG_IN_AND_DISCOVER , title : '' , arguments : [ ] } ) ; loggedInStub . should . have . been . calledTwice ; accountSelectedStub . should . have . been . calledTwice ; anyResourcesStub . should . not . have . been . called ; } ) ; it ( 'should correctly group ibm cloud environments' , async ( ) => { const opsToolsEnv = new FabricEnvironmentRegistryEntry ( ) ; opsToolsEnv . name = 'opsToolsEnv' ; opsToolsEnv . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; const saasEnv = new FabricEnvironmentRegistryEntry ( ) ; saasEnv . name = 'saasEnv' ; saasEnv . environmentType = EnvironmentType . SAAS_OPS_TOOLS_ENVIRONMENT ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . add ( opsToolsEnv ) ; await FabricEnvironmentRegistry . instance ( ) . add ( saasEnv ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 1 ) ; allChildren [ 0 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 0 ] . tooltip . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 0 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; ibmCloudItems . length . should . equal ( 2 ) ; ibmCloudItems [ 0 ] . label . should . equal ( opsToolsEnv . name ) ; ibmCloudItems [ 0 ] . tooltip . should . equal ( opsToolsEnv . name ) ; ibmCloudItems [ 0 ] . contextValue . should . equal ( 'blockchain-ops-environment' ) ; ibmCloudItems [ 1 ] . label . should . equal ( saasEnv . name ) ; ibmCloudItems [ 1 ] . tooltip . should . equal ( saasEnv . name ) ; ibmCloudItems [ 1 ] . contextValue . should . equal ( 'blockchain-ops-environment' ) ; } ) ; it ( `should correctly group 'other' environments` , async ( ) => { const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) ; const otherEnvOne = new FabricEnvironmentRegistryEntry ( ) ; otherEnvOne . name = 'myFabric2' ; otherEnvOne . managedRuntime = false ; otherEnvOne . environmentType = EnvironmentType . ENVIRONMENT ; const otherEnvTwo = new FabricEnvironmentRegistryEntry ( ) ; otherEnvTwo . name = 'myMicrofab' ; otherEnvTwo . environmentType = EnvironmentType . MICROFAB_ENVIRONMENT ; otherEnvTwo . managedRuntime = false ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . add ( otherEnvOne ) ; await FabricEnvironmentRegistry . instance ( ) . add ( otherEnvTwo ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 2 ) ; allChildren [ 0 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 0 ] . tooltip . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 0 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; allChildren [ 1 ] . label . should . equal ( 'Other networks' ) ; allChildren [ 1 ] . tooltip . should . equal ( 'Other networks' ) ; allChildren [ 1 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; const otherItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 1 ] ) ; otherItems . length . should . equal ( 2 ) ; otherItems [ 0 ] . label . should . equal ( otherEnvOne . name ) ; otherItems [ 0 ] . tooltip . should . equal ( otherEnvOne . name ) ; otherItems [ 0 ] . contextValue . should . equal ( 'blockchain-environment-item' ) ; otherItems [ 1 ] . label . should . equal ( otherEnvTwo . name ) ; otherItems [ 1 ] . tooltip . should . equal ( otherEnvTwo . name ) ; otherItems [ 1 ] . contextValue . should . equal ( 'blockchain-microfab-item' ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; ibmCloudItems . length . should . equal ( 1 ) ; ibmCloudItems [ 0 ] . label . should . equal ( `+ Log in to IBM Cloud` ) ; ibmCloudItems [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . LOG_IN_AND_DISCOVER , title : '' , arguments : [ ] } ) ; loggedInStub . should . have . been . calledTwice ; accountSelectedStub . should . have . been . calledTwice ; anyResourcesStub . should . not . have . been . called ; } ) ; it ( 'should correctly display all types of groups' , async ( ) => { const ensureRuntimeLocalSpy = mySandBox . spy ( LocalMicroEnvironmentManager . instance ( ) , 'ensureRuntime' ) ; const localFabricEnv = new FabricEnvironmentRegistryEntry ( ) ; localFabricEnv . name = 'localFabricEnv' ; localFabricEnv . environmentType = EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT ; const registryEntryOne = new FabricEnvironmentRegistryEntry ( ) ; registryEntryOne . name = 'myFabric' ; registryEntryOne . managedRuntime = false ; const registryEntryTwo = new FabricEnvironmentRegistryEntry ( ) ; registryEntryTwo . name = 'myMicrofab' ; registryEntryTwo . managedRuntime = false ; registryEntryTwo . environmentType = EnvironmentType . MICROFAB_ENVIRONMENT ; const opsToolsEnv = new FabricEnvironmentRegistryEntry ( ) ; opsToolsEnv . name = 'opsToolsEnv' ; opsToolsEnv . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; const saasEnv = new FabricEnvironmentRegistryEntry ( ) ; saasEnv . name = 'saasEnv' ; saasEnv . environmentType = EnvironmentType . SAAS_OPS_TOOLS_ENVIRONMENT ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . add ( localFabricEnv ) ; await FabricEnvironmentRegistry . instance ( ) . add ( registryEntryOne ) ; await FabricEnvironmentRegistry . instance ( ) . add ( registryEntryTwo ) ; await FabricEnvironmentRegistry . instance ( ) . add ( opsToolsEnv ) ; await FabricEnvironmentRegistry . instance ( ) . add ( saasEnv ) ; await TestUtil . setupLocalFabric ( ) ; const mockRuntime = mySandBox . createStubInstance ( LocalMicroEnvironment ) ; mySandBox . stub ( LocalMicroEnvironmentManager . instance ( ) , 'getRuntime' ) . returns ( mockRuntime ) ; mockRuntime . isRunning . resolves ( false ) ; mockRuntime . startLogs . resolves ( ) ; mockRuntime . getName . returns ( FabricRuntimeUtil . LOCAL_FABRIC ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 3 ) ; allChildren [ 0 ] . label . should . equal ( 'Simple local networks' ) ; allChildren [ 0 ] . tooltip . should . equal ( 'Simple local networks' ) ; allChildren [ 0 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; allChildren [ 1 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 1 ] . tooltip . should . equal ( 'IBM Blockchain Platform on cloud' ) ; allChildren [ 1 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; allChildren [ 2 ] . label . should . equal ( 'Other networks' ) ; allChildren [ 2 ] . tooltip . should . equal ( 'Other networks' ) ; allChildren [ 2 ] . contextValue . should . equal ( 'blockchain-environment-group-item' ) ; const localEnvItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; localEnvItems . length . should . equal ( 2 ) ; localEnvItems [ 0 ] . label . should . equal ( `${ FabricRuntimeUtil . LOCAL_FABRIC }  ○ (click to start)` ) ; localEnvItems [ 0 ] . tooltip . should . equal ( 'Creates a local development runtime using Hyperledger Fabric Docker images' ) ; localEnvItems [ 0 ] . contextValue . should . equal ( 'blockchain-runtime-item' ) ; localEnvItems [ 1 ] . label . should . equal ( localFabricEnv . name ) ; localEnvItems [ 1 ] . tooltip . should . equal ( localFabricEnv . name ) ; localEnvItems [ 1 ] . contextValue . should . equal ( 'blockchain-environment-item' ) ; const opsToolsItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 1 ] ) ; opsToolsItems . length . should . equal ( 2 ) ; opsToolsItems [ 0 ] . label . should . equal ( opsToolsEnv . name ) ; opsToolsItems [ 0 ] . tooltip . should . equal ( opsToolsEnv . name ) ; opsToolsItems [ 0 ] . contextValue . should . equal ( 'blockchain-ops-environment' ) ; opsToolsItems [ 1 ] . label . should . equal ( saasEnv . name ) ; opsToolsItems [ 1 ] . tooltip . should . equal ( saasEnv . name ) ; opsToolsItems [ 1 ] . contextValue . should . equal ( 'blockchain-ops-environment' ) ; const otherItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 2 ] ) ; otherItems . length . should . equal ( 2 ) ; otherItems [ 0 ] . label . should . equal ( registryEntryOne . name ) ; otherItems [ 0 ] . tooltip . should . equal ( registryEntryOne . name ) ; otherItems [ 0 ] . contextValue . should . equal ( 'blockchain-environment-item' ) ; otherItems [ 1 ] . label . should . equal ( registryEntryTwo . name ) ; otherItems [ 1 ] . tooltip . should . equal ( registryEntryTwo . name ) ; otherItems [ 1 ] . contextValue . should . equal ( 'blockchain-microfab-item' ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , false ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-microfab-connected' , false ) ; ensureRuntimeLocalSpy . should . have . been . calledOnce ; } ) ; it ( 'should get correct context value for running local runtime' , async ( ) => { const ensureRuntimeLocalSpy = mySandBox . spy ( LocalMicroEnvironmentManager . instance ( ) , 'ensureRuntime' ) ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await TestUtil . setupLocalFabric ( ) ; const mockRuntime = mySandBox . createStubInstance ( LocalMicroEnvironment ) ; mySandBox . stub ( LocalMicroEnvironmentManager . instance ( ) , 'getRuntime' ) . returns ( mockRuntime ) ; mockRuntime . isRunning . resolves ( true ) ; mockRuntime . startLogs . resolves ( ) ; mockRuntime . getName . returns ( FabricRuntimeUtil . LOCAL_FABRIC ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; const simpleLocalNetworkItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; simpleLocalNetworkItems . length . should . equal ( 1 ) ; simpleLocalNetworkItems [ 0 ] . label . should . equal ( `${ FabricRuntimeUtil . LOCAL_FABRIC }  ●` ) ; simpleLocalNetworkItems [ 0 ] . tooltip . should . equal ( 'The local development runtime is running' ) ; simpleLocalNetworkItems [ 0 ] . contextValue . should . equal ( 'blockchain-runtime-item-running' ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , false ) ; ensureRuntimeLocalSpy . should . have . been . calledOnce ; } ) ; it ( 'should say that there are no environments' , async ( ) => { await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 2 ) ; allChildren [ 0 ] . label . should . equal ( `+ Add local or remote environment` ) ; allChildren [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . ADD_ENVIRONMENT , title : '' , arguments : [ ] } ) ; allChildren [ 1 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 1 ] ) ; ibmCloudItems . length . should . equal ( 1 ) ; ibmCloudItems [ 0 ] . label . should . equal ( `+ Log in to IBM Cloud` ) ; ibmCloudItems [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . LOG_IN_AND_DISCOVER , title : '' , arguments : [ ] } ) ; loggedInStub . should . have . been . calledTwice ; accountSelectedStub . should . have . been . calledTwice ; anyResourcesStub . should . not . have . been . called ; } ) ; it ( `should show a 'create new instance' tree item if logged into IBM Cloud with no available instances` , async ( ) => { await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; loggedInStub . resolves ( true ) ; accountSelectedStub . resolves ( true ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) . resolves ( false ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 2 ) ; allChildren [ 0 ] . label . should . equal ( `+ Add local or remote environment` ) ; allChildren [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . ADD_ENVIRONMENT , title : '' , arguments : [ ] } ) ; allChildren [ 1 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 1 ] ) ; ibmCloudItems . length . should . equal ( 1 ) ; ibmCloudItems [ 0 ] . label . should . equal ( `+ create new instance` ) ; ibmCloudItems [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . OPEN_NEW_INSTANCE_LINK , title : '' , arguments : [ ] } ) ; loggedInStub . should . have . been . calledTwice ; accountSelectedStub . should . have . been . calledTwice ; anyResourcesStub . should . have . been . calledTwice ; } ) ; it ( `should show a 'install IBM Cloud Account Extension' tree item if the IBM Cloud Account Extension is not installed` , async ( ) => { await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; isIBMCloudExtensionInstalled . returns ( false ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 2 ) ; allChildren [ 1 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 1 ] ) ; ibmCloudItems . length . should . equal ( 1 ) ; ibmCloudItems [ 0 ] . label . should . equal ( `+ Install IBM Cloud Account extension` ) ; ibmCloudItems [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . OPEN_VSCODE_EXTENSION , title : '' , arguments : [ ] } ) ; } ) ; it ( 'should show log in item if there are ops tools environments but no saas environments' , async ( ) => { const opsToolsEnv = new FabricEnvironmentRegistryEntry ( ) ; opsToolsEnv . name = 'opsToolsEnv' ; opsToolsEnv . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . add ( opsToolsEnv ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) . resolves ( false ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 1 ) ; allChildren [ 0 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; ibmCloudItems . length . should . equal ( 2 ) ; ibmCloudItems [ 0 ] . label . should . equal ( `+ Log in to IBM Cloud` ) ; ibmCloudItems [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . LOG_IN_AND_DISCOVER , title : '' , arguments : [ ] } ) ; ibmCloudItems [ 1 ] . label . should . equal ( opsToolsEnv . name ) ; ibmCloudItems [ 1 ] . tooltip . should . equal ( opsToolsEnv . name ) ; ibmCloudItems [ 1 ] . contextValue . should . equal ( 'blockchain-ops-environment' ) ; loggedInStub . should . have . been . calledOnce ; accountSelectedStub . should . have . been . calledOnce ; anyResourcesStub . should . not . have . been . called ; } ) ; it ( 'should show select account item if user logged in to IBM cloud but no account selected' , async ( ) => { const opsToolsEnv = new FabricEnvironmentRegistryEntry ( ) ; opsToolsEnv . name = 'opsToolsEnv' ; opsToolsEnv . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . add ( opsToolsEnv ) ; loggedInStub . resolves ( true ) ; accountSelectedStub . resolves ( false ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) . resolves ( false ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 1 ) ; allChildren [ 0 ] . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; const ibmCloudItems = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; ibmCloudItems . length . should . equal ( 2 ) ; ibmCloudItems [ 0 ] . label . should . equal ( `+ Select IBM Cloud account` ) ; ibmCloudItems [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . LOG_IN_AND_DISCOVER , title : '' , arguments : [ ] } ) ; ibmCloudItems [ 1 ] . label . should . equal ( opsToolsEnv . name ) ; ibmCloudItems [ 1 ] . tooltip . should . equal ( opsToolsEnv . name ) ; ibmCloudItems [ 1 ] . contextValue . should . equal ( 'blockchain-ops-environment' ) ; loggedInStub . should . have . been . calledOnce ; accountSelectedStub . should . have . been . calledOnce ; anyResourcesStub . should . not . have . been . called ; } ) ; it ( `should try to automatically add discovered IBP instances` , async ( ) => { await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . DISCOVER_SAAS_ENVS , true , vscode . ConfigurationTarget . Global ) ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; executeCommandStub . withArgs ( ExtensionCommands . LOG_IN_AND_DISCOVER ) . resolves ( ) ; loggedInStub . resolves ( true ) ; accountSelectedStub . resolves ( true ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) . resolves ( true ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 1 ) ; allChildren [ 0 ] . label . should . equal ( `+ Add local or remote environment` ) ; allChildren [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . ADD_ENVIRONMENT , title : '' , arguments : [ ] } ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . LOG_IN_AND_DISCOVER ) ; loggedInStub . should . have . been . calledOnce ; accountSelectedStub . should . have . been . calledOnce ; anyResourcesStub . should . have . been . calledOnce ; } ) ; it ( `should try to automatically add discovered IBP instances when other environments have already been added` , async ( ) => { await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . DISCOVER_SAAS_ENVS , true , vscode . ConfigurationTarget . Global ) ; const registryEntry = new FabricEnvironmentRegistryEntry ( ) ; registryEntry . name = 'myFabric' ; registryEntry . managedRuntime = false ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . add ( registryEntry ) ; executeCommandStub . withArgs ( ExtensionCommands . LOG_IN_AND_DISCOVER ) . resolves ( ) ; loggedInStub . resolves ( true ) ; accountSelectedStub . resolves ( true ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) . resolves ( true ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 1 ) ; const otherGroupItem = allChildren [ 0 ] as EnvironmentGroupTreeItem ; otherGroupItem . label . should . equal ( 'Other networks' ) ; otherGroupItem . environments . should . deep . equal ( [ registryEntry ] ) ; await blockchainRuntimeExplorerProvider . getChildren ( otherGroupItem ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . LOG_IN_AND_DISCOVER ) ; loggedInStub . should . have . been . calledOnce ; accountSelectedStub . should . have . been . calledOnce ; anyResourcesStub . should . have . been . calledOnce ; } ) ; it ( 'should try to automatically add discovered IBP instances when there are ops tools environments but no saas environments' , async ( ) => { await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . DISCOVER_SAAS_ENVS , true , vscode . ConfigurationTarget . Global ) ; const opsToolsEnv = new FabricEnvironmentRegistryEntry ( ) ; opsToolsEnv . name = 'opsToolsEnv' ; opsToolsEnv . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await FabricEnvironmentRegistry . instance ( ) . add ( opsToolsEnv ) ; executeCommandStub . withArgs ( ExtensionCommands . LOG_IN_AND_DISCOVER ) . resolves ( ) ; loggedInStub . resolves ( true ) ; accountSelectedStub . resolves ( true ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) . resolves ( true ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 1 ) ; const cloudGroupItem = allChildren [ 0 ] as EnvironmentGroupTreeItem ; cloudGroupItem . label . should . equal ( 'IBM Blockchain Platform on cloud' ) ; cloudGroupItem . environments . should . deep . equal ( [ opsToolsEnv ] ) ; await blockchainRuntimeExplorerProvider . getChildren ( cloudGroupItem ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . LOG_IN_AND_DISCOVER ) ; loggedInStub . should . have . been . calledOnce ; accountSelectedStub . should . have . been . calledOnce ; anyResourcesStub . should . have . been . calledOnce ; } ) ; it ( 'should not automatically add discovered environments if set to false in user settings' , async ( ) => { await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . DISCOVER_SAAS_ENVS , false , vscode . ConfigurationTarget . Global ) ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; executeCommandStub . withArgs ( ExtensionCommands . LOG_IN_AND_DISCOVER ) . resolves ( ) ; loggedInStub . resolves ( true ) ; accountSelectedStub . resolves ( true ) ; const anyResourcesStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountAnyIbpResources' ) . resolves ( true ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 1 ) ; allChildren [ 0 ] . label . should . equal ( `+ Add local or remote environment` ) ; allChildren [ 0 ] . command . should . deep . equal ( { command : ExtensionCommands . ADD_ENVIRONMENT , title : '' , arguments : [ ] } ) ; executeCommandStub . withArgs ( ExtensionCommands . LOG_IN_AND_DISCOVER ) . should . not . have . been . called ; loggedInStub . should . have . been . calledOnce ; accountSelectedStub . should . have . been . calledOnce ; anyResourcesStub . should . have . been . calledOnce ; } ) ; it ( 'should handle errors populating the tree with runtimeTreeItems' , async ( ) => { const registryEntryOne = new FabricEnvironmentRegistryEntry ( ) ; registryEntryOne . name = 'myFabric' ; registryEntryOne . managedRuntime = false ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await TestUtil . setupLocalFabric ( ) ; const error = new Error ( 'some error' ) ; mySandBox . stub ( RuntimeTreeItem , 'newRuntimeTreeItem' ) . rejects ( error ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 0 ] ) ; logSpy . should . have . been . calledWith ( LogType . ERROR , `Error populating Fabric Environment Panel: ${ error . message }` , `Error populating Fabric Environment Panel: ${ error . toString ( ) }` ) ; } ) ; } ) ; describe ( 'connecting tree' , ( ) => { let getConnectionStub ; let environmentRegistryStub ; let fabricConnection ; let getStateStub ; let logSpy ; let commandStub ; beforeEach ( async ( ) => { getConnectionStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getConnection' ) ; fabricConnection = mySandBox . createStubInstance ( FabricEnvironmentConnection ) ; getConnectionStub . returns ( ( fabricConnection as any ) as FabricEnvironmentConnection ) ; const map = new Map < string , Array < string > > ( ) ; map . set ( 'channelOne' , [ 'peerOne' ] ) ; map . set ( 'channelTwo' , [ 'peerOne' , 'peerTwo' ] ) ; fabricConnection . createChannelMap . resolves ( map ) ; fabricConnection . getCommittedSmartContractDefinitions . withArgs ( [ 'peerOne' ] , 'channelOne' ) . resolves ( [ { name : 'biscuit-network' , version : '0.7' } ] ) ; fabricConnection . getCommittedSmartContractDefinitions . withArgs ( [ 'peerOne' , 'peerTwo' ] , 'channelTwo' ) . resolves ( [ { name : 'biscuit-network' , version : '0.7' } , { name : 'cake-network' , version : '0.10' } , { name : 'legacy-network' , version : '2.34' } ] ) ; const environmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistry . name = FabricRuntimeUtil . LOCAL_FABRIC ; environmentRegistry . managedRuntime = true ; environmentRegistry . environmentType = EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT ; environmentRegistryStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getEnvironmentRegistryEntry' ) ; environmentRegistryStub . returns ( environmentRegistry ) ; getStateStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getState' ) ; logSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; commandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; await ExtensionUtil . activateExtension ( ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should display setup tree if not setup' , async ( ) => { getStateStub . returns ( ConnectedState . SETUP ) ; const peerNode = FabricNode . newPeer ( 'peer1' , 'peer1.org1.example.com' , 'http://peer.sample.org' , undefined , undefined , undefined ) ; const ordererNode = FabricNode . newOrderer ( 'orderer' , 'orderer.example.com' , 'http://orderer.sample.org' , undefined , undefined , undefined , undefined ) ; const caNode = FabricNode . newCertificateAuthority ( 'ca1' , 'ca1.org1.example.com' , 'http://ca.sample.org' , undefined , undefined , undefined , undefined , undefined , undefined ) ; mySandBox . stub ( FabricEnvironment . prototype , 'getNodes' ) . resolves ( [ peerNode , ordererNode , caNode ] ) ; const environmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistry . name = 'myEnvironment' ; environmentRegistry . managedRuntime = false ; environmentRegistryStub . returns ( environmentRegistry ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const children = await blockchainRuntimeExplorerProvider . getChildren ( ) ; commandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-setup' , true ) ; children . length . should . equal ( 5 ) ; children [ 0 ] . label . should . equal ( `Setting up: ${ environmentRegistry . name }` ) ; children [ 1 ] . label . should . equal ( `(Click each node to perform setup)` ) ; children [ 2 ] . label . should . equal ( 'peer1.org1.example.com   ⚠' ) ; children [ 2 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 2 ] . command . arguments . should . deep . equal ( [ environmentRegistry , peerNode ] ) ; children [ 2 ] . tooltip . should . equal ( peerNode . name ) ; children [ 3 ] . label . should . equal ( 'orderer.example.com   ⚠' ) ; children [ 3 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 3 ] . command . arguments . should . deep . equal ( [ environmentRegistry , ordererNode ] ) ; children [ 3 ] . tooltip . should . equal ( ordererNode . name ) ; children [ 4 ] . label . should . equal ( 'ca1.org1.example.com   ⚠' ) ; children [ 4 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 4 ] . command . arguments . should . deep . equal ( [ environmentRegistry , caNode ] ) ; children [ 4 ] . tooltip . should . equal ( caNode . name ) ; } ) ; it ( 'should display setup tree if not setup with orderer cluster name' , async ( ) => { getStateStub . returns ( ConnectedState . SETUP ) ; const peerNode = FabricNode . newPeer ( 'peer1' , 'peer1.org1.example.com' , 'http://peer.sample.org' , undefined , undefined , undefined ) ; const ordererNode = FabricNode . newOrderer ( 'orderer' , 'orderer.example.com' , 'http://orderer.sample.org' , undefined , undefined , undefined , 'Ordering Service' ) ; const ordererNode1 = FabricNode . newOrderer ( 'orderer1' , 'orderer1.example.com' , 'http://orderer.sample.org' , undefined , undefined , undefined , 'Ordering Service' ) ; const caNode = FabricNode . newCertificateAuthority ( 'ca1' , 'ca1.org1.example.com' , 'http://ca.sample.org' , undefined , undefined , undefined , undefined , undefined , undefined ) ; mySandBox . stub ( FabricEnvironment . prototype , 'getNodes' ) . resolves ( [ peerNode , ordererNode , ordererNode1 , caNode ] ) ; const environmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistry . name = 'myEnvironment' ; environmentRegistry . managedRuntime = false ; environmentRegistryStub . returns ( environmentRegistry ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const children = await blockchainRuntimeExplorerProvider . getChildren ( ) ; commandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-setup' , true ) ; should . not . exist ( blockchainRuntimeExplorerProvider [ 'fabricEnvironmentToSetUp' ] ) ; children . length . should . equal ( 5 ) ; children [ 0 ] . label . should . equal ( `Setting up: ${ environmentRegistry . name }` ) ; children [ 1 ] . label . should . equal ( `(Click each node to perform setup)` ) ; children [ 2 ] . label . should . equal ( 'peer1.org1.example.com   ⚠' ) ; children [ 2 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 2 ] . command . arguments . should . deep . equal ( [ environmentRegistry , peerNode ] ) ; children [ 2 ] . tooltip . should . equal ( peerNode . name ) ; children [ 3 ] . label . should . equal ( 'Ordering Service   ⚠' ) ; children [ 3 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 3 ] . command . arguments . should . deep . equal ( [ environmentRegistry , ordererNode ] ) ; children [ 3 ] . tooltip . should . equal ( ordererNode . cluster_name ) ; children [ 4 ] . label . should . equal ( 'ca1.org1.example.com   ⚠' ) ; children [ 4 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 4 ] . command . arguments . should . deep . equal ( [ environmentRegistry , caNode ] ) ; children [ 4 ] . tooltip . should . equal ( caNode . name ) ; } ) ; it ( 'should display setup tree with multiple ordering services' , async ( ) => { getStateStub . returns ( ConnectedState . SETUP ) ; const peerNode = FabricNode . newPeer ( 'peer1' , 'peer1.org1.example.com' , 'http://peer.sample.org' , undefined , undefined , undefined ) ; const peerNode2 = FabricNode . newPeer ( 'peer2' , 'peer2.org1.example.com' , 'http://peer.sample.org' , 'some wallet' , 'some identity' , undefined ) ; const ordererNode = FabricNode . newOrderer ( 'orderer' , 'orderer.example.com' , 'http://orderer.sample.org' , 'some wallet' , undefined , undefined , 'Ordering Service' ) ; const ordererNode1 = FabricNode . newOrderer ( 'orderer1' , 'orderer1.example.com' , 'http://orderer.sample.org' , 'some wallet' , undefined , undefined , 'Ordering Service' ) ; const ordererNode2 = FabricNode . newOrderer ( 'orderer2' , 'orderer2.example.com' , 'http://orderer.sample.org' , undefined , 'some identity' , undefined , 'Another Ordering Service' ) ; const ordererNode3 = FabricNode . newOrderer ( 'orderer3' , 'orderer3.example.com' , 'http://orderer.sample.org' , undefined , 'some identity' , undefined , 'Another Ordering Service' ) ; const caNode = FabricNode . newCertificateAuthority ( 'ca1' , 'ca1.org1.example.com' , 'http://ca.sample.org' , undefined , undefined , undefined , undefined , undefined , undefined ) ; mySandBox . stub ( FabricEnvironment . prototype , 'getNodes' ) . resolves ( [ peerNode , peerNode2 , ordererNode , ordererNode1 , ordererNode2 , ordererNode3 , caNode ] ) ; const environmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistry . name = 'myEnvironment' ; environmentRegistry . managedRuntime = false ; environmentRegistryStub . returns ( environmentRegistry ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const children = await blockchainRuntimeExplorerProvider . getChildren ( ) ; commandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-setup' , true ) ; should . not . exist ( blockchainRuntimeExplorerProvider [ 'fabricEnvironmentToSetUp' ] ) ; children . length . should . equal ( 7 ) ; children [ 0 ] . label . should . equal ( `Setting up: ${ environmentRegistry . name }` ) ; children [ 1 ] . label . should . equal ( `(Click each node to perform setup)` ) ; children [ 2 ] . label . should . equal ( 'peer1.org1.example.com   ⚠' ) ; children [ 2 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 2 ] . command . arguments . should . deep . equal ( [ environmentRegistry , peerNode ] ) ; children [ 2 ] . tooltip . should . equal ( peerNode . name ) ; children [ 3 ] . label . should . equal ( 'peer2.org1.example.com' ) ; children [ 3 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 3 ] . command . arguments . should . deep . equal ( [ environmentRegistry , peerNode2 ] ) ; children [ 3 ] . tooltip . should . equal ( peerNode2 . name ) ; children [ 4 ] . label . should . equal ( 'Ordering Service   ⚠' ) ; children [ 4 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 4 ] . command . arguments . should . deep . equal ( [ environmentRegistry , ordererNode ] ) ; children [ 4 ] . tooltip . should . equal ( ordererNode . cluster_name ) ; children [ 5 ] . label . should . equal ( 'Another Ordering Service   ⚠' ) ; children [ 5 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 5 ] . command . arguments . should . deep . equal ( [ environmentRegistry , ordererNode2 ] ) ; children [ 5 ] . tooltip . should . equal ( ordererNode2 . cluster_name ) ; children [ 6 ] . label . should . equal ( 'ca1.org1.example.com   ⚠' ) ; children [ 6 ] . command . command . should . equal ( ExtensionCommands . ASSOCIATE_IDENTITY_NODE ) ; children [ 6 ] . command . arguments . should . deep . equal ( [ environmentRegistry , caNode ] ) ; children [ 6 ] . tooltip . should . equal ( caNode . name ) ; } ) ; it ( 'should error if gRPC cant connect to Fabric' , async ( ) => { getStateStub . returns ( ConnectedState . CONNECTED ) ; fabricConnection . getAllPeerNames . returns ( [ 'peerOne' ] ) ; const error = new Error ( 'Cannot connect to Fabric: Received http2 header with status: 503' ) ; fabricConnection . createChannelMap . rejects ( error ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; await blockchainRuntimeExplorerProvider . getChildren ( ) ; logSpy . should . have . been . calledOnceWith ( LogType . ERROR , `Error populating channel view: ${ error . message }` , `Error populating channel view: ${ error . toString ( ) }` ) ; } ) ; it ( 'should error if getAllChannelsForPeer errors with message when populating channels view' , async ( ) => { getStateStub . returns ( ConnectedState . CONNECTED ) ; fabricConnection . getAllPeerNames . returns ( [ 'peerOne' ] ) ; const error = new Error ( 'Error creating channel map: some error' ) ; fabricConnection . createChannelMap . rejects ( error ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; await blockchainRuntimeExplorerProvider . getChildren ( ) ; logSpy . should . have . been . calledOnceWith ( LogType . ERROR , `Error populating channel view: ${ error . message }` , `Error populating channel view: ${ error . toString ( ) }` ) ; } ) ; it ( 'should error if populating nodes view fails' , async ( ) => { getStateStub . returns ( ConnectedState . CONNECTED ) ; fabricConnection . getAllPeerNames . throws ( { message : 'some error' } ) ; fabricConnection . getChannelCapabilityFromPeer . resolves ( [ UserInputUtil . V2_0 ] ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ allChildren . length - 2 ] ) ; logSpy . should . have . been . calledOnceWith ( LogType . ERROR , 'Error populating nodes view: some error' ) ; } ) ; } ) ; describe ( 'connected tree' , ( ) => { let allChildren ; let blockchainRuntimeExplorerProvider ; let fabricConnection ; let logSpy ; let executeCommandStub ; let environmentStub ; let connectedStateStub ; let environmentRegistry ; beforeEach ( async ( ) => { logSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; await ExtensionUtil . activateExtension ( ) ; connectedStateStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getState' ) . returns ( ConnectedState . CONNECTED ) ; executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; fabricConnection = mySandBox . createStubInstance ( FabricEnvironmentConnection ) ; fabricConnection . getAllPeerNames . returns ( [ 'peerOne' , 'peerTwo' ] ) ; const installedChaincodeMapOne = [ { label : 'sample-car-network' , packageId : '1.0' } , { label : 'sample-car-network' , packageId : '1.2' } , { label : 'sample-food-network' , packageId : '0.6' } ] ; fabricConnection . getInstalledSmartContracts . withArgs ( 'peerOne' ) . returns ( installedChaincodeMapOne ) ; const installedChaincodeMapTwo = [ { label : 'biscuit-network' , packageId : '0.7' } , { label : 'sample-food-network' , packageId : '0.6' } ] ; fabricConnection . getInstalledSmartContracts . withArgs ( 'peerTwo' ) . returns ( installedChaincodeMapTwo ) ; fabricConnection . getCommittedSmartContractDefinitions . withArgs ( [ 'peerOne' ] , 'channelOne' ) . resolves ( [ { name : 'biscuit-network' , version : '0.7' } ] ) ; fabricConnection . getCommittedSmartContractDefinitions . withArgs ( [ 'peerOne' , 'peerTwo' ] , 'channelTwo' ) . resolves ( [ { name : 'biscuit-network' , version : '0.7' } , { name : 'cake-network' , version : '0.10' } , { name : 'legacy-network' , version : '2.34' } ] ) ; fabricConnection . getCommittedSmartContractDefinitions . withArgs ( [ 'peerOne' ] , 'channelThree' ) . resolves ( [ ] ) ; fabricConnection . getAllOrganizationNames . returns ( [ 'Org1' , 'Org2' ] ) ; fabricConnection . getAllOrdererNames . returns ( [ 'orderer1' , 'orderer2' ] ) ; fabricConnection . getChannelCapabilityFromPeer . resolves ( [ UserInputUtil . V2_0 ] ) ; const map = new Map < string , Array < string > > ( ) ; map . set ( 'channelOne' , [ 'peerOne' ] ) ; map . set ( 'channelTwo' , [ 'peerOne' , 'peerTwo' ] ) ; map . set ( 'channelThree' , [ 'peerOne' ] ) ; fabricConnection . createChannelMap . resolves ( map ) ; environmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistry . name = FabricRuntimeUtil . LOCAL_FABRIC ; environmentRegistry . managedRuntime = true ; environmentRegistry . environmentType = EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT ; environmentStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getEnvironmentRegistryEntry' ) . returns ( environmentRegistry ) ; blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const fabricRuntimeManager = LocalMicroEnvironmentManager . instance ( ) ; mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getConnection' ) . returns ( ( fabricConnection as any ) as FabricEnvironmentConnection ) ; mySandBox . stub ( fabricRuntimeManager . getRuntime ( FabricRuntimeUtil . LOCAL_FABRIC ) , 'isRunning' ) . resolves ( true ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; const getTransactionNamesStub = mySandBox . stub ( MetadataUtil , 'getTransactionNames' ) ; getTransactionNamesStub . withArgs ( sinon . match . any , 'biscuit-network' , sinon . match . any ) . resolves ( new Map < string , string [ ] > ( ) ) ; getTransactionNamesStub . withArgs ( sinon . match . any , 'cake-network' , sinon . match . any ) . resolves ( new Map < string , string [ ] > ( ) ) ; getTransactionNamesStub . withArgs ( sinon . match . any , 'legacy-network' , sinon . match . any ) . resolves ( null ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should create a connected tree if there is a connection' , async ( ) => { allChildren . length . should . equal ( 6 ) ; const connectedTo = allChildren [ 0 ] as EnvironmentConnectedTreeItem ; connectedTo . label . should . equal ( `Connected to environment: ${ FabricRuntimeUtil . LOCAL_FABRIC }` ) ; const channelOne = allChildren [ 1 ] as ChannelTreeItem ; channelOne . tooltip . should . equal ( `Associated peers: peerOne\nChannel capabilities: ${ UserInputUtil . V2_0 }` ) ; channelOne . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . Collapsed ) ; channelOne . contextValue . should . equal ( 'blockchain-channel-item' ) ; channelOne . label . should . equal ( 'channelOne' ) ; const channelTwo = allChildren [ 2 ] as ChannelTreeItem ; channelTwo . tooltip . should . equal ( `Associated peers: peerOne, peerTwo\nChannel capabilities: ${ UserInputUtil . V2_0 }` ) ; channelTwo . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . Collapsed ) ; channelTwo . contextValue . should . equal ( 'blockchain-channel-item' ) ; channelTwo . label . should . equal ( 'channelTwo' ) ; const channelThree = allChildren [ 3 ] as ChannelTreeItem ; channelThree . tooltip . should . equal ( `Associated peers: peerOne\nChannel capabilities: ${ UserInputUtil . V2_0 }` ) ; channelThree . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . Collapsed ) ; channelThree . contextValue . should . equal ( 'blockchain-channel-item' ) ; channelThree . label . should . equal ( 'channelThree' ) ; const nodes = allChildren [ 4 ] as NodesTreeItem ; nodes . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . Collapsed ) ; nodes . contextValue . should . equal ( 'blockchain-runtime-nodes-item' ) ; nodes . label . should . equal ( 'Nodes' ) ; const orgs = allChildren [ 5 ] as OrganizationsTreeItem ; orgs . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . Collapsed ) ; orgs . contextValue . should . equal ( 'blockchain-runtime-organizations-item' ) ; orgs . label . should . equal ( 'Organizations' ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , true ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , true ) ; } ) ; it ( 'should set correct context if not local runtime' , async ( ) => { const otherEnvironmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; otherEnvironmentRegistry . name = 'myFabric' ; otherEnvironmentRegistry . managedRuntime = false ; otherEnvironmentRegistry . environmentType = EnvironmentType . ENVIRONMENT ; environmentStub . returns ( otherEnvironmentRegistry ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; const connectedTo = allChildren [ 0 ] as EnvironmentConnectedTreeItem ; connectedTo . label . should . equal ( `Connected to environment: myFabric` ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , true ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; } ) ; it ( 'should set correct context if imported microfab' , async ( ) => { const otherEnvironmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; otherEnvironmentRegistry . name = 'myMicrofab' ; otherEnvironmentRegistry . managedRuntime = false ; otherEnvironmentRegistry . environmentType = EnvironmentType . MICROFAB_ENVIRONMENT ; environmentStub . returns ( otherEnvironmentRegistry ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; const connectedTo = allChildren [ 0 ] as EnvironmentConnectedTreeItem ; connectedTo . label . should . equal ( `Connected to environment: myMicrofab` ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-microfab-connected' , true ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , true ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; } ) ; it ( 'should show the committed smart contracts' , async ( ) => { allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 6 ) ; const smartContractsChannelOne = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 1 ] ) ; smartContractsChannelOne . length . should . equal ( 2 ) ; smartContractsChannelOne [ 0 ] . label . should . equal ( 'biscuit-network@0.7' ) ; smartContractsChannelOne [ 0 ] . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; smartContractsChannelOne [ 0 ] . tooltip . should . equal ( 'biscuit-network@0.7' ) ; smartContractsChannelOne [ 1 ] . label . should . equal ( '+ Deploy smart contract' ) ; smartContractsChannelOne [ 1 ] . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; smartContractsChannelOne [ 1 ] . tooltip . should . equal ( '+ Deploy smart contract' ) ; smartContractsChannelOne [ 1 ] . command . command . should . equal ( ExtensionCommands . OPEN_DEPLOY_PAGE ) ; smartContractsChannelOne [ 1 ] . command . arguments . should . deep . equal ( [ environmentRegistry , 'channelOne' ] ) ; const smartContractsChannelTwo = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ 2 ] ) ; smartContractsChannelTwo . length . should . equal ( 4 ) ; smartContractsChannelTwo [ 0 ] . label . should . equal ( 'biscuit-network@0.7' ) ; smartContractsChannelTwo [ 0 ] . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; smartContractsChannelTwo [ 0 ] . tooltip . should . equal ( 'biscuit-network@0.7' ) ; smartContractsChannelTwo [ 1 ] . label . should . equal ( 'cake-network@0.10' ) ; smartContractsChannelTwo [ 1 ] . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; smartContractsChannelTwo [ 1 ] . tooltip . should . equal ( 'cake-network@0.10' ) ; smartContractsChannelTwo [ 2 ] . label . should . equal ( 'legacy-network@2.34' ) ; smartContractsChannelTwo [ 2 ] . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; smartContractsChannelTwo [ 2 ] . tooltip . should . equal ( 'legacy-network@2.34' ) ; smartContractsChannelTwo [ 3 ] . label . should . equal ( '+ Deploy smart contract' ) ; smartContractsChannelTwo [ 3 ] . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; smartContractsChannelTwo [ 3 ] . tooltip . should . equal ( '+ Deploy smart contract' ) ; smartContractsChannelTwo [ 3 ] . command . command . should . equal ( ExtensionCommands . OPEN_DEPLOY_PAGE ) ; smartContractsChannelTwo [ 3 ] . command . arguments . should . deep . equal ( [ environmentRegistry , 'channelTwo' ] ) ; } ) ; it ( 'should show peers, certificate authorities, and orderer nodes correctly' , async ( ) => { fabricConnection . getAllCertificateAuthorityNames . returns ( [ 'ca-name' ] ) ; fabricConnection . getNode . withArgs ( 'peerOne' ) . returns ( FabricNode . newPeer ( 'peerOne' , 'peerOne' , 'grpc://localhost:7051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'peerTwo' ) . returns ( FabricNode . newPeer ( 'peerTwo' , 'peerTwo' , 'grpc://localhost:8051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'ca-name' ) . returns ( FabricNode . newCertificateAuthority ( 'ca-name' , 'ca-name' , 'http://localhost:7054' , 'ca_name' , 'wallet' , 'identity' , 'Org1MSP' , 'admin' , 'adminpw' ) ) ; fabricConnection . getNode . withArgs ( 'orderer1' ) . returns ( FabricNode . newOrderer ( 'orderer1' , 'orderer1' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , undefined ) ) ; fabricConnection . getNode . withArgs ( 'orderer2' ) . returns ( FabricNode . newOrderer ( 'orderer2' , 'orderer2' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , undefined ) ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 6 ) ; const items = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ allChildren . length - 2 ] ) ; items . length . should . equal ( 5 ) ; const peerOne = items [ 0 ] as PeerTreeItem ; peerOne . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerOne . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerOne . label . should . equal ( 'peerOne' ) ; peerOne . node . api_url . should . equal ( 'grpc://localhost:7051' ) ; let tooltip = `Name: ${ peerOne . node . name }\nMSPID: ${ peerOne . node . msp_id }\nAssociated Identity:\n${ peerOne . node . identity }` ; peerOne . tooltip . should . equal ( tooltip ) ; const peerTwo = items [ 1 ] as PeerTreeItem ; peerTwo . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerTwo . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerTwo . label . should . equal ( 'peerTwo' ) ; peerTwo . node . api_url . should . equal ( 'grpc://localhost:8051' ) ; tooltip = `Name: ${ peerTwo . node . name }\nMSPID: ${ peerTwo . node . msp_id }\nAssociated Identity:\n${ peerTwo . node . identity }` ; peerTwo . tooltip . should . equal ( tooltip ) ; const ca = items [ 2 ] as CertificateAuthorityTreeItem ; ca . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; ca . contextValue . should . equal ( 'blockchain-runtime-certificate-authority-item' ) ; ca . label . should . equal ( 'ca-name' ) ; ca . node . api_url . should . equal ( 'http://localhost:7054' ) ; tooltip = `Name: ${ ca . node . name }\nAssociated Identity:\n${ ca . node . identity }` ; ca . tooltip . should . equal ( tooltip ) ; const orderer = items [ 3 ] as OrdererTreeItem ; orderer . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer . label . should . equal ( 'orderer1' ) ; orderer . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer . node . name }\nMSPID: ${ orderer . node . msp_id }\nAssociated Identity:\n${ orderer . node . identity }` ; orderer . tooltip . should . equal ( tooltip ) ; const orderer2 = items [ 4 ] as OrdererTreeItem ; orderer2 . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer2 . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer2 . label . should . equal ( 'orderer2' ) ; orderer2 . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer2 . node . name }\nMSPID: ${ orderer2 . node . msp_id }\nAssociated Identity:\n${ orderer2 . node . identity }` ; orderer2 . tooltip . should . equal ( tooltip ) ; logSpy . should . not . have . been . calledWith ( LogType . ERROR ) ; } ) ; it ( 'should show peers, certificate authorities, and orderer nodes correctly with none local fabric' , async ( ) => { const anotherEnvironmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; anotherEnvironmentRegistry . name = 'myEnvironment' ; environmentStub . returns ( anotherEnvironmentRegistry ) ; fabricConnection . getAllCertificateAuthorityNames . returns ( [ 'ca-name' ] ) ; fabricConnection . getNode . withArgs ( 'peerOne' ) . returns ( FabricNode . newPeer ( 'peerOne' , 'peerOne' , 'grpc://localhost:7051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'peerTwo' ) . returns ( FabricNode . newPeer ( 'peerTwo' , 'peerTwo' , 'grpc://localhost:8051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'ca-name' ) . returns ( FabricNode . newCertificateAuthority ( 'ca-name' , 'ca-name' , 'http://localhost:7054' , 'ca_name' , 'wallet' , 'identity' , 'Org1MSP' , 'admin' , 'adminpw' ) ) ; fabricConnection . getNode . withArgs ( 'orderer1' ) . returns ( FabricNode . newOrderer ( 'orderer1' , 'orderer1' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , undefined ) ) ; fabricConnection . getNode . withArgs ( 'orderer2' ) . returns ( FabricNode . newOrderer ( 'orderer2' , 'orderer2' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , undefined ) ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 6 ) ; const items = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ allChildren . length - 2 ] ) ; items . length . should . equal ( 6 ) ; const peerOne = items [ 0 ] as PeerTreeItem ; peerOne . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerOne . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerOne . label . should . equal ( 'peerOne' ) ; peerOne . node . api_url . should . equal ( 'grpc://localhost:7051' ) ; let tooltip = `Name: ${ peerOne . node . name }\nMSPID: ${ peerOne . node . msp_id }\nAssociated Identity:\n${ peerOne . node . identity }` ; peerOne . tooltip . should . equal ( tooltip ) ; const peerTwo = items [ 1 ] as PeerTreeItem ; peerTwo . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerTwo . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerTwo . label . should . equal ( 'peerTwo' ) ; peerTwo . node . api_url . should . equal ( 'grpc://localhost:8051' ) ; tooltip = `Name: ${ peerTwo . node . name }\nMSPID: ${ peerTwo . node . msp_id }\nAssociated Identity:\n${ peerTwo . node . identity }` ; peerTwo . tooltip . should . equal ( tooltip ) ; const ca = items [ 2 ] as CertificateAuthorityTreeItem ; ca . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; ca . contextValue . should . equal ( 'blockchain-runtime-certificate-authority-item' ) ; ca . label . should . equal ( 'ca-name' ) ; ca . node . api_url . should . equal ( 'http://localhost:7054' ) ; tooltip = `Name: ${ ca . node . name }\nAssociated Identity:\n${ ca . node . identity }` ; ca . tooltip . should . equal ( tooltip ) ; const orderer = items [ 3 ] as OrdererTreeItem ; orderer . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer . label . should . equal ( 'orderer1' ) ; orderer . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer . node . name }\nMSPID: ${ orderer . node . msp_id }\nAssociated Identity:\n${ orderer . node . identity }` ; orderer . tooltip . should . equal ( tooltip ) ; const orderer2 = items [ 4 ] as OrdererTreeItem ; orderer2 . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer2 . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer2 . label . should . equal ( 'orderer2' ) ; orderer2 . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer2 . node . name }\nMSPID: ${ orderer2 . node . msp_id }\nAssociated Identity:\n${ orderer2 . node . identity }` ; orderer2 . tooltip . should . equal ( tooltip ) ; const importNodes = items [ 5 ] as ImportNodesTreeItem ; importNodes . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; importNodes . contextValue . should . equal ( 'blockchain-import-nodes-item' ) ; importNodes . label . should . equal ( '+ Import Nodes' ) ; logSpy . should . not . have . been . calledWith ( LogType . ERROR ) ; } ) ; it ( 'should show peers, certificate authorities, and orderer nodes correctly with OpsTool instance' , async ( ) => { connectedStateStub . returns ( ConnectedState . CONNECTING ) ; const setStateStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'setState' ) ; const anotherEnvironmentRegistry = new FabricEnvironmentRegistryEntry ( ) ; anotherEnvironmentRegistry . name = 'myEnvironment' ; anotherEnvironmentRegistry . url = 'someURL' ; anotherEnvironmentRegistry . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; const connectCommandStub = executeCommandStub . withArgs ( ExtensionCommands . CONNECT_TO_ENVIRONMENT , anotherEnvironmentRegistry ) . resolves ( ) ; environmentStub . returns ( anotherEnvironmentRegistry ) ; fabricConnection . getAllCertificateAuthorityNames . returns ( [ 'ca-name' ] ) ; fabricConnection . getNode . withArgs ( 'peerOne' ) . returns ( FabricNode . newPeer ( 'peerOne' , 'peerOne' , 'grpc://localhost:7051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'peerTwo' ) . returns ( FabricNode . newPeer ( 'peerTwo' , 'peerTwo' , 'grpc://localhost:8051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'ca-name' ) . returns ( FabricNode . newCertificateAuthority ( 'ca-name' , 'ca-name' , 'http://localhost:7054' , 'ca_name' , 'wallet' , 'identity' , 'Org1MSP' , 'admin' , 'adminpw' ) ) ; fabricConnection . getNode . withArgs ( 'orderer1' ) . returns ( FabricNode . newOrderer ( 'orderer1' , 'orderer1' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , undefined ) ) ; fabricConnection . getNode . withArgs ( 'orderer2' ) . returns ( FabricNode . newOrderer ( 'orderer2' , 'orderer2' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , undefined ) ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 6 ) ; const items = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ allChildren . length - 2 ] ) ; items . length . should . equal ( 6 ) ; const peerOne = items [ 0 ] as PeerTreeItem ; peerOne . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerOne . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerOne . label . should . equal ( 'peerOne' ) ; peerOne . node . api_url . should . equal ( 'grpc://localhost:7051' ) ; let tooltip = `Name: ${ peerOne . node . name }\nMSPID: ${ peerOne . node . msp_id }\nAssociated Identity:\n${ peerOne . node . identity }` ; peerOne . tooltip . should . equal ( tooltip ) ; const peerTwo = items [ 1 ] as PeerTreeItem ; peerTwo . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerTwo . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerTwo . label . should . equal ( 'peerTwo' ) ; peerTwo . node . api_url . should . equal ( 'grpc://localhost:8051' ) ; tooltip = `Name: ${ peerTwo . node . name }\nMSPID: ${ peerTwo . node . msp_id }\nAssociated Identity:\n${ peerTwo . node . identity }` ; peerTwo . tooltip . should . equal ( tooltip ) ; const ca = items [ 2 ] as CertificateAuthorityTreeItem ; ca . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; ca . contextValue . should . equal ( 'blockchain-runtime-certificate-authority-item' ) ; ca . label . should . equal ( 'ca-name' ) ; ca . node . api_url . should . equal ( 'http://localhost:7054' ) ; tooltip = `Name: ${ ca . node . name }\nAssociated Identity:\n${ ca . node . identity }` ; ca . tooltip . should . equal ( tooltip ) ; const orderer = items [ 3 ] as OrdererTreeItem ; orderer . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer . label . should . equal ( 'orderer1' ) ; orderer . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer . node . name }\nMSPID: ${ orderer . node . msp_id }\nAssociated Identity:\n${ orderer . node . identity }` ; orderer . tooltip . should . equal ( tooltip ) ; const orderer2 = items [ 4 ] as OrdererTreeItem ; orderer2 . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer2 . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer2 . label . should . equal ( 'orderer2' ) ; orderer2 . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer2 . node . name }\nMSPID: ${ orderer2 . node . msp_id }\nAssociated Identity:\n${ orderer2 . node . identity }` ; orderer2 . tooltip . should . equal ( tooltip ) ; const importNodes = items [ 5 ] as ImportNodesTreeItem ; importNodes . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; importNodes . contextValue . should . equal ( 'blockchain-filter-nodes-item' ) ; importNodes . label . should . equal ( 'Edit Filters' ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-opstool-connected' , true ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , true ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; executeCommandStub . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-setup' , false ) ; executeCommandStub . should . have . been . called ; connectCommandStub . should . have . not . been . called ; setStateStub . should . have . been . calledWith ( ConnectedState . CONNECTED ) ; logSpy . should . not . have . been . calledWith ( LogType . ERROR ) ; } ) ; it ( 'should show peers, certificate authorities, and orderer nodes correctly with cluster name' , async ( ) => { fabricConnection . getAllCertificateAuthorityNames . returns ( [ 'ca-name' ] ) ; fabricConnection . getNode . withArgs ( 'peerOne' ) . returns ( FabricNode . newPeer ( 'peerOne' , 'peerOne' , 'grpc://localhost:7051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'peerTwo' ) . returns ( FabricNode . newPeer ( 'peerTwo' , 'peerTwo' , 'grpc://localhost:8051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'ca-name' ) . returns ( FabricNode . newCertificateAuthority ( 'ca-name' , 'ca-name' , 'http://localhost:7054' , 'ca_name' , 'wallet' , 'identity' , 'Org1MSP' , 'admin' , 'adminpw' ) ) ; fabricConnection . getNode . withArgs ( 'orderer1' ) . returns ( FabricNode . newOrderer ( 'orderer1' , 'orderer1' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , 'my ordering service' ) ) ; fabricConnection . getNode . withArgs ( 'orderer2' ) . returns ( FabricNode . newOrderer ( 'orderer2' , 'orderer2' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , 'my ordering service' ) ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 6 ) ; const items = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ allChildren . length - 2 ] ) ; items . length . should . equal ( 4 ) ; const peerOne = items [ 0 ] as PeerTreeItem ; peerOne . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerOne . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerOne . label . should . equal ( 'peerOne' ) ; peerOne . node . api_url . should . equal ( 'grpc://localhost:7051' ) ; let tooltip = `Name: ${ peerOne . node . name }\nMSPID: ${ peerOne . node . msp_id }\nAssociated Identity:\n${ peerOne . node . identity }` ; peerOne . tooltip . should . equal ( tooltip ) ; const peerTwo = items [ 1 ] as PeerTreeItem ; peerTwo . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerTwo . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerTwo . label . should . equal ( 'peerTwo' ) ; peerTwo . node . api_url . should . equal ( 'grpc://localhost:8051' ) ; tooltip = `Name: ${ peerTwo . node . name }\nMSPID: ${ peerTwo . node . msp_id }\nAssociated Identity:\n${ peerTwo . node . identity }` ; peerTwo . tooltip . should . equal ( tooltip ) ; const ca = items [ 2 ] as CertificateAuthorityTreeItem ; ca . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; ca . contextValue . should . equal ( 'blockchain-runtime-certificate-authority-item' ) ; ca . label . should . equal ( 'ca-name' ) ; ca . node . api_url . should . equal ( 'http://localhost:7054' ) ; tooltip = `Name: ${ ca . node . name }\nAssociated Identity:\n${ ca . node . identity }` ; ca . tooltip . should . equal ( tooltip ) ; const orderer = items [ 3 ] as OrdererTreeItem ; orderer . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer . label . should . equal ( 'my ordering service' ) ; orderer . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer . node . cluster_name }\nMSPID: ${ orderer . node . msp_id }\nAssociated Identity:\n${ orderer . node . identity }` ; orderer . tooltip . should . equal ( tooltip ) ; logSpy . should . not . have . been . calledWith ( LogType . ERROR ) ; } ) ; it ( 'should show peers, certificate authorities, and multiple orderer nodes correctly with cluster name' , async ( ) => { fabricConnection . getAllCertificateAuthorityNames . returns ( [ 'ca-name' ] ) ; fabricConnection . getAllOrdererNames . returns ( [ 'orderer1' , 'orderer2' , 'orderer3' , 'orderer4' ] ) ; fabricConnection . getNode . withArgs ( 'peerOne' ) . returns ( FabricNode . newPeer ( 'peerOne' , 'peerOne' , 'grpc://localhost:7051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'peerTwo' ) . returns ( FabricNode . newPeer ( 'peerTwo' , 'peerTwo' , 'grpc://localhost:8051' , 'wallet' , 'identity' , 'Org1MSP' ) ) ; fabricConnection . getNode . withArgs ( 'ca-name' ) . returns ( FabricNode . newCertificateAuthority ( 'ca-name' , 'ca-name' , 'http://localhost:7054' , 'ca_name' , 'wallet' , 'identity' , 'Org1MSP' , 'admin' , 'adminpw' ) ) ; fabricConnection . getNode . withArgs ( 'orderer1' ) . returns ( FabricNode . newOrderer ( 'orderer1' , 'orderer1' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , 'my ordering service' ) ) ; fabricConnection . getNode . withArgs ( 'orderer2' ) . returns ( FabricNode . newOrderer ( 'orderer2' , 'orderer2' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , 'my ordering service' ) ) ; fabricConnection . getNode . withArgs ( 'orderer3' ) . returns ( FabricNode . newOrderer ( 'orderer3' , 'orderer3' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , 'my other ordering service' ) ) ; fabricConnection . getNode . withArgs ( 'orderer4' ) . returns ( FabricNode . newOrderer ( 'orderer4' , 'orderer4' , 'grpc://localhost:7050' , 'wallet' , 'identity' , 'Org1MSP' , 'my other ordering service' ) ) ; allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 6 ) ; const items = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ allChildren . length - 2 ] ) ; items . length . should . equal ( 5 ) ; const peerOne = items [ 0 ] as PeerTreeItem ; peerOne . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerOne . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerOne . label . should . equal ( 'peerOne' ) ; peerOne . node . api_url . should . equal ( 'grpc://localhost:7051' ) ; let tooltip = `Name: ${ peerOne . node . name }\nMSPID: ${ peerOne . node . msp_id }\nAssociated Identity:\n${ peerOne . node . identity }` ; peerOne . tooltip . should . equal ( tooltip ) ; const peerTwo = items [ 1 ] as PeerTreeItem ; peerTwo . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; peerTwo . contextValue . should . equal ( 'blockchain-peer-item' ) ; peerTwo . label . should . equal ( 'peerTwo' ) ; peerTwo . node . api_url . should . equal ( 'grpc://localhost:8051' ) ; tooltip = `Name: ${ peerTwo . node . name }\nMSPID: ${ peerTwo . node . msp_id }\nAssociated Identity:\n${ peerTwo . node . identity }` ; peerTwo . tooltip . should . equal ( tooltip ) ; const ca = items [ 2 ] as CertificateAuthorityTreeItem ; ca . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; ca . contextValue . should . equal ( 'blockchain-runtime-certificate-authority-item' ) ; ca . label . should . equal ( 'ca-name' ) ; ca . node . api_url . should . equal ( 'http://localhost:7054' ) ; tooltip = `Name: ${ ca . node . name }\nAssociated Identity:\n${ ca . node . identity }` ; ca . tooltip . should . equal ( tooltip ) ; const orderer = items [ 3 ] as OrdererTreeItem ; orderer . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer . label . should . equal ( 'my ordering service' ) ; orderer . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer . node . cluster_name }\nMSPID: ${ orderer . node . msp_id }\nAssociated Identity:\n${ orderer . node . identity }` ; orderer . tooltip . should . equal ( tooltip ) ; const orderer2 = items [ 4 ] as OrdererTreeItem ; orderer2 . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orderer2 . contextValue . should . equal ( 'blockchain-runtime-orderer-item' ) ; orderer2 . label . should . equal ( 'my other ordering service' ) ; orderer2 . node . api_url . should . equal ( 'grpc://localhost:7050' ) ; tooltip = `Name: ${ orderer2 . node . cluster_name }\nMSPID: ${ orderer2 . node . msp_id }\nAssociated Identity:\n${ orderer2 . node . identity }` ; orderer2 . tooltip . should . equal ( tooltip ) ; logSpy . should . not . have . been . calledWith ( LogType . ERROR ) ; } ) ; it ( 'should show organizations correctly' , async ( ) => { allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 6 ) ; const orgs = await blockchainRuntimeExplorerProvider . getChildren ( allChildren [ allChildren . length - 1 ] ) ; orgs . length . should . equal ( 2 ) ; const orgOne = orgs [ 0 ] as OrgTreeItem ; orgOne . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orgOne . contextValue . should . equal ( 'blockchain-runtime-org-item' ) ; orgOne . label . should . equal ( 'Org1' ) ; const orgTwo = orgs [ 1 ] as OrgTreeItem ; orgTwo . collapsibleState . should . equal ( vscode . TreeItemCollapsibleState . None ) ; orgTwo . contextValue . should . equal ( 'blockchain-runtime-org-item' ) ; orgTwo . label . should . equal ( 'Org2' ) ; logSpy . should . not . have . been . called ; } ) ; } ) ; } ) ; describe ( 'refresh' , ( ) => { let registryEntry ; let getEnvRegEntryStub ; let commandStub ; beforeEach ( async ( ) => { await ExtensionUtil . activateExtension ( ) ; registryEntry = new FabricEnvironmentRegistryEntry ( ) ; registryEntry . name = FabricRuntimeUtil . LOCAL_FABRIC ; registryEntry . managedRuntime = true ; mySandBox . stub ( LocalMicroEnvironment . prototype , 'startLogs' ) . resolves ( ) ; mySandBox . stub ( LocalMicroEnvironment . prototype , 'stopLogs' ) . returns ( undefined ) ; commandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; commandStub . callThrough ( ) ; registryEntry . environmentType = EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT ; getEnvRegEntryStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getEnvironmentRegistryEntry' ) ; getEnvRegEntryStub . returns ( registryEntry ) ; const map = new Map < string , Array < string > > ( ) ; map . set ( 'channelOne' , [ 'peerOne' ] ) ; map . set ( 'channelTwo' , [ 'peerOne' , 'peerTwo' ] ) ; const fabricConnection = mySandBox . createStubInstance ( FabricEnvironmentConnection ) ; fabricConnection . createChannelMap . resolves ( map ) ; fabricConnection . getChannelCapabilityFromPeer . resolves ( [ UserInputUtil . V2_0 ] ) ; fabricConnection . getCommittedSmartContractDefinitions . withArgs ( [ 'peerOne' ] , 'channelOne' ) . resolves ( [ { name : 'biscuit-network' , version : '0.7' } ] ) ; fabricConnection . getCommittedSmartContractDefinitions . withArgs ( [ 'peerOne' , 'peerTwo' ] , 'channelTwo' ) . resolves ( [ { name : 'biscuit-network' , version : '0.7' } , { name : 'cake-network' , version : '0.10' } , { name : 'legacy-network' , version : '2.34' } ] ) ; const getConnectionStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getConnection' ) ; getConnectionStub . returns ( ( fabricConnection as any ) as FabricEnvironmentConnection ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should test the tree is refreshed when the refresh command is run' , async ( ) => { const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const onDidChangeTreeDataSpy = mySandBox . spy ( blockchainRuntimeExplorerProvider [ '_onDidChangeTreeData' ] , 'fire' ) ; await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_ENVIRONMENTS ) ; onDidChangeTreeDataSpy . should . have . been . called ; } ) ; it ( 'should test the tree is refreshed when the refresh command is run' , async ( ) => { const mockTreeItem = mySandBox . createStubInstance ( ChannelTreeItem ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const onDidChangeTreeDataSpy = mySandBox . spy ( blockchainRuntimeExplorerProvider [ '_onDidChangeTreeData' ] , 'fire' ) ; await vscode . commands . executeCommand ( ExtensionCommands . REFRESH_ENVIRONMENTS , mockTreeItem ) ; onDidChangeTreeDataSpy . should . have . been . calledOnceWithExactly ( mockTreeItem ) ; } ) ; it ( 'should refresh on connect event' , async ( ) => { const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const connectStub = mySandBox . stub ( blockchainRuntimeExplorerProvider , 'connect' ) . resolves ( ) ; FabricEnvironmentManager . instance ( ) . emit ( 'connected' ) ; connectStub . should . have . been . called ; } ) ; it ( 'should refresh on disconnect event' , async ( ) => { const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const disconnectStub = mySandBox . stub ( blockchainRuntimeExplorerProvider , 'disconnect' ) . resolves ( ) ; FabricEnvironmentManager . instance ( ) . emit ( 'disconnected' ) ; disconnectStub . should . have . been . called ; } ) ; it ( 'should try to reconnect if refreshing a connected Ops Tools environment, and return current tree' , async ( ) => { const getStateStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getState' ) . returns ( ConnectedState . CONNECTED ) ; const registryEntryOpsTools = new FabricEnvironmentRegistryEntry ( ) ; registryEntryOpsTools . name = 'myOpsToolsFabric' ; registryEntryOpsTools . managedRuntime = false ; registryEntryOpsTools . url = '/some/url:port' ; registryEntryOpsTools . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; getEnvRegEntryStub . returns ( registryEntryOpsTools ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const connectCommandStub = commandStub . withArgs ( ExtensionCommands . CONNECT_TO_ENVIRONMENT , registryEntryOpsTools ) . resolves ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 5 ) ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-opstool-connected' , true ) ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , true ) ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-environment-setup' , false ) ; getStateStub . should . have . been . called ; connectCommandStub . should . have . been . called ; } ) ; it ( 'should handle disconnect when refreshing a connected Ops Tools environment, and return current tree' , async ( ) => { const getStateStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getState' ) ; getStateStub . returns ( ConnectedState . CONNECTED ) ; getStateStub . onCall ( 4 ) . returns ( ConnectedState . DISCONNECTED ) ; const registryEntryOpsTools = new FabricEnvironmentRegistryEntry ( ) ; registryEntryOpsTools . name = 'myOpsToolsFabric' ; registryEntryOpsTools . managedRuntime = false ; registryEntryOpsTools . url = '/some/url:port' ; registryEntryOpsTools . environmentType = EnvironmentType . OPS_TOOLS_ENVIRONMENT ; getEnvRegEntryStub . returns ( registryEntryOpsTools ) ; const getAllStub = mySandBox . stub ( FabricEnvironmentRegistry . instance ( ) , 'getAll' ) . resolves ( [ registryEntry , registryEntryOpsTools ] ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const connectCommandStub = commandStub . withArgs ( ExtensionCommands . CONNECT_TO_ENVIRONMENT , registryEntryOpsTools ) . resolves ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; allChildren . length . should . equal ( 2 ) ; getAllStub . should . have . been . called ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-opstool-connected' , true ) ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , true ) ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-runtime-connected' , false ) ; commandStub . should . have . not . been . calledWith ( 'setContext' , 'blockchain-environment-setup' , false ) ; getStateStub . should . have . been . called ; connectCommandStub . should . have . been . called ; } ) ; } ) ; describe ( 'connect' , ( ) => { beforeEach ( async ( ) => { await ExtensionUtil . activateExtension ( ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should set the current client connection' , async ( ) => { const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const onDidChangeTreeDataSpy = mySandBox . spy ( blockchainRuntimeExplorerProvider [ '_onDidChangeTreeData' ] , 'fire' ) ; await blockchainRuntimeExplorerProvider . connect ( ) ; onDidChangeTreeDataSpy . should . have . been . called ; } ) ; } ) ; describe ( 'disconnect' , ( ) => { beforeEach ( async ( ) => { await ExtensionUtil . activateExtension ( ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should disconnect the runtime connection' , async ( ) => { const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const onDidChangeTreeDataSpy = mySandBox . spy ( blockchainRuntimeExplorerProvider [ '_onDidChangeTreeData' ] , 'fire' ) ; const executeCommandSpy = mySandBox . spy ( vscode . commands , 'executeCommand' ) ; await blockchainRuntimeExplorerProvider . disconnect ( ) ; onDidChangeTreeDataSpy . should . have . been . called ; executeCommandSpy . should . have . been . calledOnce ; executeCommandSpy . getCall ( 0 ) . should . have . been . calledWith ( 'setContext' , 'blockchain-environment-connected' , false ) ; } ) ; } ) ; describe ( 'getTreeItem' , ( ) => { let loggedInStub ; let accountSelectedStub ; beforeEach ( async ( ) => { mySandBox . stub ( ExtensionsInteractionUtil , 'isIBMCloudExtensionInstalled' ) . returns ( true ) ; loggedInStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountIsLoggedIn' ) . resolves ( false ) ; accountSelectedStub = mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountHasSelectedAccount' ) . resolves ( false ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should get a tree item' , async ( ) => { await TestUtil . setupLocalFabric ( ) ; await ExtensionUtil . activateExtension ( ) ; mySandBox . stub ( LocalMicroEnvironmentManager . instance ( ) . getRuntime ( FabricRuntimeUtil . LOCAL_FABRIC ) , 'isRunning' ) . resolves ( false ) ; mySandBox . stub ( LocalMicroEnvironmentManager . instance ( ) . getRuntime ( FabricRuntimeUtil . LOCAL_FABRIC ) , 'getName' ) . returns ( FabricRuntimeUtil . LOCAL_FABRIC ) ; const blockchainRuntimeExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainRuntimeExplorerProvider . getChildren ( ) ; const result = blockchainRuntimeExplorerProvider . getTreeItem ( allChildren [ 0 ] ) as EnvironmentGroupTreeItem ; result . label . should . equal ( 'Simple local networks' ) ; loggedInStub . should . have . been . called . calledOnce ; accountSelectedStub . should . have . been . called . calledOnce ; } ) ; } ) ; } ) ;