'use strict' ; import * as vscode from 'vscode' ; import * as chai from 'chai' ; import * as sinon from 'sinon' ; import * as sinonChai from 'sinon-chai' ; import * as path from 'path' ; import { BlockchainTreeItem } from '../../extension/explorer/model/BlockchainTreeItem' ; import { TestUtil } from '../TestUtil' ; import { UserInputUtil } from '../../extension/commands/UserInputUtil' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { VSCodeBlockchainOutputAdapter } from '../../extension/logging/VSCodeBlockchainOutputAdapter' ; import { FabricEnvironmentRegistry , FabricEnvironmentRegistryEntry , FabricRuntimeUtil , LogType , FabricGatewayRegistryEntry , EnvironmentType } from 'ibm-blockchain-platform-common' ; import { BlockchainEnvironmentExplorerProvider } from '../../extension/explorer/environmentExplorer' ; import { ExtensionUtil } from '../../extension/util/ExtensionUtil' ; import { FabricEnvironmentManager } from '../../extension/fabric/environments/FabricEnvironmentManager' ; import { FabricGatewayConnectionManager } from '../../extension/fabric/FabricGatewayConnectionManager' ; import { RuntimeTreeItem } from '../../extension/explorer/runtimeOps/disconnectedTree/RuntimeTreeItem' ; import { SettingConfigurations } from '../../extension/configurations' ; import { GlobalState , ExtensionData } from '../../extension/util/GlobalState' ; import { ExtensionsInteractionUtil } from '../../extension/util/ExtensionsInteractionUtil' ; import { LocalMicroEnvironmentManager } from '../../extension/fabric/environments/LocalMicroEnvironmentManager' ; import { LocalMicroEnvironment } from '../../extension/fabric/environments/LocalMicroEnvironment' ; chai . should ( ) ; chai . use ( sinonChai ) ; describe ( 'DeleteEnvironmentCommand' , ( ) => { let mySandBox ; let showConfirmationWarningMessage ; before ( async ( ) => { mySandBox = sinon . createSandbox ( ) ; await TestUtil . setupTests ( mySandBox ) ; } ) ; describe ( 'deleteEnvironment' , ( ) => { let showFabricEnvironmentQuickPickBoxStub ; let environments ; let myEnvironmentA ; let myEnvironmentB ; let logSpy ; let commandSpy ; let geConnectedEnvironmentRegistryStub ; let getConnectedGatewayRegistryStub ; let getAllSpy ; let globalStateUpdateSpy ; let removeLocalRuntimeSpy ; beforeEach ( async ( ) => { mySandBox . restore ( ) ; showConfirmationWarningMessage = mySandBox . stub ( UserInputUtil , 'showConfirmationWarningMessage' ) . withArgs ( `This will remove the environment(s). Do you want to continue?` ) . resolves ( true ) ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; const settings = { } ; settings [ FabricRuntimeUtil . LOCAL_FABRIC ] = 8080 ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . FABRIC_RUNTIME , settings , vscode . ConfigurationTarget . Global ) ; environments = [ ] ; myEnvironmentA = new FabricEnvironmentRegistryEntry ( { name : 'myEnvironmentA' , environmentType : EnvironmentType . ENVIRONMENT } ) ; await FabricEnvironmentRegistry . instance ( ) . add ( myEnvironmentA ) ; myEnvironmentB = new FabricEnvironmentRegistryEntry ( { name : 'myEnvironmentB' , environmentType : EnvironmentType . ENVIRONMENT } ) ; await FabricEnvironmentRegistry . instance ( ) . add ( myEnvironmentB ) ; await TestUtil . startLocalFabric ( ) ; showFabricEnvironmentQuickPickBoxStub = mySandBox . stub ( UserInputUtil , 'showFabricEnvironmentQuickPickBox' ) . resolves ( [ { label : 'myEnvironmentB' , data : myEnvironmentB } ] ) ; geConnectedEnvironmentRegistryStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getEnvironmentRegistryEntry' ) ; getConnectedGatewayRegistryStub = mySandBox . stub ( FabricGatewayConnectionManager . instance ( ) , 'getGatewayRegistryEntry' ) . resolves ( ) ; commandSpy = mySandBox . spy ( vscode . commands , 'executeCommand' ) ; logSpy = mySandBox . stub ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; getAllSpy = mySandBox . spy ( FabricEnvironmentRegistry . instance ( ) , 'getAll' ) ; globalStateUpdateSpy = mySandBox . spy ( GlobalState , 'update' ) ; removeLocalRuntimeSpy = mySandBox . spy ( LocalMicroEnvironmentManager . instance ( ) , 'removeRuntime' ) ; mySandBox . stub ( LocalMicroEnvironment . prototype , 'isRunning' ) . resolves ( false ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should test an environment can be deleted from the command' , async ( ) => { await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; commandSpy . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ myEnvironmentB . name } environment` ) ; } ) ; it ( 'should test multiple environments can be deleted from the command' , async ( ) => { showFabricEnvironmentQuickPickBoxStub . resolves ( [ { label : 'myenvironmentA' , data : await FabricEnvironmentRegistry . instance ( ) . get ( 'myEnvironmentA' ) } , { label : 'myEnvironmentB' , data : await FabricEnvironmentRegistry . instance ( ) . get ( 'myEnvironmentB' ) } ] ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 1 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted environments` ) ; } ) ; it ( 'should test an environment can be deleted from tree' , async ( ) => { mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountIsLoggedIn' ) . resolves ( false ) ; mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountHasSelectedAccount' ) . resolves ( false ) ; const blockchainEnvironmentExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainEnvironmentExplorerProvider . getChildren ( ) ; const groupChildren = await blockchainEnvironmentExplorerProvider . getChildren ( allChildren [ 2 ] ) ; const environmentToDelete = groupChildren [ 0 ] ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT_SHORT , environmentToDelete ) ; showFabricEnvironmentQuickPickBoxStub . should . not . have . been . called ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentB ) ; commandSpy . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ myEnvironmentA . name } environment` ) ; } ) ; it ( 'should test an environment can be deleted from environment registry' , async ( ) => { const environmentRegistryEntry = await FabricEnvironmentRegistry . instance ( ) . get ( 'myEnvironmentA' ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT , environmentRegistryEntry ) ; showFabricEnvironmentQuickPickBoxStub . should . not . have . been . called ; getAllSpy . should . not . have . been . called ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentB ) ; commandSpy . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ myEnvironmentA . name } environment` ) ; } ) ; it ( 'should disconnect before deleting if connected' , async ( ) => { const environmentRegistryEntry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistryEntry . name = 'myEnvironmentB' ; geConnectedEnvironmentRegistryStub . returns ( environmentRegistryEntry ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; commandSpy . should . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ myEnvironmentB . name } environment` ) ; } ) ; it ( 'should disconnect from gateway before deleting if connected to a related gateway' , async ( ) => { const environmentRegistryEntry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistryEntry . name = 'myEnvironmentB' ; geConnectedEnvironmentRegistryStub . returns ( environmentRegistryEntry ) ; const gatewayRegistryEntry = new FabricGatewayRegistryEntry ( { name : 'myGateway' , fromEnvironment : environmentRegistryEntry . name , associatedWallet : '' , connectionProfilePath : path . join ( 'blockchain' , 'extension' , 'directory' , 'gatewayOne' , 'connection.json' ) } ) ; getConnectedGatewayRegistryStub . resolves ( gatewayRegistryEntry ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; commandSpy . should . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; commandSpy . should . have . been . calledWith ( ExtensionCommands . DISCONNECT_GATEWAY ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ myEnvironmentB . name } environment` ) ; } ) ; it ( 'should not disconnect from gateway before deleting if connected to a non-related gateway' , async ( ) => { const environmentRegistryEntry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegistryEntry . name = 'myEnvironmentB' ; geConnectedEnvironmentRegistryStub . returns ( environmentRegistryEntry ) ; const gatewayRegistryEntry = new FabricGatewayRegistryEntry ( { name : 'myGateway' , fromEnvironment : 'anotherEnv' , associatedWallet : '' , connectionProfilePath : path . join ( 'blockchain' , 'extension' , 'directory' , 'gatewayOne' , 'connection.json' ) } ) ; getConnectedGatewayRegistryStub . resolves ( gatewayRegistryEntry ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; commandSpy . should . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; commandSpy . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_GATEWAY ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ myEnvironmentB . name } environment` ) ; } ) ; it ( 'should test an environment can be forcefully deleted' , async ( ) => { await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT , undefined , true ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; commandSpy . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; showConfirmationWarningMessage . should . not . have . been . called ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ myEnvironmentB . name } environment` ) ; } ) ; it ( 'should test delete environment can be cancelled' , async ( ) => { showFabricEnvironmentQuickPickBoxStub . resolves ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 3 ) ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , `delete environment` ) ; } ) ; it ( 'should handle the user not selecting an environment to delete' , async ( ) => { showFabricEnvironmentQuickPickBoxStub . resolves ( [ ] ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 3 ) ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , `delete environment` ) ; } ) ; it ( 'should show an error message if no environments have been added' , async ( ) => { await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . not . have . been . called ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . ERROR , `No environments to delete.` ) ; } ) ; it ( 'should handle no from confirmation message' , async ( ) => { showConfirmationWarningMessage . resolves ( false ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 3 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; environments [ 2 ] . should . deep . equal ( myEnvironmentB ) ; logSpy . should . have . been . calledOnceWithExactly ( LogType . INFO , undefined , `delete environment` ) ; } ) ; it ( 'should handle error from deleting environment' , async ( ) => { const error = new Error ( 'some error' ) ; mySandBox . stub ( FabricEnvironmentRegistry . instance ( ) , 'delete' ) . rejects ( error ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 3 ) ; commandSpy . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . ERROR , `Error deleting environment: ${ error . message }` , `Error deleting environment: ${ error . toString ( ) }` ) ; } ) ; it ( `should be able to delete the ${ FabricRuntimeUtil . LOCAL_FABRIC } environment from the tree` , async ( ) => { commandSpy . restore ( ) ; const executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; executeCommandStub . withArgs ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC ) . resolves ( ) ; mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountIsLoggedIn' ) . resolves ( false ) ; mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountHasSelectedAccount' ) . resolves ( false ) ; const blockchainEnvironmentExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainEnvironmentExplorerProvider . getChildren ( ) ; const groupChildren = await blockchainEnvironmentExplorerProvider . getChildren ( allChildren [ 0 ] ) ; const environmentToDelete = groupChildren [ 0 ] ; environmentToDelete . should . be . an . instanceOf ( RuntimeTreeItem ) ; const globalState = GlobalState . get ( ) ; globalState . deletedOneOrgLocalFabric = false ; await GlobalState . update ( globalState ) ; globalStateUpdateSpy . resetHistory ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT_SHORT , environmentToDelete ) ; globalStateUpdateSpy . should . have . been . calledOnce ; const updateCall = globalStateUpdateSpy . getCall ( 0 ) . args [ 0 ] ; updateCall . deletedOneOrgLocalFabric . should . equal ( true ) ; showFabricEnvironmentQuickPickBoxStub . should . not . have . been . called ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . should . deep . equal ( myEnvironmentA ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentB ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC ) ; executeCommandStub . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; removeLocalRuntimeSpy . should . have . been . calledOnceWithExactly ( FabricRuntimeUtil . LOCAL_FABRIC ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ FabricRuntimeUtil . LOCAL_FABRIC } environment` ) ; const localSettings = await vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . FABRIC_RUNTIME , vscode . ConfigurationTarget . Global ) ; localSettings . should . deep . equal ( { } ) ; } ) ; it ( `should be able to delete a local microfab from the tree` , async ( ) => { const originalSettings = vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . FABRIC_RUNTIME , vscode . ConfigurationTarget . Global ) ; const newSettings = Object . assign ( { otherLocal : 8081 } , originalSettings ) ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . FABRIC_RUNTIME , newSettings , vscode . ConfigurationTarget . Global ) ; const otherLocalEnvEntry = new FabricEnvironmentRegistryEntry ( { name : 'otherLocal' , managedRuntime : true , numberOfOrgs : 1 , environmentType : EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT , environmentDirectory : path . join ( __dirname , '..' , 'data' , '1 Org Local Fabric' ) , fabricCapabilities : UserInputUtil . V2_0 } ) ; await FabricEnvironmentRegistry . instance ( ) . add ( otherLocalEnvEntry ) ; showFabricEnvironmentQuickPickBoxStub . resolves ( [ { label : 'otherLocal' , data : otherLocalEnvEntry } ] ) ; commandSpy . restore ( ) ; const executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; executeCommandStub . withArgs ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , 'otherLocal' ) . resolves ( ) ; mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountIsLoggedIn' ) . resolves ( false ) ; mySandBox . stub ( ExtensionsInteractionUtil , 'cloudAccountHasSelectedAccount' ) . resolves ( false ) ; const blockchainEnvironmentExplorerProvider = ExtensionUtil . getBlockchainEnvironmentExplorerProvider ( ) ; const allChildren = await blockchainEnvironmentExplorerProvider . getChildren ( ) ; const groupChildren = await blockchainEnvironmentExplorerProvider . getChildren ( allChildren [ 0 ] ) ; const environmentToDelete = groupChildren [ 1 ] ; environmentToDelete . should . be . an . instanceOf ( RuntimeTreeItem ) ; globalStateUpdateSpy . resetHistory ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT , environmentToDelete ) ; globalStateUpdateSpy . should . not . have . been . called ; showFabricEnvironmentQuickPickBoxStub . should . not . have . been . called ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 3 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; environments [ 2 ] . should . deep . equal ( myEnvironmentB ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , 'otherLocal' ) ; executeCommandStub . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; removeLocalRuntimeSpy . should . have . been . calledOnceWithExactly ( 'otherLocal' ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted otherLocal environment` ) ; const localSettings = await vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . FABRIC_RUNTIME , vscode . ConfigurationTarget . Global ) ; localSettings . should . deep . equal ( originalSettings ) ; } ) ; it ( `should be able to delete the ${ FabricRuntimeUtil . LOCAL_FABRIC } environment from the command` , async ( ) => { commandSpy . restore ( ) ; const executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; executeCommandStub . withArgs ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC ) . resolves ( ) ; const localEntry = await FabricEnvironmentRegistry . instance ( ) . get ( FabricRuntimeUtil . LOCAL_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub . resolves ( [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEntry } ] ) ; const globalState = GlobalState . get ( ) ; globalState . deletedOneOrgLocalFabric = false ; await GlobalState . update ( globalState ) ; globalStateUpdateSpy . resetHistory ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; globalStateUpdateSpy . should . have . been . calledOnce ; const updateCall = globalStateUpdateSpy . getCall ( 0 ) . args [ 0 ] ; updateCall . deletedOneOrgLocalFabric . should . equal ( true ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . should . deep . equal ( myEnvironmentA ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentB ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC ) ; executeCommandStub . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; removeLocalRuntimeSpy . should . have . been . calledOnceWithExactly ( FabricRuntimeUtil . LOCAL_FABRIC ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ FabricRuntimeUtil . LOCAL_FABRIC } environment` ) ; const localSettings = await vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . FABRIC_RUNTIME , vscode . ConfigurationTarget . Global ) ; localSettings . should . deep . equal ( { } ) ; } ) ; it ( `should be able to delete a local microfab environment from the command and ignore refreshing during teardown` , async ( ) => { commandSpy . restore ( ) ; const executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; executeCommandStub . withArgs ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC ) . resolves ( ) ; const localEntry = await FabricEnvironmentRegistry . instance ( ) . get ( FabricRuntimeUtil . LOCAL_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub . resolves ( [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEntry } ] ) ; const globalState = GlobalState . get ( ) ; globalState . deletedOneOrgLocalFabric = false ; await GlobalState . update ( globalState ) ; globalStateUpdateSpy . resetHistory ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT , undefined , undefined , true ) ; globalStateUpdateSpy . should . have . been . calledOnce ; const updateCall = globalStateUpdateSpy . getCall ( 0 ) . args [ 0 ] ; updateCall . deletedOneOrgLocalFabric . should . equal ( true ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . should . deep . equal ( myEnvironmentA ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentB ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC , true ) ; executeCommandStub . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; removeLocalRuntimeSpy . should . have . been . calledOnceWithExactly ( FabricRuntimeUtil . LOCAL_FABRIC ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ FabricRuntimeUtil . LOCAL_FABRIC } environment` ) ; const localSettings = await vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . FABRIC_RUNTIME , vscode . ConfigurationTarget . Global ) ; localSettings . should . deep . equal ( { } ) ; } ) ; it ( 'should be able to delete a local microfab from the command' , async ( ) => { const settings = { } ; settings [ 'OtherLocalMicrofab' ] = 8081 ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . FABRIC_RUNTIME , settings , vscode . ConfigurationTarget . Global ) ; const otherLocalEnvEntry = new FabricEnvironmentRegistryEntry ( { name : 'OtherLocalMicrofab' , managedRuntime : true , numberOfOrgs : 1 , environmentType : EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT , environmentDirectory : path . join ( __dirname , '..' , 'data' , 'OtherLocalMicrofab' ) , fabricCapabilities : UserInputUtil . V2_0 } ) ; await FabricEnvironmentRegistry . instance ( ) . add ( otherLocalEnvEntry ) ; commandSpy . restore ( ) ; const executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; executeCommandStub . withArgs ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , 'OtherLocalMicrofab' ) . resolves ( ) ; showFabricEnvironmentQuickPickBoxStub . resolves ( [ { label : 'OtherLocalMicrofab' , data : otherLocalEnvEntry } ] ) ; const globalState = GlobalState . get ( ) ; globalState . deletedOneOrgLocalFabric = false ; await GlobalState . update ( globalState ) ; globalStateUpdateSpy . resetHistory ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; globalStateUpdateSpy . should . not . have . been . called ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 3 ) ; environments [ 0 ] . name . should . equal ( FabricRuntimeUtil . LOCAL_FABRIC ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentA ) ; environments [ 2 ] . should . deep . equal ( myEnvironmentB ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , 'OtherLocalMicrofab' ) ; executeCommandStub . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; removeLocalRuntimeSpy . should . have . been . calledOnceWithExactly ( 'OtherLocalMicrofab' ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted OtherLocalMicrofab environment` ) ; const localSettings = await vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . FABRIC_RUNTIME , vscode . ConfigurationTarget . Global ) ; localSettings . should . deep . equal ( { } ) ; } ) ; it ( 'should warn user if error occurs whilst tearing down local microfab environment during deletion' , async ( ) => { commandSpy . restore ( ) ; const executeCommandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) ; executeCommandStub . callThrough ( ) ; const error = new Error ( 'something went wrong' ) ; executeCommandStub . withArgs ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC ) . throws ( error ) ; const localEntry = await FabricEnvironmentRegistry . instance ( ) . get ( FabricRuntimeUtil . LOCAL_FABRIC ) ; showFabricEnvironmentQuickPickBoxStub . resolves ( [ { label : FabricRuntimeUtil . LOCAL_FABRIC , data : localEntry } ] ) ; const globalState = GlobalState . get ( ) ; globalState . deletedOneOrgLocalFabric = false ; await GlobalState . update ( globalState ) ; globalStateUpdateSpy . resetHistory ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_ENVIRONMENT ) ; globalStateUpdateSpy . should . have . been . calledOnce ; const updateCall = globalStateUpdateSpy . getCall ( 0 ) . args [ 0 ] ; updateCall . deletedOneOrgLocalFabric . should . equal ( true ) ; showFabricEnvironmentQuickPickBoxStub . should . have . been . calledOnceWithExactly ( 'Choose the environment(s) that you want to delete' , true , false ) ; getAllSpy . should . have . been . calledOnceWithExactly ( ) ; environments = await FabricEnvironmentRegistry . instance ( ) . getAll ( ) ; environments . length . should . equal ( 2 ) ; environments [ 0 ] . should . deep . equal ( myEnvironmentA ) ; environments [ 1 ] . should . deep . equal ( myEnvironmentB ) ; executeCommandStub . should . have . been . calledWith ( ExtensionCommands . TEARDOWN_FABRIC , undefined , true , FabricRuntimeUtil . LOCAL_FABRIC ) ; executeCommandStub . should . not . have . been . calledWith ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) ; logSpy . getCall ( 0 ) . should . have . been . calledWithExactly ( LogType . INFO , undefined , `delete environment` ) ; logSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . WARNING , undefined , `Error whilst tearing down ${ FabricRuntimeUtil . LOCAL_FABRIC } environment: ${ error . message }` ) ; logSpy . getCall ( 2 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , `Successfully deleted ${ FabricRuntimeUtil . LOCAL_FABRIC } environment` ) ; const localSettings = await vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . FABRIC_RUNTIME , vscode . ConfigurationTarget . Global ) ; localSettings . should . deep . equal ( { } ) ; } ) ; } ) ; } ) ;