fabric-samples/token-sdk/e2e/e2e_test.go
Arne Rutjes 99a1f49da0 add token sdk sample application
Signed-off-by: Arne Rutjes <arne123@gmail.com>
2023-10-10 09:00:23 -04:00

249 lines
7.4 KiB
Go

package e2e
import (
"context"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
var auditor *ClientWithResponses
var issuer *ClientWithResponses
var err error
var CODE string = "TEST"
var alice = Counterparty{
Account: "alice",
Node: "owner1",
}
var bob = Counterparty{
Account: "bob",
Node: "owner1",
}
var dan = Counterparty{
Account: "dan",
Node: "owner2",
}
type ownerAPI struct {
client *ClientWithResponses
}
var owner1 ownerAPI
var owner2 ownerAPI
func TestMain(t *testing.T) {
auditor, err = NewClientWithResponses(getEnv("AUDITOR_URL", "http://localhost:9000/api/v1"))
assert.NoError(t, err, "failed creating client")
issuer, err = NewClientWithResponses(getEnv("ISSUER_URL", "http://localhost:9100/api/v1"))
assert.NoError(t, err, "failed creating client")
client1, err := NewClientWithResponses(getEnv("OWNER1_URL", "http://localhost:9200/api/v1"))
assert.NoError(t, err, "failed creating client")
owner1 = ownerAPI{client: client1}
client2, err := NewClientWithResponses(getEnv("OWNER2_URL", "http://localhost:9300/api/v1"))
assert.NoError(t, err, "failed creating client")
owner2 = ownerAPI{client: client2}
// we have to issue funds to alice first to be able to do the other tests
testIssuance(t)
}
func testIssuance(t *testing.T) {
accBefore := owner1.getAccounts(t)
txBefore := owner1.getTransactions(t, "alice")
id := issue(t, alice, 1000)
acc2 := owner1.getAccounts(t)
txAfter := owner1.getTransactions(t, "alice")
assert.Equal(t, len(txBefore)+1, len(txAfter), "should have 1 issue transaction more", txAfter)
assert.Equal(t, getValue(t, accBefore, "alice")+1000, getValue(t, acc2, "alice"), acc2)
lastTx := txAfter[len(txAfter)-1]
assert.Equal(t, id, lastTx.Id)
assert.Equal(t, int64(1000), lastTx.Amount.Value)
assert.Equal(t, "alice", lastTx.Recipient)
}
func TestTransfer(t *testing.T) {
accBefore := owner1.getAccounts(t)
txBefore := owner1.getTransactions(t, "alice")
id := owner1.transfer(t, "alice", bob, 100)
accAfter := owner1.getAccounts(t)
txAfter := owner1.getTransactions(t, "alice")
assert.Equal(t, getValue(t, accBefore, "alice")-100, getValue(t, accAfter, "alice"), accAfter)
assert.Equal(t, getValue(t, accBefore, "bob")+100, getValue(t, accAfter, "bob"), accAfter)
assert.Greater(t, len(txAfter), len(txBefore))
// on the sender side there may be several transactions, so we check the recipient
txBob := owner1.getTransactions(t, "bob")
lastTx := txBob[len(txBob)-1]
assert.Equal(t, id, lastTx.Id, txBob)
assert.Equal(t, lastTx.Amount.Value, int64(100))
}
func TestTransferToSecondNode(t *testing.T) {
// current state
acc1Before := owner1.getAccounts(t)
tx1Before := owner1.getTransactions(t, "alice")
acc2Before := owner2.getAccounts(t)
tx2Before := owner2.getTransactions(t, "dan")
// transfer 100 from alice to dan
id := owner1.transfer(t, "alice", dan, 100)
// after: alice
acc1After := owner1.getAccounts(t)
assert.Equal(t, getValue(t, acc1Before, "alice")-100, getValue(t, acc1After, "alice"), acc1After) // -100 TEST
tx1After := owner1.getTransactions(t, "alice")
assert.Greater(t, len(tx1After), len(tx1Before)) // +1 tx
// after: dan
acc2After := owner2.getAccounts(t)
assert.Equal(t, getValue(t, acc2Before, "dan")+100, getValue(t, acc2After, "dan"), acc2After) // +100 TEST
tx2After := owner2.getTransactions(t, "dan")
assert.Greater(t, len(tx2After), len(tx2Before)) // + 1 tx
// on the sender side there may be several transactions, so we check the recipient
txDan := owner2.getTransactions(t, "dan")
lastTx := txDan[len(txDan)-1]
assert.Equal(t, id, lastTx.Id, txDan)
assert.Equal(t, lastTx.Amount.Value, int64(100))
owner2.testIfAuditorMatchesOwnerHistory(t, []string{"dan"})
}
func TestRedeem(t *testing.T) {
accBefore := owner1.getAccounts(t)
id := owner1.redeem(t, "alice", 10, "test redeem")
accAfter := owner1.getAccounts(t)
transactions := owner1.getTransactions(t, "alice")
assert.Equal(t, getValue(t, accBefore, "alice")-10, getValue(t, accAfter, "alice"), accAfter)
lastTx := transactions[len(transactions)-1]
assert.Equal(t, id, lastTx.Id, transactions)
assert.Equal(t, lastTx.Amount.Value, int64(10))
assert.Equal(t, "alice", lastTx.Sender)
assert.Equal(t, "test redeem", lastTx.Message)
}
func TestIfAuditorMatchesOwnerHistory(t *testing.T) {
owner1.testIfAuditorMatchesOwnerHistory(t, []string{"alice", "bob"})
owner2.testIfAuditorMatchesOwnerHistory(t, []string{"carlos", "dan"})
}
func issue(t *testing.T, counterparty Counterparty, value int64) string {
res, err := issuer.IssueWithResponse(context.TODO(), IssueJSONRequestBody{
Amount: Amount{
Code: CODE,
Value: value,
},
Counterparty: alice,
Message: new(string),
})
assert.NoError(t, err)
assert.Nil(t, res.JSONDefault)
assert.NotNil(t, res.JSON200)
t.Logf(res.JSON200.Message)
return res.JSON200.Payload
}
func getAuditorTransactions(t *testing.T, wallet string) []TransactionRecord {
res, err := auditor.AuditorTransactionsWithResponse(context.TODO(), wallet)
assert.NoError(t, err)
assert.Nil(t, res.JSONDefault)
assert.NotNil(t, res.JSON200)
t.Logf(res.JSON200.Message)
return res.JSON200.Payload
}
func (o *ownerAPI) testIfAuditorMatchesOwnerHistory(t *testing.T, accounts []string) {
for _, w := range accounts {
tx := o.getTransactions(t, w)
audittx := getAuditorTransactions(t, w)
assert.Equal(t, len(tx), len(audittx), w)
// Timestamp is the time of storing the tx in the database
// so it's not the same on both sides.
for i := 0; i < len(tx); i++ {
tx[i].Timestamp = time.Time{}
audittx[i].Timestamp = time.Time{}
}
assert.Equal(t, tx, audittx)
}
}
func (o *ownerAPI) getTransactions(t *testing.T, wallet string) []TransactionRecord {
res, err := o.client.OwnerTransactionsWithResponse(context.TODO(), wallet)
assert.NoError(t, err)
assert.Nil(t, res.JSONDefault)
assert.NotNil(t, res.JSON200)
t.Logf(res.JSON200.Message)
return res.JSON200.Payload
}
func (o *ownerAPI) transfer(t *testing.T, sender string, counterparty Counterparty, value int64) string {
res, err := o.client.TransferWithResponse(context.TODO(), sender, TransferJSONRequestBody{
Amount: Amount{
Code: CODE,
Value: value,
},
Counterparty: counterparty,
Message: new(string),
})
assert.NoError(t, err)
assert.Nil(t, res.JSONDefault)
assert.NotNil(t, res.JSON200)
t.Logf(res.JSON200.Message)
return res.JSON200.Payload
}
func (o *ownerAPI) redeem(t *testing.T, wallet string, value int64, message string) string {
res, err := o.client.RedeemWithResponse(context.TODO(), wallet, RedeemJSONRequestBody{
Amount: Amount{
Code: CODE,
Value: value,
},
Message: &message,
})
assert.NoError(t, err)
assert.Nil(t, res.JSONDefault)
assert.NotNil(t, res.JSON200)
t.Logf(res.JSON200.Message)
return res.JSON200.Payload
}
func (o *ownerAPI) getAccounts(t *testing.T) []Account {
res, err := o.client.OwnerAccountsWithResponse(context.TODO())
assert.NoError(t, err)
assert.Nil(t, res.JSONDefault)
assert.NotNil(t, res.JSON200)
t.Logf(res.JSON200.Message)
return res.JSON200.Payload
}
func getValue(t *testing.T, acc []Account, wallet string) int64 {
for _, a := range acc {
if a.Id == wallet {
for _, b := range a.Balance {
if b.Code == CODE {
return b.Value
}
}
}
}
t.Logf("%s value not found for wallet %s in %v", CODE, wallet, acc)
return 0
}
// getEnv returns an environment variable or the fallback
func getEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}