diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go index f6b66ccd..b74a9450 100644 --- a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go +++ b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go @@ -549,7 +549,7 @@ func (s *SmartContract) CreateUserID(ctx contractapi.TransactionContextInterface return fmt.Errorf("the user with APIId %s already exists", APIId) } else { UUID, err := uuid.NewRandom() - fmt.Printf(UUID.String()) + fmt.Print(UUID.String()) //UUID, err := "Random String", "Even a more random string" //if err == "Random" { if err != nil { @@ -571,7 +571,7 @@ func (s *SmartContract) CreateUserID(ctx contractapi.TransactionContextInterface if err3 != nil { return fmt.Errorf("failed to create new user. %v", err3) } else { - fmt.Print("A new User has been created with the UUID %v", UUID) + fmt.Printf("A new User has been created with the UUID %v", UUID) return nil } @@ -689,7 +689,7 @@ func (s *SmartContract) CreateGroup(ctx contractapi.TransactionContextInterface, return fmt.Errorf("failed to create new Group. %v", err) } - fmt.Print("The Group %v has been created ", group.GroupName) + fmt.Printf("The Group %v has been created ", group.GroupName) return nil } diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer_test.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer_test.go index c6ec5ac5..ad1f8ed9 100644 --- a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer_test.go +++ b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer_test.go @@ -13,7 +13,6 @@ import ( "github.com/hyperledger/fabric-chaincode-go/pkg/cid" "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-contract-api-go/contractapi" - "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" @@ -55,306 +54,6 @@ const myOrg2Msp = "Org2Testmsp" const myOrg2Clientid = "myOrg2Userid" const myOrg2PrivCollection = "Org2TestmspPrivateCollection" -type assetTransientInput struct { - Type string `json:"objectType"` - ID string `json:"assetID"` - Color string `json:"color"` - Size int `json:"size"` - AppraisedValue int `json:"appraisedValue"` -} - -type assetTransferTransientInput struct { - ID string `json:"assetID"` - BuyerMSP string `json:"buyerMSP"` -} - -func TestCreateAssetBadInput(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - // No transient map - err := assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "asset not found in the transient map input") - - // transient map with incomplete asset data - assetPropMap := map[string][]byte{ - "asset_properties": []byte("ill formatted property"), - } - chaincodeStub.GetTransientReturns(assetPropMap, nil) - err = assetTransferCC.CreateAsset(transactionContext) - require.Error(t, err, "Expected error: transient map with incomplete asset data") - require.Contains(t, err.Error(), "failed to unmarshal JSON") - - testAsset := &assetTransientInput{ - Type: "testfulasset", - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - err = assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "assetID field must be a non-empty string") - - testAsset = &assetTransientInput{ - ID: "id1", - Color: "gray", - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - err = assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "objectType field must be a non-empty string") - - // case when asset exists, GetPrivateData returns a valid data from ledger - testAsset = &assetTransientInput{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - AppraisedValue: 500, - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - chaincodeStub.GetPrivateDataReturns([]byte{}, nil) - err = assetTransferCC.CreateAsset(transactionContext) - require.EqualError(t, err, "this asset already exists: id1") -} - -func TestCreateAssetSuccessful(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - testAsset := &assetTransientInput{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - AppraisedValue: 500, - } - setReturnAssetPropsInTransientMap(t, chaincodeStub, testAsset) - err := assetTransferCC.CreateAsset(transactionContext) - require.NoError(t, err) - //Validate PutPrivateData calls - calledCollection, calledId, _ := chaincodeStub.PutPrivateDataArgsForCall(0) - require.Equal(t, assetCollectionName, calledCollection) - require.Equal(t, "id1", calledId) - - expectedPrivateDetails := &chaincode.AssetPrivateDetails{ - ID: "id1", - AppraisedValue: 500, - } - assetBytes, err := json.Marshal(expectedPrivateDetails) - calledCollection, calledId, calledAssetBytes := chaincodeStub.PutPrivateDataArgsForCall(1) - require.Equal(t, myOrg1PrivCollection, calledCollection) - require.Equal(t, "id1", calledId) - require.Equal(t, assetBytes, calledAssetBytes) -} - -func TestAgreeToTransferBadInput(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - - assetPrivDetail := &chaincode.AssetPrivateDetails{ - ID: "id1", - //no AppraisedValue - } - setReturnAssetPrivateDetailsInTransientMap(t, chaincodeStub, assetPrivDetail) - origAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &origAsset) - - err := assetTransferCC.AgreeToTransfer(transactionContext) - 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") -} - -func TestAgreeToTransferSuccessful(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - 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) - - 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() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg2Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - origAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &origAsset) - //to ensure we pass data hash verification - chaincodeStub.GetPrivateDataHashReturns([]byte("datahash"), nil) - //to ensure that ReadTransferAgreement call returns org2 client ID - chaincodeStub.GetPrivateDataReturnsOnCall(1, []byte(myOrg2Clientid), nil) - chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil) - - err := assetTransferCC.TransferAsset(transactionContext) - require.NoError(t, err) - //Validate PutPrivateData calls - expectedNewAsset := origAsset - expectedNewAsset.Owner = myOrg2Clientid - expectedNewAssetBytes, err := json.Marshal(expectedNewAsset) - require.NoError(t, err) - calledCollection, calledId, calledWithAssetBytes := chaincodeStub.PutPrivateDataArgsForCall(0) - require.Equal(t, assetCollectionName, calledCollection) - require.Equal(t, "id1", calledId) - require.Equal(t, expectedNewAssetBytes, calledWithAssetBytes) - calledCollection, calledId = chaincodeStub.DelPrivateDataArgsForCall(0) - require.Equal(t, myOrg1PrivCollection, calledCollection) - require.Equal(t, "id1", calledId) - - calledCollection, calledId = chaincodeStub.DelPrivateDataArgsForCall(1) - require.Equal(t, assetCollectionName, calledCollection) - require.Equal(t, transferAgreementObjectType+"id1", calledId) - -} - -func TestTransferAssetByNonOwner(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg1Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - //Try to transfer asset owned by Org2 - org2Asset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg2Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &org2Asset) - err := assetTransferCC.TransferAsset(transactionContext) - require.EqualError(t, err, "failed transfer verification: error: submitting client identity does not own asset") -} - -func TestTransferAssetWithoutAnAgreement(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg1Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - orgAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &orgAsset) - //to ensure we pass data hash verification - chaincodeStub.GetPrivateDataHashReturns([]byte("datahash"), nil) - chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil) - //ReadTransferAgreement call returns no buyer client ID - chaincodeStub.GetPrivateDataReturnsOnCall(1, []byte{}, nil) - - err := assetTransferCC.TransferAsset(transactionContext) - require.EqualError(t, err, "BuyerID not found in TransferAgreement for id1") -} - -func TestTransferAssetNonMatchingAppraisalValue(t *testing.T) { - transactionContext, chaincodeStub := prepMocksAsOrg1() - assetTransferCC := chaincode.SmartContract{} - assetNewOwner := &assetTransferTransientInput{ - ID: "id1", - BuyerMSP: myOrg2Msp, - } - setReturnAssetOwnerInTransientMap(t, chaincodeStub, assetNewOwner) - - orgAsset := chaincode.Asset{ - ID: "id1", - Type: "testfulasset", - Color: "gray", - Size: 7, - Owner: myOrg1Clientid, - } - setReturnPrivateDataInStub(t, chaincodeStub, &orgAsset) - chaincodeStub.CreateCompositeKeyReturns(transferAgreementObjectType+"id1", nil) - //data hash different in each collection - chaincodeStub.GetPrivateDataHashReturnsOnCall(0, []byte("datahash1"), nil) - chaincodeStub.GetPrivateDataHashReturnsOnCall(1, []byte("datahash2"), nil) - - err := assetTransferCC.TransferAsset(transactionContext) - require.Error(t, err, "Expected failed hash verification") - require.Contains(t, err.Error(), "failed transfer verification: hash for appraised value") -} - func prepMocksAsOrg1() (*mocks.TransactionContext, *mocks.ChaincodeStub) { return prepMocks(myOrg1Msp, myOrg1Clientid) } @@ -375,70 +74,28 @@ func prepMocks(orgMSP, clientId string) (*mocks.TransactionContext, *mocks.Chain 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 TestCreateUserID(t *testing.T) { + chaincodeStub := &mocks.ChaincodeStub{} + transactionContext := &mocks.TransactionContext{} + transactionContext.GetStubReturns(chaincodeStub) + + contract := chaincode.SmartContract{} + err := contract.CreateUserID(transactionContext, "testID", "testOrg") + require.NoError(t, err) } -func setReturnAssetOwnerInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, assetOwner *assetTransferTransientInput) []byte { - assetOwnerBytes := []byte{} - if assetOwner != nil { - var err error - assetOwnerBytes, err = json.Marshal(assetOwner) - require.NoError(t, err) - } - assetPropMap := map[string][]byte{ - "asset_owner": assetOwnerBytes, - } - chaincodeStub.GetTransientReturns(assetPropMap, nil) - return assetOwnerBytes -} +func TestCreateUserIDDuplicate(t *testing.T) { + chaincodeStub := &mocks.ChaincodeStub{} + transactionContext := &mocks.TransactionContext{} + transactionContext.GetStubReturns(chaincodeStub) -func setReturnAssetPropsInTransientMap(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *assetTransientInput) []byte { - assetBytes := []byte{} - if testAsset != nil { - var err error - assetBytes, err = json.Marshal(testAsset) - require.NoError(t, err) - } - assetPropMap := map[string][]byte{ - "asset_properties": assetBytes, - } - chaincodeStub.GetTransientReturns(assetPropMap, nil) - return assetBytes -} + existingUser := &chaincode.User{UUID: "uuid1", APIUserId: []string{"testID"}, Org: "testOrg"} + bytes, err := json.Marshal(existingUser) + require.NoError(t, err) -func setReturnPrivateDataInStub(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *chaincode.Asset) []byte { - if testAsset == nil { - chaincodeStub.GetPrivateDataReturns(nil, nil) - return nil - } else { - var err error - assetBytes, err := json.Marshal(testAsset) - require.NoError(t, err) - chaincodeStub.GetPrivateDataReturns(assetBytes, nil) - return assetBytes - } -} + chaincodeStub.GetStateReturns(bytes, nil) -func setReturnAssetPrivateDetailsInStub(t *testing.T, chaincodeStub *mocks.ChaincodeStub, testAsset *chaincode.AssetPrivateDetails) []byte { - if testAsset == nil { - chaincodeStub.GetPrivateDataReturns(nil, nil) - return nil - } else { - var err error - assetBytes, err := json.Marshal(testAsset) - require.NoError(t, err) - chaincodeStub.GetPrivateDataReturns(assetBytes, nil) - return assetBytes - } + contract := chaincode.SmartContract{} + err = contract.CreateUserID(transactionContext, "testID", "testOrg") + require.EqualError(t, err, "the user with APIId testID already exists") }