'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 fs from 'fs-extra' ; import { TestUtil } from '../TestUtil' ; import { UserInputUtil } from '../../extension/commands/UserInputUtil' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { EnvironmentType , FabricEnvironmentRegistry , FabricEnvironmentRegistryEntry , FabricGatewayRegistryEntry , FabricRuntimeUtil , LogType } from 'ibm-blockchain-platform-common' ; import { SettingConfigurations } from '../../extension/configurations' ; import { VSCodeBlockchainOutputAdapter } from '../../extension/logging/VSCodeBlockchainOutputAdapter' ; import { FabricEnvironmentManager } from '../../extension/fabric/environments/FabricEnvironmentManager' ; import { FabricGatewayConnectionManager } from '../../extension/fabric/FabricGatewayConnectionManager' ; chai . should ( ) ; chai . use ( sinonChai ) ; describe ( 'DeleteExtensionDirectoryCommand' , ( ) => { let mySandBox ; before ( async ( ) => { mySandBox = sinon . createSandbox ( ) ; await TestUtil . setupTests ( mySandBox ) ; } ) ; describe ( 'DeleteExtensionDirectory' , ( ) => { let myEnvironmentA ; let myEnvironmentB ; let removeStub ; let commandStub ; let reloadStub ; let confirmationWarningStub ; let tearDownStub ; let pathExistsStub ; let disconnectGatewayStub ; let disconnectEnvrionmentStub ; let getGatewayRegistryEntryStub ; let getEnvironmentRegistryEntryStub ; let deleteEnvironmentStub ; let logSpy ; let getAllSpy ; beforeEach ( async ( ) => { mySandBox . restore ( ) ; await FabricEnvironmentRegistry . instance ( ) . clear ( ) ; const settings = { } ; settings [ FabricRuntimeUtil . LOCAL_FABRIC ] = 8080 ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . FABRIC_RUNTIME , settings , vscode . ConfigurationTarget . Global ) ; myEnvironmentA = new FabricEnvironmentRegistryEntry ( { name : 'myEnvironmentA' , environmentType : EnvironmentType . LOCAL_MICROFAB_ENVIRONMENT , } ) ; await FabricEnvironmentRegistry . instance ( ) . add ( myEnvironmentA ) ; myEnvironmentB = new FabricEnvironmentRegistryEntry ( { name : 'myEnvironmentB' , environmentType : EnvironmentType . OPS_TOOLS_ENVIRONMENT , } ) ; await FabricEnvironmentRegistry . instance ( ) . add ( myEnvironmentB ) ; await TestUtil . startLocalFabric ( ) ; removeStub = mySandBox . stub ( fs , 'remove' ) . resolves ( ) ; pathExistsStub = mySandBox . stub ( fs , 'pathExists' ) . resolves ( true ) ; commandStub = mySandBox . stub ( vscode . commands , 'executeCommand' ) . callThrough ( ) ; reloadStub = commandStub . withArgs ( 'workbench.action.reloadWindow' ) . resolves ( ) ; tearDownStub = commandStub . withArgs ( ExtensionCommands . TEARDOWN_FABRIC ) . resolves ( ) ; getGatewayRegistryEntryStub = mySandBox . stub ( FabricGatewayConnectionManager . instance ( ) , 'getGatewayRegistryEntry' ) . resolves ( ) ; getEnvironmentRegistryEntryStub = mySandBox . stub ( FabricEnvironmentManager . instance ( ) , 'getEnvironmentRegistryEntry' ) ; disconnectGatewayStub = commandStub . withArgs ( ExtensionCommands . DISCONNECT_GATEWAY ) . resolves ( ) ; disconnectEnvrionmentStub = commandStub . withArgs ( ExtensionCommands . DISCONNECT_ENVIRONMENT ) . resolves ( ) ; deleteEnvironmentStub = mySandBox . stub ( FabricEnvironmentRegistry . instance ( ) , 'delete' ) . callThrough ( ) ; confirmationWarningStub = mySandBox . stub ( UserInputUtil , 'showConfirmationWarningMessage' ) . withArgs ( `This will delete the extension directory. Do you want to continue?` ) . resolves ( true ) ; logSpy = mySandBox . stub ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; getAllSpy = mySandBox . spy ( FabricEnvironmentRegistry . instance ( ) , 'getAll' ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should test the extension directory can be deleted from the command' , async ( ) => { await vscode . commands . executeCommand ( ExtensionCommands . DELETE_DIRECTORY ) ; reloadStub . should . have . been . calledOnce ; tearDownStub . should . have . been . called ; confirmationWarningStub . should . have . been . calledOnce ; removeStub . should . have . been . calledOnce ; getAllSpy . should . have . been . calledOnce ; } ) ; it ( 'should handle an error in tearing down an environment' , async ( ) => { const error = new Error ( 'some error' ) ; tearDownStub . rejects ( error ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_DIRECTORY ) ; confirmationWarningStub . should . have . been . calledOnce ; removeStub . should . have . been . calledOnce ; reloadStub . should . have . been . calledOnce ; getAllSpy . should . have . been . calledOnce ; logSpy . should . have . not . been . called ; } ) ; it ( 'should handle an error in deleting the extension directory' , async ( ) => { const error = new Error ( 'some error' ) ; removeStub . rejects ( error ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_DIRECTORY ) ; confirmationWarningStub . should . have . been . calledOnce ; tearDownStub . should . have . been . called ; reloadStub . should . have . not . been . called ; pathExistsStub . should . have . been . calledOnce ; getAllSpy . should . have . been . calledOnce ; logSpy . should . have . been . calledWithExactly ( LogType . ERROR , `Error deleting directory: ${ error . message }` , `Error deleting directory: ${ error . toString ( ) }` ) ; } ) ; it ( 'should test the extension directory delete command can be cancelled' , async ( ) => { confirmationWarningStub . withArgs ( `This will delete the extension directory. Do you want to continue?` ) . resolves ( false ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_DIRECTORY ) ; confirmationWarningStub . should . have . been . called ; reloadStub . should . have . not . been . called ; tearDownStub . should . have . not . been . called ; tearDownStub . should . have . not . been . called ; removeStub . should . have . not . been . called ; getAllSpy . should . have . not . been . called ; logSpy . should . have . not . been . called ; } ) ; it ( 'should ignore any exceptions other than exceptions caused by deleting the directory' , async ( ) => { const gatewayRegEntry = new FabricGatewayRegistryEntry ( ) ; gatewayRegEntry . name = 'gatewayEntry' ; const environmentRegEntry = new FabricEnvironmentRegistryEntry ( ) ; environmentRegEntry . name = 'environmentEntry' ; getGatewayRegistryEntryStub . resolves ( gatewayRegEntry ) ; getEnvironmentRegistryEntryStub . resolves ( environmentRegEntry ) ; disconnectGatewayStub . rejects ( 'oops1' ) ; disconnectEnvrionmentStub . rejects ( 'oops2' ) ; tearDownStub . rejects ( 'oops3' ) ; deleteEnvironmentStub . rejects ( 'oops4' ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_DIRECTORY ) ; reloadStub . should . have . been . calledOnce ; tearDownStub . should . have . been . called ; confirmationWarningStub . should . have . been . calledOnce ; removeStub . should . have . been . calledOnce ; deleteEnvironmentStub . should . have . been . called ; getAllSpy . should . have . been . calledOnce ; logSpy . should . have . not . been . called ; } ) ; it ( 'should error if extension path is invalid' , async ( ) => { pathExistsStub . resolves ( false ) ; await vscode . commands . executeCommand ( ExtensionCommands . DELETE_DIRECTORY ) ; reloadStub . should . have . not . been . calledOnce ; tearDownStub . should . have . been . called ; confirmationWarningStub . should . have . been . calledOnce ; removeStub . should . have . not . been . called ; getAllSpy . should . have . been . calledOnce ; } ) ; } ) ; } ) ;