'use strict' ; import * as vscode from 'vscode' ; import * as sinon from 'sinon' ; import * as chai from 'chai' ; import * as sinonChai from 'sinon-chai' ; import Axios from 'axios' ; import * as fs from 'fs-extra' ; import * as shell from 'shelljs' ; import * as path from 'path' ; import { SampleView } from '../../extension/webview/SampleView' ; import { VSCodeBlockchainOutputAdapter } from '../../extension/logging/VSCodeBlockchainOutputAdapter' ; import { CommandUtil } from '../../extension/util/CommandUtil' ; import { RepositoryRegistry } from '../../extension/registries/RepositoryRegistry' ; import { UserInputUtil } from '../../extension/commands/UserInputUtil' ; import * as ejs from 'ejs' ; import { LogType } from 'ibm-blockchain-platform-common' ; import { View } from '../../extension/webview/View' ; import { Reporter } from '../../extension/util/Reporter' ; import { RepositoryRegistryEntry } from '../../extension/registries/RepositoryRegistryEntry' ; import { TestUtil } from '../TestUtil' ; import { TimerUtil } from '../../extension/util/TimerUtil' ; const should = chai . should ( ) ; chai . use ( sinonChai ) ; describe ( 'SampleView' , ( ) => { let mySandBox ; let repositoryName ; let createWebviewPanelStub ; let context ; let sendCommandWithOutputAndProgress ; let sendTelemetryEventStub ; beforeEach ( async ( ) => { mySandBox = sinon . createSandbox ( ) ; await TestUtil . setupTests ( mySandBox ) ; repositoryName = 'hyperledger/fabric-samples' ; await RepositoryRegistry . instance ( ) . clear ( ) ; const repoEntry = new RepositoryRegistryEntry ( ) ; repoEntry . path = '/some/path' ; repoEntry . name = repositoryName ; await RepositoryRegistry . instance ( ) . add ( repoEntry ) ; context = { extensionPath : 'path' } as vscode . ExtensionContext ; mySandBox . spy ( vscode . commands , 'executeCommand' ) ; createWebviewPanelStub = mySandBox . stub ( vscode . window , 'createWebviewPanel' ) ; createWebviewPanelStub . returns ( { webview : { onDidReceiveMessage : mySandBox . stub ( ) , asWebviewUri : mySandBox . stub ( ) } , reveal : ( ) : void => { return ; } , title : 'FabCar' , onDidDispose : mySandBox . stub ( ) , onDidChangeViewState : mySandBox . stub ( ) , _isDisposed : false } ) ; sendCommandWithOutputAndProgress = mySandBox . stub ( CommandUtil , 'sendCommandWithOutputAndProgress' ) . resolves ( ) ; View [ 'openPanels' ] . splice ( 0 , View [ 'openPanels' ] . length ) ; sendTelemetryEventStub = mySandBox . stub ( Reporter . instance ( ) , 'sendTelemetryEvent' ) ; } ) ; afterEach ( ( ) => { mySandBox . restore ( ) ; } ) ; it ( 'should register and show sample page' , async ( ) => { const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; createWebviewPanelStub . should . have . been . called ; sendTelemetryEventStub . should . have . been . calledOnceWithExactly ( 'openedView' , { openedView : 'FabCar' } ) ; } ) ; it ( 'should do nothing if command not recognised' , async ( ) => { const onDidReceiveMessagePromises = [ ] ; const postMessageStub = mySandBox . stub ( ) . resolves ( ) ; onDidReceiveMessagePromises . push ( new Promise ( ( resolve ) : void => { createWebviewPanelStub . onCall ( 0 ) . returns ( { webview : { onDidReceiveMessage : async ( callback ) : Promise < void > => { await callback ( { command : 'unknown-command' } ) ; resolve ( ) ; } , postMessage : postMessageStub , asWebviewUri : mySandBox . stub ( ) } , reveal : ( ) : void => { return ; } , onDidDispose : mySandBox . stub ( ) , onDidChangeViewState : mySandBox . stub ( ) , _isDisposed : false } ) ; } ) ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; const htmlSpy = mySandBox . spy ( sampleView , 'getHTMLString' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; createWebviewPanelStub . getCall ( 0 ) . should . have . been . calledWith ( 'FabCar' , 'FabCar Sample' , vscode . ViewColumn . One , { enableScripts : true , retainContextWhenHidden : false , enableCommandUris : true , localResourceRoots : [ vscode . Uri . file ( path . join ( context . extensionPath , 'resources' ) ) , vscode . Uri . file ( path . join ( context . extensionPath , 'build' ) ) ] } ) ; htmlSpy . should . have . been . calledOnce ; postMessageStub . should . not . have . been . called ; } ) ; it ( 'should dispose sample page' , async ( ) => { const onDidReceiveMessagePromises = [ ] ; const disposeStub = mySandBox . stub ( ) . yields ( ) ; onDidReceiveMessagePromises . push ( new Promise ( ( resolve ) : void => { createWebviewPanelStub . onCall ( 0 ) . returns ( { title : 'FabCar Sample' , webview : { onDidReceiveMessage : async ( callback ) : Promise < void > => { await callback ( { command : 'unknown-command' } ) ; resolve ( ) ; } , postMessage : mySandBox . stub ( ) . resolves ( ) , asWebviewUri : mySandBox . stub ( ) } , reveal : ( ) : void => { return ; } , onDidDispose : disposeStub , onDidChangeViewState : mySandBox . stub ( ) , _isDisposed : false } ) ; } ) ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; createWebviewPanelStub . getCall ( 0 ) . should . have . been . calledWith ( 'FabCar' , 'FabCar Sample' , vscode . ViewColumn . One , { enableScripts : true , retainContextWhenHidden : false , enableCommandUris : true , localResourceRoots : [ vscode . Uri . file ( path . join ( context . extensionPath , 'resources' ) ) , vscode . Uri . file ( path . join ( context . extensionPath , 'build' ) ) ] } ) ; disposeStub . should . have . been . called ; } ) ; it ( 'should reveal panel if open already' , async ( ) => { const onDidReceiveMessagePromises = [ ] ; onDidReceiveMessagePromises . push ( new Promise ( ( resolve ) : void => { createWebviewPanelStub . onCall ( 0 ) . returns ( { webview : { onDidReceiveMessage : async ( callback ) : Promise < void > => { await callback ( { command : 'openSample' , repoName : 'hyperledger/fabric-samples' , sampleName : 'FabCar' } ) ; resolve ( ) ; } , asWebviewUri : mySandBox . stub ( ) } , title : 'FabCar Sample' , reveal : ( ) : void => { return ; } , onDidDispose : mySandBox . stub ( ) , onDidChangeViewState : mySandBox . stub ( ) , _isDisposed : false } ) ; } ) ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; should . equal ( createWebviewPanelStub . getCall ( 1 ) , null ) ; } ) ; describe ( 'getHTMLString' , ( ) => { it ( 'should get correct html when not cloned' , async ( ) => { const readme = `# FabCar README

            This is the readme` ; await RepositoryRegistry . instance ( ) . clear ( ) ; const AxiosStub = mySandBox . stub ( Axios , 'get' ) . resolves ( { data : readme } ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; const webview = { asWebviewUri : mySandBox . stub ( ) } ; const samplePageHtml = await sampleView . getHTMLString ( webview ) ; AxiosStub . should . have . been . calledWith ( 'https://raw.githubusercontent.com/hyperledger/fabric-samples/main/README.md' ) ; samplePageHtml . should . contain ( `<h1 id="sample-title">FabCar Sample</h1>` ) ; samplePageHtml . should . contain ( `<button class="clone-button" onclick="cloneRepository()">Clone</button>` ) ; samplePageHtml . should . contain ( `<h1 id="fabcarreadme">FabCar README</h1>` ) ; samplePageHtml . should . contain ( `<div class="cell">FabCar Contract</div>` ) ; samplePageHtml . should . contain ( `<button disabled class="open-button" onclick="openFile('contracts','FabCar Contract','Go')">Open Locally</button>` ) ; samplePageHtml . should . contain ( `<button disabled class="open-button" onclick="openFile('applications','JavaScript Application','JavaScript')">Open Locally</button>` ) ; samplePageHtml . should . contain ( `<button disabled class="open-button" onclick="openFile('applications','TypeScript Application','TypeScript')">Open Locally</button>` ) ; } ) ; it ( 'should display everything excluding the readme when there is no internet connection and the repository has not been cloned' , async ( ) => { const outputAdapterSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; const error = new Error ( 'error happened' ) ; mySandBox . stub ( Axios , 'get' ) . rejects ( error ) ; mySandBox . stub ( ejs , 'renderFile' ) . callThrough ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; const webview = { asWebviewUri : mySandBox . stub ( ) } ; const samplePageHtml = await sampleView . getHTMLString ( webview ) ; samplePageHtml . should . contain ( `<div id='readme' class="showMore showMore-theme">No internet connection - unable to retrieve the README.</div>` ) ; outputAdapterSpy . should . have . been . calledWith ( LogType . WARNING , 'Unable to retrieve README' ) ; } ) ; it ( 'should throw error if not able to render file' , async ( ) => { const readme = `# FabCar README

            This is the readme` ; mySandBox . stub ( Axios , 'get' ) . resolves ( { data : readme } ) ; const error = new Error ( 'error happened' ) ; mySandBox . stub ( ejs , 'renderFile' ) . yields ( error ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; const webview = { asWebviewUri : mySandBox . stub ( ) } ; await sampleView . getHTMLString ( webview ) . should . be . rejectedWith ( error ) ; } ) ; it ( 'should get correct html when cloned' , async ( ) => { const readme = `# FabCar README

            This is the readme` ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const AxiosStub = mySandBox . stub ( Axios , 'get' ) . resolves ( { data : readme } ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; const webview = { asWebviewUri : mySandBox . stub ( ) } ; const samplePageHtml = await sampleView . getHTMLString ( webview ) ; AxiosStub . should . have . been . calledWith ( 'https://raw.githubusercontent.com/hyperledger/fabric-samples/main/README.md' ) ; samplePageHtml . should . contain ( `<h1 id="sample-title">FabCar Sample</h1>` ) ; samplePageHtml . should . contain ( `<div class="repository-config-item">Cloned to: /some/path</div>` ) ; samplePageHtml . should . contain ( `<div class="repository-config-item"><a href="#" onclick="cloneRepository(true)">Clone again</a></div>` ) ; samplePageHtml . should . contain ( `<h1 id="fabcarreadme">FabCar README</h1>` ) ; samplePageHtml . should . contain ( `<div class="cell">FabCar Contract</div>` ) ; samplePageHtml . should . contain ( `<button class="open-button" onclick="openFile('contracts','FabCar Contract','Go')">Open Locally</button>` ) ; samplePageHtml . should . contain ( `<button class="open-button" onclick="openFile('applications','JavaScript Application','JavaScript')">Open Locally</button>` ) ; samplePageHtml . should . contain ( `<button class="open-button" onclick="openFile('applications','TypeScript Application','TypeScript')">Open Locally</button>` ) ; } ) ; it ( 'should get correct html when cloned and there is no internet connection' , async ( ) => { const error = new Error ( 'error happened' ) ; mySandBox . stub ( Axios , 'get' ) . rejects ( error ) ; mySandBox . stub ( ejs , 'renderFile' ) . callThrough ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const readFileStub = mySandBox . stub ( fs , 'readFile' ) . resolves ( 'README read here' ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; const webview = { asWebviewUri : mySandBox . stub ( ) } ; const samplePageHtml = await sampleView . getHTMLString ( webview ) ; readFileStub . should . have . been . calledOnce ; samplePageHtml . should . contain ( `<h1 id="sample-title">FabCar Sample</h1>` ) ; samplePageHtml . should . contain ( `<div class="repository-config-item">Cloned to: /some/path</div>` ) ; samplePageHtml . should . contain ( `<div class="repository-config-item"><a href="#" onclick="cloneRepository(true)">Clone again</a></div>` ) ; samplePageHtml . should . contain ( `<p>README read here</p>` ) ; samplePageHtml . should . contain ( `<div class="cell">FabCar Contract</div>` ) ; samplePageHtml . should . contain ( `<button class="open-button" onclick="openFile('contracts','FabCar Contract','Go')">Open Locally</button>` ) ; samplePageHtml . should . contain ( `<button class="open-button" onclick="openFile('applications','JavaScript Application','JavaScript')">Open Locally</button>` ) ; samplePageHtml . should . contain ( `<button class="open-button" onclick="openFile('applications','TypeScript Application','TypeScript')">Open Locally</button>` ) ; } ) ; } ) ; describe ( 'getLanguageVersion' , ( ) => { it ( 'should get version of a contract, depending on the language' , async ( ) => { const onDidReceiveMessagePromises = [ ] ; const postMessageStub = mySandBox . stub ( ) . resolves ( ) ; onDidReceiveMessagePromises . push ( new Promise ( ( resolve ) : void => { createWebviewPanelStub . onCall ( 0 ) . returns ( { webview : { onDidReceiveMessage : async ( callback ) : Promise < void > => { await callback ( { command : 'getLanguageVersion' , contractName : 'FabCar Contract' , languageType : 'Go' } ) ; resolve ( ) ; } , postMessage : postMessageStub , asWebviewUri : mySandBox . stub ( ) } , reveal : ( ) : void => { return ; } , onDidDispose : mySandBox . stub ( ) , onDidChangeViewState : mySandBox . stub ( ) , _isDisposed : false } ) ; } ) ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; postMessageStub . should . have . been . calledWith ( { version : '1.0.0' } ) ; } ) ; } ) ; describe ( 'cloneRepository' , ( ) => { let onDidReceiveMessagePromises ; function setUpTest ( reclone ) { onDidReceiveMessagePromises = [ ] ; onDidReceiveMessagePromises . push ( new Promise ( ( resolve ) : void => { createWebviewPanelStub . onCall ( 0 ) . returns ( { webview : { onDidReceiveMessage : async ( callback ) : Promise < void > => { await callback ( { command : 'clone' , repository : 'https://github.com/hyperledger/fabric-samples.git' , recloning : reclone } ) ; resolve ( ) ; } , asWebviewUri : mySandBox . stub ( ) } , reveal : ( ) : void => { return ; } , onDidDispose : mySandBox . stub ( ) , onDidChangeViewState : mySandBox . stub ( ) , _isDisposed : false } ) ; } ) ) ; } it ( 'should clone a repository and save to disk' , async ( ) => { await RepositoryRegistry . instance ( ) . clear ( ) ; setUpTest ( false ) ; const outputAdapterSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; mySandBox . stub ( vscode . window , 'showSaveDialog' ) . resolves ( { fsPath : '/some/path' } ) ; mySandBox . stub ( CommandUtil , 'sendCommandWithProgress' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; outputAdapterSpy . should . have . been . calledTwice ; outputAdapterSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , 'Successfully cloned repository!' ) ; sendTelemetryEventStub . should . have . been . calledWithExactly ( 'Sample Cloned' , { sample : 'FabCar' } ) ; const result = await RepositoryRegistry . instance ( ) . getAll ( ) ; result . should . deep . equal ( [ { name : 'fabric-samples' , path : '/some/path' } ] ) ; } ) ; it ( 'should stop if user cancels dialog' , async ( ) => { setUpTest ( false ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; const outputAdapterSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; mySandBox . stub ( vscode . window , 'showSaveDialog' ) . resolves ( ) ; const sendCommandWithProgressStub = mySandBox . stub ( CommandUtil , 'sendCommandWithProgress' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; outputAdapterSpy . should . not . have . been . called ; sendCommandWithProgressStub . should . not . have . been . called ; await RepositoryRegistry . instance ( ) . getAll ( ) . should . eventually . deep . equal ( [ ] ) ; } ) ; it ( 'should throw an error if repository cannot be cloned' , async ( ) => { setUpTest ( false ) ; const outputAdapterSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; mySandBox . stub ( vscode . window , 'showSaveDialog' ) . resolves ( { fsPath : '/some/path' } ) ; const error = new Error ( 'problem cloning' ) ; mySandBox . stub ( CommandUtil , 'sendCommandWithProgress' ) . throws ( error ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; outputAdapterSpy . should . have . been . calledOnceWithExactly ( LogType . ERROR , `Could not clone sample: ${ error . message }` ) ; } ) ; it ( 'should reclone a repository and update the repository registry' , async ( ) => { setUpTest ( true ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : 'another/path' } ) ; const outputAdapterSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; mySandBox . stub ( vscode . window , 'showSaveDialog' ) . resolves ( { fsPath : '/some/path' } ) ; mySandBox . stub ( CommandUtil , 'sendCommandWithProgress' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; outputAdapterSpy . should . have . been . calledTwice ; outputAdapterSpy . getCall ( 1 ) . should . have . been . calledWithExactly ( LogType . SUCCESS , 'Successfully cloned repository!' ) ; sendTelemetryEventStub . should . have . been . calledWithExactly ( 'Sample Cloned' , { sample : 'FabCar' } ) ; await RepositoryRegistry . instance ( ) . getAll ( ) . should . eventually . deep . equal ( [ { name : 'fabric-samples' , path : '/some/path' } ] ) ; } ) ; } ) ; describe ( 'openFile' , ( ) => { let onDidReceiveMessagePromises = [ ] ; afterEach ( ( ) => { onDidReceiveMessagePromises = [ ] ; } ) ; async function setupTest ( fileType , fileName , language ) { onDidReceiveMessagePromises . push ( new Promise ( ( resolve , reject ) : void => { createWebviewPanelStub . onCall ( 0 ) . returns ( { webview : { onDidReceiveMessage : async ( callback ) : Promise < void > => { try { await callback ( { command : 'open' , fileType : fileType , fileName : fileName , language : language } ) ; resolve ( ) ; } catch ( error ) { reject ( error ) ; } } , asWebviewUri : mySandBox . stub ( ) } , reveal : ( ) : void => { return ; } , onDidDispose : mySandBox . stub ( ) , onDidChangeViewState : mySandBox . stub ( ) , _isDisposed : false } ) ; } ) ) ; } it ( 'should open contract' , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const pathExistsStub = mySandBox . stub ( fs , 'pathExists' ) . resolves ( true ) ; const shellCdStub = mySandBox . stub ( shell , 'cd' ) . returns ( undefined ) ; const sendCommandStub = mySandBox . stub ( CommandUtil , 'sendCommand' ) . resolves ( ) ; mySandBox . stub ( TimerUtil , 'sleep' ) . resolves ( ) ; mySandBox . stub ( UserInputUtil , 'showFolderOptions' ) . resolves ( UserInputUtil . ADD_TO_WORKSPACE ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; pathExistsStub . should . have . been . calledWithExactly ( '/some/path' ) ; shellCdStub . should . have . been . calledOnceWithExactly ( '/some/path' ) ; sendCommandStub . should . have . been . calledOnceWithExactly ( 'git checkout -b main origin/main' ) ; openNewProjectStub . should . have . been . calledOnce ; sendCommandWithOutputAndProgress . should . not . have . been . called ; sendCommandWithOutputAndProgress . should . not . have . been . called ; sendTelemetryEventStub . should . have . been . calledWithExactly ( 'Sample Opened' , { sample : 'FabCar' , name : 'FabCar Contract' , type : 'contracts' , language : 'Go' } ) ; } ) ; it ( `should show error if the repository isn't in the user settings` , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; const logSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; mySandBox . stub ( TimerUtil , 'sleep' ) . resolves ( ) ; mySandBox . stub ( UserInputUtil , 'showFolderOptions' ) . resolves ( UserInputUtil . ADD_TO_WORKSPACE ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . ERROR , 'The location of the cloned repository on the disk is unknown. Try re-cloning the sample repository.' ) ; } ) ; it ( 'should delete the repository from the user settings if the directory cannot be found on disk' , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const logSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; logSpy . should . have . been . calledOnceWithExactly ( LogType . ERROR , `The location of the file(s) you're trying to open is unknown. The sample repository has either been deleted or moved. Try re-cloning the sample repository.` ) ; await RepositoryRegistry . instance ( ) . getAll ( ) . should . eventually . deep . equal ( [ ] ) ; } ) ; it ( 'should return if user doesnt select how to open files' , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const pathExistsStub = mySandBox . stub ( fs , 'pathExists' ) . resolves ( true ) ; const shellCdStub = mySandBox . stub ( shell , 'cd' ) . returns ( undefined ) ; const sendCommandStub = mySandBox . stub ( CommandUtil , 'sendCommand' ) . resolves ( ) ; mySandBox . stub ( TimerUtil , 'sleep' ) . resolves ( ) ; mySandBox . stub ( UserInputUtil , 'showFolderOptions' ) . resolves ( ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; pathExistsStub . should . have . been . calledWithExactly ( '/some/path' ) ; shellCdStub . should . have . been . calledOnceWithExactly ( '/some/path' ) ; sendCommandStub . should . have . been . calledOnceWithExactly ( 'git checkout -b main origin/main' ) ; openNewProjectStub . should . have . not . have . been . called ; } ) ; it ( 'should handle if the local branch already exists' , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const pathExistsStub = mySandBox . stub ( fs , 'pathExists' ) . resolves ( true ) ; const shellCdStub = mySandBox . stub ( shell , 'cd' ) . returns ( undefined ) ; const sendCommandStub = mySandBox . stub ( CommandUtil , 'sendCommand' ) ; const errorOne = new Error ( 'already exists' ) ; sendCommandStub . onCall ( 0 ) . throws ( errorOne ) ; sendCommandStub . onCall ( 1 ) . resolves ( ) ; mySandBox . stub ( TimerUtil , 'sleep' ) . resolves ( ) ; mySandBox . stub ( UserInputUtil , 'showFolderOptions' ) . resolves ( UserInputUtil . ADD_TO_WORKSPACE ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; pathExistsStub . should . have . been . calledWithExactly ( '/some/path' ) ; shellCdStub . should . have . been . calledOnceWithExactly ( '/some/path' ) ; sendCommandStub . getCall ( 1 ) . should . have . been . calledWithExactly ( 'git checkout main' ) ; openNewProjectStub . should . have . been . calledOnce ; sendTelemetryEventStub . should . have . been . calledWithExactly ( 'Sample Opened' , { sample : 'FabCar' , name : 'FabCar Contract' , type : 'contracts' , language : 'Go' } ) ; } ) ; it ( 'should handle other errors' , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const pathExistsStub = mySandBox . stub ( fs , 'pathExists' ) . resolves ( true ) ; const shellCdStub = mySandBox . stub ( shell , 'cd' ) . returns ( undefined ) ; const sendCommandStub = mySandBox . stub ( CommandUtil , 'sendCommand' ) ; const errorOne = new Error ( 'some other error' ) ; sendCommandStub . onCall ( 0 ) . throws ( errorOne ) ; sendCommandStub . onCall ( 1 ) . resolves ( ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) . should . be . rejectedWith ( 'Could not retrieve file(s) from repository: some other error' ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; pathExistsStub . should . have . been . calledWithExactly ( '/some/path' ) ; shellCdStub . should . have . been . calledOnceWithExactly ( '/some/path' ) ; openNewProjectStub . should . have . not . have . been . called ; } ) ; it ( 'should throw an error if a second error is thrown and repository cant be checked out automatically' , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const pathExistsStub = mySandBox . stub ( fs , 'pathExists' ) . resolves ( true ) ; const shellCdStub = mySandBox . stub ( shell , 'cd' ) . returns ( undefined ) ; const sendCommandStub = mySandBox . stub ( CommandUtil , 'sendCommand' ) ; const errorOne = new Error ( 'already exists' ) ; const errorTwo = new Error ( 'couldnt checkout for some reason' ) ; sendCommandStub . onCall ( 0 ) . throws ( errorOne ) ; sendCommandStub . onCall ( 1 ) . throws ( errorTwo ) ; mySandBox . stub ( TimerUtil , 'sleep' ) . resolves ( ) ; mySandBox . stub ( UserInputUtil , 'showFolderOptions' ) . resolves ( UserInputUtil . ADD_TO_WORKSPACE ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) . should . be . rejectedWith ( /Couldn't automatically checkout 'main' branch. Please checkout branch manually. Error: couldnt checkout for some reason/ ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; pathExistsStub . should . have . been . calledWithExactly ( '/some/path' ) ; shellCdStub . should . have . been . calledOnceWithExactly ( '/some/path' ) ; sendCommandStub . getCall ( 1 ) . should . have . been . calledWithExactly ( 'git checkout main' ) ; openNewProjectStub . should . not . have . been . called ; } ) ; it ( 'should open application and run script' , async ( ) => { const logSpy = mySandBox . spy ( VSCodeBlockchainOutputAdapter . instance ( ) , 'log' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; await setupTest ( 'applications' , 'JavaScript Application' , 'JavaScript' ) ; const pathExistsStub = mySandBox . stub ( fs , 'pathExists' ) . resolves ( true ) ; const shellCdStub = mySandBox . stub ( shell , 'cd' ) . returns ( undefined ) ; const sendCommandStub = mySandBox . stub ( CommandUtil , 'sendCommand' ) . resolves ( ) ; mySandBox . stub ( TimerUtil , 'sleep' ) . resolves ( ) ; mySandBox . stub ( UserInputUtil , 'showFolderOptions' ) . resolves ( UserInputUtil . ADD_TO_WORKSPACE ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) . resolves ( ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) ; pathExistsStub . should . have . been . calledWithExactly ( '/some/path' ) ; shellCdStub . should . have . been . calledOnceWithExactly ( '/some/path' ) ; sendCommandStub . should . have . been . calledOnceWithExactly ( 'git checkout -b main origin/main' ) ; openNewProjectStub . should . have . been . calledOnce ; logSpy . should . have . been . calledWith ( LogType . INFO , null , `Starting command "npm" with arguments "install" for sample "FabCar"` ) ; logSpy . should . have . been . calledWith ( LogType . INFO , null , `Finished command "npm" with arguments "install" for sample "FabCar"` ) ; sendCommandWithOutputAndProgress . should . have . been . calledOnceWithExactly ( 'npm' , [ 'install' ] , 'Installing Node.js dependencies ...' , path . join ( '/' , 'some' , 'path' , 'fabcar' , 'javascript' ) , null , sinon . match . any ) ; sendTelemetryEventStub . should . have . been . calledWithExactly ( 'Sample Opened' , { sample : 'FabCar' , name : 'JavaScript Application' , type : 'applications' , language : 'JavaScript' } ) ; } ) ; it ( 'should throw an error if fileType not recognised' , async ( ) => { await setupTest ( 'bob' , 'bob file' , 'Go' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) . should . be . rejectedWith ( /File type not supported/ ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; openNewProjectStub . should . not . have . been . called ; } ) ; it ( 'should throw an error if language not recognised' , async ( ) => { await setupTest ( 'contracts' , 'FabCar Contract' , 'myLanguage' ) ; await RepositoryRegistry . instance ( ) . clear ( ) ; await RepositoryRegistry . instance ( ) . add ( { name : 'fabric-samples' , path : '/some/path' } ) ; const openNewProjectStub = mySandBox . stub ( UserInputUtil , 'openNewProject' ) ; const sampleView = new SampleView ( context , 'fabric-samples' , 'FabCar' ) ; await sampleView . openView ( false ) ; await Promise . all ( onDidReceiveMessagePromises ) . should . be . rejectedWith ( /Language type not supported/ ) ; sendCommandWithOutputAndProgress . should . not . have . been . called ; openNewProjectStub . should . not . have . been . called ; } ) ; } ) ; } ) ;