Skip to content
This repository has been archived by the owner on Jan 31, 2023. It is now read-only.

Commit

Permalink
Adding basic evaluate functionality to the transaction view
Browse files Browse the repository at this point in the history
Signed-off-by: Erin Hughes <Erin.Hughes@ibm.com>
  • Loading branch information
erin-hughes committed Nov 26, 2019
1 parent 1fa9582 commit 7b9c652
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,27 @@ export async function openTransactionView(treeItem?: InstantiatedTreeItem): Prom
const chaincodes: Array<FabricChaincode> = await connection.getInstantiatedChaincode(thisChannelName); // returns array of objects
for (const chaincode of chaincodes) {
metadataObj = await connection.getMetadata(chaincode.name, thisChannelName);
contract = metadataObj.contracts[Object.keys(metadataObj.contracts)[0]];
data = {
name: chaincode.name,
version: chaincode.version,
channel: thisChannelName,
label: chaincode.name + '@' + chaincode.version,
transactions: contract.transactions,
namespace: contract.name
};
instantiatedChaincodes.push(data);
const contractsObject: any = metadataObj.contracts;
Object.keys(contractsObject).forEach((key: string) => {
if (key !== 'org.hyperledger.fabric' && (contractsObject[key].transactions.length > 0)) {
contract = metadataObj.contracts[key];
data = {
name: chaincode.name,
version: chaincode.version,
channel: thisChannelName,
label: chaincode.name + '@' + chaincode.version,
transactions: contract.transactions,
namespace: contract.name
};
instantiatedChaincodes.push(data);
}
});
}
}

const appState: {} = {
smartContracts: instantiatedChaincodes,
activeSmartContract: instantiatedChaincodes.filter((obj: any) => obj.label === smartContractLabel)[0]
activeSmartContract: instantiatedChaincodes.find((obj: any) => obj.label === smartContractLabel)
};

const context: vscode.ExtensionContext = GlobalState.getExtensionContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ export class ExtensionUtil {
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.TEST_ALL_SMART_CONTRACT, (chaincode: InstantiatedContractTreeItem) => testSmartContract(true, chaincode)));
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.TEST_SMART_CONTRACT, (treeItem: ContractTreeItem | InstantiatedTreeItem) => testSmartContract(false, treeItem)));
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.SUBMIT_TRANSACTION, (transactionTreeItem?: InstantiatedTreeItem | TransactionTreeItem, channelName?: string, smartContract?: string, transactionObject?: any) => submitTransaction(false, transactionTreeItem, channelName, smartContract, transactionObject)));
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.EVALUATE_TRANSACTION, (transactionTreeItem?: InstantiatedTreeItem | TransactionTreeItem, channelName?: string, smartContract?: string) => submitTransaction(true, transactionTreeItem, channelName, smartContract)));
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.EVALUATE_TRANSACTION, (transactionTreeItem?: InstantiatedTreeItem | TransactionTreeItem, channelName?: string, smartContract?: string, transactionObject?: any) => submitTransaction(true, transactionTreeItem, channelName, smartContract, transactionObject)));
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.UPGRADE_SMART_CONTRACT, (instantiatedChainCodeTreeItem?: InstantiatedTreeItem, channelName?: string, peerNames?: Array<string>) => upgradeSmartContract(instantiatedChainCodeTreeItem, channelName, peerNames)));
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.CREATE_NEW_IDENTITY, (certificateAuthorityTreeItem?: CertificateAuthorityTreeItem) => createNewIdentity(certificateAuthorityTreeItem)));
context.subscriptions.push(vscode.commands.registerCommand(ExtensionCommands.REFRESH_WALLETS, (element: BlockchainTreeItem) => blockchainWalletExplorerProvider.refresh(element)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export class TransactionView extends ReactView {
panel.webview.onDidReceiveMessage(async (message: {command: string, data: any}) => {
if (message.command === 'submit') {
await vscode.commands.executeCommand(ExtensionCommands.SUBMIT_TRANSACTION, undefined, undefined, undefined, message.data);
} else if (message.command === 'evaluate') {
await vscode.commands.executeCommand(ExtensionCommands.EVALUATE_TRANSACTION, undefined, undefined, undefined, message.data);
}
});
this.loadComponent(panel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ describe('OpenTransactionViewCommand', () => {
name: 'transaction2'
}
],
},
'org.hyperledger.fabric': {
name: 'org.hyperledger.fabric',
transactions: [
{
name: 'GetMetadata'
}
]
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,5 +626,24 @@ describe('SubmitTransactionCommand', () => {
logSpy.should.have.been.calledWith(LogType.SUCCESS, 'Successfully submitted transaction');
reporterStub.should.have.been.calledWith('submit transaction');
});

it('should evaluate a transaction through the transaction view', async () => {
const transactionObject: any = {
smartContract: 'myContract',
transactionName: 'transaction1',
channelName: 'myChannel',
args: `["arg1", "arg2", "arg3"]`,
namespace: 'my-contract',
transientData: '',
peerTargetNames: []
};

await vscode.commands.executeCommand(ExtensionCommands.EVALUATE_TRANSACTION, undefined, undefined, undefined, transactionObject);
fabricClientConnectionMock.submitTransaction.should.have.been.calledWith('myContract', 'transaction1', 'myChannel', ['arg1', 'arg2', 'arg3'], 'my-contract');
dockerLogsOutputSpy.should.not.have.been.called;
logSpy.should.have.been.calledWith(LogType.INFO, undefined, `evaluating transaction transaction1 with args arg1,arg2,arg3 on channel myChannel`);
logSpy.should.have.been.calledWith(LogType.SUCCESS, 'Successfully evaluated transaction');
reporterStub.should.have.been.calledWith('evaluate transaction');
});
});
});
30 changes: 30 additions & 0 deletions packages/blockchain-extension/test/webview/TransactionView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,36 @@ describe('TransactionView', () => {
executeCommandStub.should.have.been.calledWith(ExtensionCommands.SUBMIT_TRANSACTION, undefined, undefined, undefined, transactionObject);
});

it(`should handle an 'evaluate' message`, async () => {
const onDidReceiveMessagePromises: any[] = [];

onDidReceiveMessagePromises.push(new Promise((resolve: any): void => {
createWebviewPanelStub.onCall(0).returns({
webview: {
postMessage: mySandBox.stub(),
onDidReceiveMessage: async (callback: any): Promise<void> => {
await callback({
command: 'evaluate',
data: transactionObject
});
resolve();
}
},
reveal: (): void => {
return;
},
onDidDispose: mySandBox.stub(),
onDidChangeViewState: mySandBox.stub()
});
}));

const transactionView: TransactionView = new TransactionView(context, mockAppState);
await transactionView.openView(false);
await Promise.all(onDidReceiveMessagePromises);

executeCommandStub.should.have.been.calledWith(ExtensionCommands.EVALUATE_TRANSACTION, undefined, undefined, undefined, transactionObject);
});

it('should not do anything if it receives an invalid message', async () => {
const onDidReceiveMessagePromises: any[] = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,22 @@ describe('Cypress', () => {
});
});

it('can submit a transaction with the user\'s input', () => {
it(`can submit a transaction with the user's input`, () => {
cy.get('#transaction-name-select').select('transactionOne');
cy.get('#arguments-text-area').type('{leftarrow}{leftarrow}{leftarrow}penguin');

cy.get('#submit-button').click();

cy.get('@postMessageStub').should('be.called');
});

it(`can evaluate a transaction with the user's input`, () => {
cy.get('#transaction-name-select').select('transactionTwo');
cy.get('#arguments-text-area').type('{leftarrow}{leftarrow}{leftarrow}big');

cy.get('#evaluate-button').click();

cy.get('@postMessageStub').should('be.called');
});
});
});
22 changes: 22 additions & 0 deletions packages/blockchain-ui/enzyme/tests/TransactionCreate.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,28 @@ describe('TransactionCreate component', () => {
});
});

it('should attempt to evaluate a transaction when the evaluate button is clicked', async () => {
const component: any = mount(<TransactionCreate activeSmartContract={greenContract} postMessageHandler={postMessageHandlerStub}/>);
component.setState({
activeTransaction: transactionOne,
transactionArguments: 'name: Green\n'
});
component.find('#evaluate-button').at(1).simulate('click');
postMessageHandlerStub.should.have.been.calledOnceWithExactly({
data: {
args: 'Green',
channelName: 'mychannel',
evaluate: true,
namespace: 'GreenContract',
peerTargetNames: [],
smartContract: 'greenContract',
transactionName: 'transactionOne',
transientData: ''
},
command: 'evaluate'
});
});

it('should do nothing if no transaction has been selected', async () => {
const component: any = mount(<TransactionCreate activeSmartContract={greenContract} postMessageHandler={postMessageHandlerStub}/>);
component.find('#submit-button').at(1).simulate('click');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ exports[`TransactionCreate component should render the expected snapshot 1`] = `
className="bx--btn bx--btn--field bx--btn--primary bx--btn--disabled"
disabled={true}
id="evaluate-button"
onClick={[Function]}
tabIndex={0}
type="button"
>
Expand Down
5 changes: 1 addition & 4 deletions packages/blockchain-ui/src/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ const Utils: any = {
},

postToVSCode(message: {command: string, data: any}): void {
vscode.postMessage({
command: message.command,
data: message.data
});
vscode.postMessage(message);
}

};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ class TransactionCreate extends Component<CreateProps, CreateState> {
submitTxn(evaluate: boolean): void {
const activeTransaction: ITransaction = this.state.activeTransaction as ITransaction;

const command: string = evaluate ? 'evaluate' : 'submit';
const args: string = this.parseArgs(activeTransaction, this.state.transactionArguments);

const transactionObject: any = {
command: 'submit',
command: command,
data: {
smartContract: this.state.activeSmartContract.name,
transactionName: activeTransaction.name,
Expand Down Expand Up @@ -159,7 +160,7 @@ class TransactionCreate extends Component<CreateProps, CreateState> {
</div>
</div>
<div className='bx--row'>
<Button size='field' id='evaluate-button' disabled={shouldDisableButtons}>Evaluate</Button>
<Button size='field' id='evaluate-button' disabled={shouldDisableButtons} onClick={(): void => this.submitTxn(true)}>Evaluate</Button>
<Button size='field' id='submit-button' disabled={shouldDisableButtons} onClick={(): void => this.submitTxn(false)}>Submit</Button>
</div>
</div>
Expand Down

0 comments on commit 7b9c652

Please sign in to comment.