mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 07:25:10 +00:00
Add new chaincode and javascript application to demostrate the use of chaincode events and block events with private data. Signed-off-by: Bret Harrison <beharrison@nc.rr.com>
224 lines
7.6 KiB
JavaScript
224 lines
7.6 KiB
JavaScript
'use strict';
|
|
const sinon = require('sinon');
|
|
const chai = require('chai');
|
|
const sinonChai = require('sinon-chai');
|
|
const expect = chai.expect;
|
|
|
|
const { Context } = require('fabric-contract-api');
|
|
const { ChaincodeStub, ClientIdentity } = require('fabric-shim');
|
|
|
|
const AssetTransfer = require('../lib/assetTransferEvents.js');
|
|
|
|
let assert = sinon.assert;
|
|
chai.use(sinonChai);
|
|
|
|
describe('Asset Transfer Events Tests', () => {
|
|
let transactionContext, chaincodeStub, clientIdentity, asset;
|
|
let transientMap, asset_properties;
|
|
|
|
beforeEach(() => {
|
|
transactionContext = new Context();
|
|
|
|
chaincodeStub = sinon.createStubInstance(ChaincodeStub);
|
|
chaincodeStub.getMspID.returns('org1');
|
|
transactionContext.setChaincodeStub(chaincodeStub);
|
|
|
|
clientIdentity = sinon.createStubInstance(ClientIdentity);
|
|
clientIdentity.getMSPID.returns('org1');
|
|
transactionContext.clientIdentity = clientIdentity;
|
|
|
|
chaincodeStub.putState.callsFake((key, value) => {
|
|
if (!chaincodeStub.states) {
|
|
chaincodeStub.states = {};
|
|
}
|
|
chaincodeStub.states[key] = value;
|
|
});
|
|
|
|
chaincodeStub.getState.callsFake(async (key) => {
|
|
let ret;
|
|
if (chaincodeStub.states) {
|
|
ret = chaincodeStub.states[key];
|
|
}
|
|
return Promise.resolve(ret);
|
|
});
|
|
|
|
chaincodeStub.deleteState.callsFake(async (key) => {
|
|
if (chaincodeStub.states) {
|
|
delete chaincodeStub.states[key];
|
|
}
|
|
return Promise.resolve(key);
|
|
});
|
|
|
|
chaincodeStub.getStateByRange.callsFake(async () => {
|
|
function* internalGetStateByRange() {
|
|
if (chaincodeStub.states) {
|
|
// Shallow copy
|
|
const copied = Object.assign({}, chaincodeStub.states);
|
|
|
|
for (let key in copied) {
|
|
yield {value: copied[key]};
|
|
}
|
|
}
|
|
}
|
|
|
|
return Promise.resolve(internalGetStateByRange());
|
|
});
|
|
|
|
asset = {
|
|
ID: 'asset1',
|
|
Color: 'blue',
|
|
Size: 5,
|
|
Owner: 'Tomoko',
|
|
AppraisedValue: 300,
|
|
};
|
|
const randomNumber = Math.floor(Math.random() * 100) + 1;
|
|
asset_properties = {
|
|
object_type: 'asset_properties',
|
|
asset_id: 'asset1',
|
|
Price: '90',
|
|
salt: Buffer.from(randomNumber.toString()).toString('hex')
|
|
};
|
|
transientMap = {
|
|
asset_properties: Buffer.from(JSON.stringify(asset_properties))
|
|
};
|
|
});
|
|
|
|
describe('Test CreateAsset', () => {
|
|
it('should return error on CreateAsset', async () => {
|
|
chaincodeStub.putState.rejects('failed inserting key');
|
|
|
|
let assetTransfer = new AssetTransfer();
|
|
try {
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
assert.fail('CreateAsset should have failed');
|
|
} catch(err) {
|
|
expect(err.name).to.equal('failed inserting key');
|
|
}
|
|
});
|
|
|
|
it('should return success on CreateAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString());
|
|
expect(ret).to.eql(asset);
|
|
});
|
|
it('should return success on CreateAsset with transient data', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
chaincodeStub.getTransient.returns(transientMap);
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString());
|
|
expect(ret).to.eql(asset);
|
|
});
|
|
});
|
|
|
|
describe('Test ReadAsset', () => {
|
|
it('should return error on ReadAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
try {
|
|
await assetTransfer.ReadAsset(transactionContext, 'asset2');
|
|
assert.fail('ReadAsset should have failed');
|
|
} catch (err) {
|
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
|
}
|
|
});
|
|
|
|
it('should return success on ReadAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
const assetString = await assetTransfer.ReadAsset(transactionContext, 'asset1');
|
|
const readAsset = JSON.parse(assetString);
|
|
expect(readAsset).to.eql(asset);
|
|
});
|
|
|
|
it('should return success on ReadAsset with private data', async () => {
|
|
asset.asset_properties = asset_properties;
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
chaincodeStub.getPrivateData.returns(Buffer.from(JSON.stringify(asset_properties)));
|
|
const assetString = await assetTransfer.ReadAsset(transactionContext, 'asset1');
|
|
const readAsset = JSON.parse(assetString);
|
|
expect(readAsset).to.eql(asset);
|
|
});
|
|
});
|
|
|
|
describe('Test UpdateAsset', () => {
|
|
it('should return error on UpdateAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
try {
|
|
await assetTransfer.UpdateAsset(transactionContext, 'asset2', 'orange', 10, 'Me', 500);
|
|
assert.fail('UpdateAsset should have failed');
|
|
} catch (err) {
|
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
|
}
|
|
});
|
|
|
|
it('should return success on UpdateAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
await assetTransfer.UpdateAsset(transactionContext, 'asset1', 'orange', 10, 'Me', 500);
|
|
let ret = JSON.parse(await chaincodeStub.getState(asset.ID));
|
|
let expected = {
|
|
ID: 'asset1',
|
|
Color: 'orange',
|
|
Size: 10,
|
|
Owner: 'Me',
|
|
AppraisedValue: 500
|
|
};
|
|
expect(ret).to.eql(expected);
|
|
});
|
|
});
|
|
|
|
describe('Test DeleteAsset', () => {
|
|
it('should return error on DeleteAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
try {
|
|
await assetTransfer.DeleteAsset(transactionContext, 'asset2');
|
|
assert.fail('DeleteAsset should have failed');
|
|
} catch (err) {
|
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
|
}
|
|
});
|
|
|
|
it('should return success on DeleteAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
await assetTransfer.DeleteAsset(transactionContext, asset.ID);
|
|
let ret = await chaincodeStub.getState(asset.ID);
|
|
expect(ret).to.equal(undefined);
|
|
});
|
|
});
|
|
|
|
describe('Test TransferAsset', () => {
|
|
it('should return error on TransferAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
try {
|
|
await assetTransfer.TransferAsset(transactionContext, 'asset2', 'Me');
|
|
assert.fail('DeleteAsset should have failed');
|
|
} catch (err) {
|
|
expect(err.message).to.equal('The asset asset2 does not exist');
|
|
}
|
|
});
|
|
|
|
it('should return success on TransferAsset', async () => {
|
|
let assetTransfer = new AssetTransfer();
|
|
await assetTransfer.CreateAsset(transactionContext, asset.ID, asset.Color, asset.Size, asset.Owner, asset.AppraisedValue);
|
|
|
|
await assetTransfer.TransferAsset(transactionContext, asset.ID, 'Me');
|
|
let ret = JSON.parse((await chaincodeStub.getState(asset.ID)).toString());
|
|
expect(ret).to.eql(Object.assign({}, asset, {Owner: 'Me'}));
|
|
});
|
|
});
|
|
});
|