Added unit tests for query-asset chaincode functions

Signed-off-by: Sijo Cherian <sijo@ibm.com>
This commit is contained in:
Sijo Cherian 2020-08-10 22:51:54 -04:00
parent eadeaab813
commit a16d6c8ea8
3 changed files with 319 additions and 175 deletions

View file

@ -0,0 +1,185 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode_test
import (
"encoding/json"
"fmt"
"testing"
"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
"github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go/chaincode"
"github.com/hyperledger/fabric-samples/asset-transfer-private-data/chaincode-go/chaincode/mocks"
"github.com/stretchr/testify/require"
)
/*
For details on generating the mocks, see comments in the file asset_transfer_test.go
*/
func TestReadAsset(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{}
assetBytes, err := assetTransferCC.ReadAsset(transactionContext, "id1")
require.NoError(t, err)
require.Nil(t, assetBytes)
chaincodeStub.GetPrivateDataReturns(nil, fmt.Errorf("unable to retrieve asset"))
assetBytes, err = assetTransferCC.ReadAsset(transactionContext, "id1")
require.EqualError(t, err, "failed to read asset: unable to retrieve asset")
testAsset := &chaincode.Asset{
ID: "id1",
Type: "testfulasset",
Color: "gray",
Size: 7,
Owner: myOrg1Clientid,
}
setReturnPrivateDataInStub(t, chaincodeStub, testAsset)
assetRead, err := assetTransferCC.ReadAsset(transactionContext, "id1")
require.NoError(t, err)
require.Equal(t, testAsset, assetRead)
}
func TestReadAssetPrivateDetails(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{}
assetBytes, err := assetTransferCC.ReadAssetPrivateDetails(transactionContext, myOrg1PrivCollection, "id1")
require.NoError(t, err)
require.Nil(t, assetBytes)
//read from the collection with no access
chaincodeStub.GetPrivateDataReturns(nil, fmt.Errorf("collection not found"))
assetBytes, err = assetTransferCC.ReadAssetPrivateDetails(transactionContext, myOrg2PrivCollection, "id1")
require.EqualError(t, err, "failed to read asset details: collection not found")
returnPrivData := &chaincode.AssetPrivateDetails{
ID: "id1",
AppraisedValue: 5,
}
setReturnAssetPrivateDetailsInStub(t, chaincodeStub, returnPrivData)
assetRead, err := assetTransferCC.ReadAssetPrivateDetails(transactionContext, myOrg1PrivCollection, "id1")
require.NoError(t, err)
require.Equal(t, returnPrivData, assetRead)
}
func TestReadTransferAgreement(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{}
//TransferAgreement does not exist
assetBytes, err := assetTransferCC.ReadTransferAgreement(transactionContext, "id1")
require.NoError(t, err)
require.Nil(t, assetBytes)
chaincodeStub.GetPrivateDataReturns([]byte(myOrg2Clientid), nil)
expectedData := &chaincode.TransferAgreement{
ID: "id1",
BuyerID: myOrg2Clientid,
}
dataRead, err := assetTransferCC.ReadTransferAgreement(transactionContext, "id1")
require.NoError(t, err)
require.Equal(t, expectedData, dataRead)
}
func TestQueryAssetByOwner(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
asset := &chaincode.Asset{Type: "valuableasset", ID: "asset1", Owner: "user1"}
asset1Bytes, err := json.Marshal(asset)
require.NoError(t, err)
iterator := &mocks.StateQueryIterator{}
iterator.HasNextReturnsOnCall(0, true)
iterator.HasNextReturnsOnCall(1, false)
iterator.NextReturns(&queryresult.KV{Value: asset1Bytes}, nil)
chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil)
assetTransferCC := &chaincode.SmartContract{}
assets, err := assetTransferCC.QueryAssetByOwner(transactionContext, "valuableasset", "user1")
require.NoError(t, err)
require.Equal(t, []*chaincode.Asset{asset}, assets)
iterator.HasNextReturns(true)
iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item"))
assets, err = assetTransferCC.QueryAssetByOwner(transactionContext, "valuableasset", "user1")
require.EqualError(t, err, "failed retrieving next item")
require.Nil(t, assets)
}
func TestQueryAssets(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
//Iterator with no records
iterator := &mocks.StateQueryIterator{}
iterator.HasNextReturns(false)
chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil)
assetTransferCC := &chaincode.SmartContract{}
assets, err := assetTransferCC.QueryAssets(transactionContext, "querystr")
require.NoError(t, err)
require.Equal(t, []*chaincode.Asset{}, assets)
iterator = &mocks.StateQueryIterator{}
chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil)
iterator.HasNextReturns(true)
iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item"))
assets, err = assetTransferCC.QueryAssets(transactionContext, "querystr")
require.EqualError(t, err, "failed retrieving next item")
require.Nil(t, assets)
asset := &chaincode.Asset{Type: "valuableasset", ID: "asset1", Owner: "user1"}
asset1Bytes, err := json.Marshal(asset)
require.NoError(t, err)
iterator = &mocks.StateQueryIterator{}
chaincodeStub.GetPrivateDataQueryResultReturns(iterator, nil)
iterator.HasNextReturnsOnCall(0, true)
iterator.HasNextReturnsOnCall(1, false)
iterator.NextReturns(&queryresult.KV{Value: asset1Bytes}, nil)
assets, err = assetTransferCC.QueryAssets(transactionContext, "querystr")
require.NoError(t, err)
require.Equal(t, []*chaincode.Asset{asset}, assets)
}
func TestGetAssetByRange(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
//Iterator with no records
iterator := &mocks.StateQueryIterator{}
iterator.HasNextReturns(false)
chaincodeStub.GetPrivateDataByRangeReturns(iterator, nil)
assetTransferCC := &chaincode.SmartContract{}
assets, err := assetTransferCC.GetAssetByRange(transactionContext, "st", "end")
require.NoError(t, err)
require.Equal(t, []*chaincode.Asset{}, assets)
iterator = &mocks.StateQueryIterator{}
chaincodeStub.GetPrivateDataByRangeReturns(iterator, nil)
iterator.HasNextReturns(true)
iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item"))
assets, err = assetTransferCC.GetAssetByRange(transactionContext, "st", "end")
require.EqualError(t, err, "failed retrieving next item")
require.Nil(t, assets)
asset := &chaincode.Asset{Type: "valuableasset", ID: "asset1", Owner: "user1"}
asset1Bytes, err := json.Marshal(asset)
require.NoError(t, err)
iterator = &mocks.StateQueryIterator{}
chaincodeStub.GetPrivateDataByRangeReturns(iterator, nil)
iterator.HasNextReturnsOnCall(0, true)
iterator.HasNextReturnsOnCall(1, false)
iterator.NextReturns(&queryresult.KV{Value: asset1Bytes}, nil)
assets, err = assetTransferCC.GetAssetByRange(transactionContext, "st", "end")
require.NoError(t, err)
require.Equal(t, []*chaincode.Asset{asset}, assets)
}

View file

@ -116,14 +116,14 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface)
} }
// Make submitting client the owner // Make submitting client the owner
asset := &Asset{ asset := Asset{
Type: assetInput.Type, Type: assetInput.Type,
ID: assetInput.ID, ID: assetInput.ID,
Color: assetInput.Color, Color: assetInput.Color,
Size: assetInput.Size, Size: assetInput.Size,
Owner: clientID, Owner: clientID,
} }
assetJSONasBytes, err := json.Marshal(asset) assetJSONasBytes, err := json.Marshal(&asset)
if err != nil { if err != nil {
return fmt.Errorf("failed to marshal asset into JSON: %v", err) return fmt.Errorf("failed to marshal asset into JSON: %v", err)
} }
@ -138,12 +138,12 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface)
} }
// Save asset details to collection visible to owning organization // Save asset details to collection visible to owning organization
assetPrivateDetails := &AssetPrivateDetails{ assetPrivateDetails := AssetPrivateDetails{
ID: assetInput.ID, ID: assetInput.ID,
AppraisedValue: assetInput.AppraisedValue, AppraisedValue: assetInput.AppraisedValue,
} }
assetPrivateDetailsAsBytes, err := json.Marshal(assetPrivateDetails) // marshal asset details to JSON assetPrivateDetailsAsBytes, err := json.Marshal(&assetPrivateDetails) // marshal asset details to JSON
if err != nil { if err != nil {
return fmt.Errorf("failed to marshal into JSON: %v", err) return fmt.Errorf("failed to marshal into JSON: %v", err)
} }
@ -202,6 +202,14 @@ func (s *SmartContract) AgreeToTransfer(ctx contractapi.TransactionContextInterf
return fmt.Errorf("appraisedValue field must be a positive integer") return fmt.Errorf("appraisedValue field must be a positive integer")
} }
// Read asset from the private data collection
asset, err := s.ReadAsset(ctx, valueJSON.ID)
if err != nil {
return fmt.Errorf("error reading asset: %v", err)
}
if asset == nil {
return fmt.Errorf("%v does not exist", valueJSON.ID)
}
// Verify that the client is submitting request to peer in their organization // Verify that the client is submitting request to peer in their organization
err = verifyClientOrgMatchesPeerOrg(ctx) err = verifyClientOrgMatchesPeerOrg(ctx)
if err != nil { if err != nil {
@ -488,7 +496,7 @@ func (s *SmartContract) DeleteTranferAgreement(ctx contractapi.TransactionContex
} }
if len(assetDeleteInput.ID) == 0 { if len(assetDeleteInput.ID) == 0 {
return fmt.Errorf("ID field must be a non-empty string") return fmt.Errorf("transient input ID field must be a non-empty string")
} }
// Verify that the client is submitting request to peer in their organization // Verify that the client is submitting request to peer in their organization

View file

@ -1,8 +1,12 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode_test package chaincode_test
import ( import (
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"testing" "testing"
@ -139,36 +143,102 @@ func TestCreateAssetSuccessful(t *testing.T) {
require.Equal(t, assetBytes, calledAssetBytes) require.Equal(t, assetBytes, calledAssetBytes)
} }
func TestReadAsset(t *testing.T) { func TestAgreeToTransferBadInput(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1() transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{} assetTransferCC := chaincode.SmartContract{}
assetBytes, err := assetTransferCC.ReadAsset(transactionContext, "id1") assetPrivDetail := &chaincode.AssetPrivateDetails{
require.NoError(t, err) ID: "id1",
require.Nil(t, assetBytes) //no AppraisedValue
}
chaincodeStub.GetPrivateDataReturns(nil, fmt.Errorf("unable to retrieve asset")) setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail)
assetBytes, err = assetTransferCC.ReadAsset(transactionContext, "id1") origAsset := chaincode.Asset{
require.EqualError(t, err, "failed to read asset: unable to retrieve asset")
testAsset := &chaincode.Asset{
ID: "id1", ID: "id1",
Type: "testfulasset", Type: "testfulasset",
Color: "gray", Color: "gray",
Size: 7, Size: 7,
Owner: myOrg1Clientid, Owner: myOrg1Clientid,
} }
setReturnPrivateDataInStub(t, chaincodeStub, testAsset) setReturnPrivateDataInStub(t, chaincodeStub, &origAsset)
assetRead, err := assetTransferCC.ReadAsset(transactionContext, "id1")
require.NoError(t, err) err := assetTransferCC.AgreeToTransfer(transactionContext)
require.Equal(t, testAsset, assetRead) require.EqualError(t, err, "appraisedValue field must be a positive integer")
assetPrivDetail = &chaincode.AssetPrivateDetails{
//no ID
AppraisedValue: 500,
}
setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail)
err = assetTransferCC.AgreeToTransfer(transactionContext)
require.EqualError(t, err, "assetID field must be a non-empty string")
assetPrivDetail = &chaincode.AssetPrivateDetails{
ID: "id1",
AppraisedValue: 500,
}
setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail)
//asset does not exist
setReturnPrivateDataInStub(t, chaincodeStub, nil)
err = assetTransferCC.AgreeToTransfer(transactionContext)
require.EqualError(t, err, "id1 does not exist")
} }
//todo func TestAgreeToTransferSuccessful(t *testing.T) {
// ReadAssetPrivateDetails transactionContext, chaincodeStub := prepMocksAsOrg1()
// AgreeToTransfer assetTransferCC := chaincode.SmartContract{}
assetPrivDetail := &chaincode.AssetPrivateDetails{
ID: "id1",
AppraisedValue: 500,
}
setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail)
origAsset := chaincode.Asset{
ID: "id1",
Type: "testfulasset",
Color: "gray",
Size: 7,
Owner: myOrg1Clientid,
}
setReturnPrivateDataInStub(t, chaincodeStub, &origAsset)
chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil)
err := assetTransferCC.AgreeToTransfer(transactionContext)
require.NoError(t, err)
func TestTransferAsset(t *testing.T) { expectedDataBytes, err := json.Marshal(assetPrivDetail)
calledCollection, calledId, calledWithDataBytes := chaincodeStub.PutPrivateDataArgsForCall(0)
require.Equal(t, myOrg1PrivCollection, calledCollection)
require.Equal(t, "id1", calledId)
require.Equal(t, expectedDataBytes, calledWithDataBytes)
calledCollection, calledId, calledWithDataBytes = chaincodeStub.PutPrivateDataArgsForCall(1)
require.Equal(t, assetCollectionName, calledCollection)
require.Equal(t, transferAgreementObjectType+"id1", calledId)
require.Equal(t, []byte(myOrg1Clientid), calledWithDataBytes)
}
func TestTransferAssetBadInput(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{}
assetNewOwner := &assetTransferTransientInput{
ID: "id1",
BuyerMSP: "",
}
setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner)
setReturnPrivateDataInStub(t, chaincodeStub, &chaincode.Asset{})
err := assetTransferCC.TransferAsset(transactionContext)
require.EqualError(t, err, "buyerMSP field must be a non-empty string")
assetNewOwner = &assetTransferTransientInput{
ID: "id1",
BuyerMSP: myOrg2Msp,
}
setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner)
//asset does not exist
setReturnPrivateDataInStub(t, chaincodeStub, nil)
err = assetTransferCC.TransferAsset(transactionContext)
require.EqualError(t, err, "id1 does not exist")
}
func TestTransferAssetSuccessful(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1() transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{} assetTransferCC := chaincode.SmartContract{}
assetNewOwner := &assetTransferTransientInput{ assetNewOwner := &assetTransferTransientInput{
@ -258,30 +328,6 @@ func TestTransferAssetWithoutAnAgreement(t *testing.T) {
require.EqualError(t, err, "BuyerID not found in TransferAgreement for id1") require.EqualError(t, err, "BuyerID not found in TransferAgreement for id1")
} }
func TestTransferAssetBadInput(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{}
assetNewOwner := &assetTransferTransientInput{
ID: "id1",
BuyerMSP: "",
}
setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner)
setReturnPrivateDataInStub(t, chaincodeStub, &chaincode.Asset{})
err := assetTransferCC.TransferAsset(transactionContext)
require.EqualError(t, err, "buyerMSP field must be a non-empty string")
assetNewOwner = &assetTransferTransientInput{
ID: "id1",
BuyerMSP: myOrg2Msp,
}
setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner)
//asset does not exist
setReturnPrivateDataInStub(t, chaincodeStub, nil)
err = assetTransferCC.TransferAsset(transactionContext)
require.EqualError(t, err, "id1 does not exist")
}
func TestTransferAssetNonMatchingAppraisalValue(t *testing.T) { func TestTransferAssetNonMatchingAppraisalValue(t *testing.T) {
transactionContext, chaincodeStub := prepMocksAsOrg1() transactionContext, chaincodeStub := prepMocksAsOrg1()
assetTransferCC := chaincode.SmartContract{} assetTransferCC := chaincode.SmartContract{}
@ -329,6 +375,20 @@ func prepMocks(orgMSP, clientId string) (*mocks.TransactionContext, *mocks.Chain
return transactionContext, chaincodeStub return transactionContext, chaincodeStub
} }
func setReturnAssetPrivateDetailsInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, assetPrivDetail *chaincode.AssetPrivateDetails) []byte {
assetOwnerBytes := []byte{}
if assetPrivDetail != nil {
var err error
assetOwnerBytes, err = json.Marshal(assetPrivDetail)
require.NoError(t, err)
}
assetPropMap := map[string][]byte{
"asset_value": assetOwnerBytes,
}
chaincodeStub.GetTransientReturns(assetPropMap, nil)
return assetOwnerBytes
}
func setReturnAssetOwnerInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, assetOwner *assetTransferTransientInput) []byte { func setReturnAssetOwnerInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, assetOwner *assetTransferTransientInput) []byte {
assetOwnerBytes := []byte{} assetOwnerBytes := []byte{}
if assetOwner != nil { if assetOwner != nil {
@ -358,136 +418,27 @@ func setReturnAssetPropsInTransientMap(t *testing.T, chaincodeStub *mocks.Chainc
} }
func setReturnPrivateDataInStub(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *chaincode.Asset) []byte { func setReturnPrivateDataInStub(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *chaincode.Asset) []byte {
assetBytes := []byte{} if testAsset == nil {
if testAsset != nil { chaincodeStub.GetPrivateDataReturns(nil, nil)
return nil
} else {
var err error var err error
assetBytes, err = json.Marshal(testAsset) assetBytes, err := json.Marshal(testAsset)
require.NoError(t, err) require.NoError(t, err)
chaincodeStub.GetPrivateDataReturns(assetBytes, nil)
return assetBytes
} }
chaincodeStub.GetPrivateDataReturns(assetBytes, nil)
return assetBytes
} }
/* func setReturnAssetPrivateDetailsInStub(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *chaincode.AssetPrivateDetails) []byte {
func TestReadAsset(t *testing.T) { if testAsset == nil {
chaincodeStub := &mocks.ChaincodeStub{} chaincodeStub.GetPrivateDataReturns(nil, nil)
transactionContext := &mocks.TransactionContext{} return nil
transactionContext.GetStubReturns(chaincodeStub) } else {
var err error
expectedAsset := &chaincode.Asset{ID: "asset1"} assetBytes, err := json.Marshal(testAsset)
bytes, err := json.Marshal(expectedAsset) require.NoError(t, err)
require.NoError(t, err) chaincodeStub.GetPrivateDataReturns(assetBytes, nil)
return assetBytes
chaincodeStub.GetStateReturns(bytes, nil) }
assetTransferCC := chaincode.SmartContract{}
asset, err := assetTransferCC.ReadAsset(transactionContext, "")
require.NoError(t, err)
require.Equal(t, expectedAsset, asset)
chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset"))
_, err = assetTransferCC.ReadAsset(transactionContext, "")
require.EqualError(t, err, "failed to read from world state: unable to retrieve asset")
chaincodeStub.GetStateReturns(nil, nil)
asset, err = assetTransferCC.ReadAsset(transactionContext, "asset1")
require.EqualError(t, err, "the asset asset1 does not exist")
require.Nil(t, asset)
} }
func TestUpdateAsset(t *testing.T) {
chaincodeStub := &mocks.ChaincodeStub{}
transactionContext := &mocks.TransactionContext{}
transactionContext.GetStubReturns(chaincodeStub)
expectedAsset := &chaincode.Asset{ID: "asset1"}
bytes, err := json.Marshal(expectedAsset)
require.NoError(t, err)
chaincodeStub.GetStateReturns(bytes, nil)
assetTransferCC := chaincode.SmartContract{}
err = assetTransferCC.UpdateAsset(transactionContext, "", "", 0, "", 0)
require.NoError(t, err)
chaincodeStub.GetStateReturns(nil, nil)
err = assetTransferCC.UpdateAsset(transactionContext, "asset1", "", 0, "", 0)
require.EqualError(t, err, "the asset asset1 does not exist")
chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset"))
err = assetTransferCC.UpdateAsset(transactionContext, "asset1", "", 0, "", 0)
require.EqualError(t, err, "failed to read from world state: unable to retrieve asset")
}
func TestDeleteAsset(t *testing.T) {
chaincodeStub := &mocks.ChaincodeStub{}
transactionContext := &mocks.TransactionContext{}
transactionContext.GetStubReturns(chaincodeStub)
asset := &chaincode.Asset{ID: "asset1"}
bytes, err := json.Marshal(asset)
require.NoError(t, err)
chaincodeStub.GetStateReturns(bytes, nil)
chaincodeStub.DelStateReturns(nil)
assetTransferCC := chaincode.SmartContract{}
err = assetTransferCC.DeleteAsset(transactionContext, "")
require.NoError(t, err)
chaincodeStub.GetStateReturns(nil, nil)
err = assetTransferCC.DeleteAsset(transactionContext, "asset1")
require.EqualError(t, err, "the asset asset1 does not exist")
chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset"))
err = assetTransferCC.DeleteAsset(transactionContext, "")
require.EqualError(t, err, "failed to read from world state: unable to retrieve asset")
}
func TestTransferAsset(t *testing.T) {
chaincodeStub := &mocks.ChaincodeStub{}
transactionContext := &mocks.TransactionContext{}
transactionContext.GetStubReturns(chaincodeStub)
asset := &chaincode.Asset{ID: "asset1"}
bytes, err := json.Marshal(asset)
require.NoError(t, err)
chaincodeStub.GetStateReturns(bytes, nil)
assetTransferCC := chaincode.SmartContract{}
err = assetTransferCC.TransferAsset(transactionContext, "", "")
require.NoError(t, err)
chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset"))
err = assetTransferCC.TransferAsset(transactionContext, "", "")
require.EqualError(t, err, "failed to read from world state: unable to retrieve asset")
}
func TestGetAllAssets(t *testing.T) {
asset := &chaincode.Asset{ID: "asset1"}
bytes, err := json.Marshal(asset)
require.NoError(t, err)
iterator := &mocks.StateQueryIterator{}
iterator.HasNextReturnsOnCall(0, true)
iterator.HasNextReturnsOnCall(1, false)
iterator.NextReturns(&queryresult.KV{Value: bytes}, nil)
chaincodeStub := &mocks.ChaincodeStub{}
transactionContext := &mocks.TransactionContext{}
transactionContext.GetStubReturns(chaincodeStub)
chaincodeStub.GetStateByRangeReturns(iterator, nil)
assetTransferCC := &chaincode.SmartContract{}
assets, err := assetTransferCC.GetAllAssets(transactionContext)
require.NoError(t, err)
require.Equal(t, []*chaincode.Asset{asset}, assets)
iterator.HasNextReturns(true)
iterator.NextReturns(nil, fmt.Errorf("failed retrieving next item"))
assets, err = assetTransferCC.GetAllAssets(transactionContext)
require.EqualError(t, err, "failed retrieving next item")
require.Nil(t, assets)
chaincodeStub.GetStateByRangeReturns(nil, fmt.Errorf("failed retrieving all assets"))
assets, err = assetTransferCC.GetAllAssets(transactionContext)
require.EqualError(t, err, "failed retrieving all assets")
require.Nil(t, assets)
}*/