github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/access/rest/request/transaction_test.go (about)

     1  package request
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/onflow/flow-go/engine/access/rest/util"
    13  	"github.com/onflow/flow-go/model/flow"
    14  	"github.com/onflow/flow-go/utils/unittest"
    15  )
    16  
    17  func buildTransaction() map[string]interface{} {
    18  	tx := unittest.TransactionFixture()
    19  	tx.Arguments = [][]uint8{}
    20  	tx.PayloadSignatures = []flow.TransactionSignature{}
    21  	auth := make([]string, len(tx.Authorizers))
    22  	for i, a := range tx.Authorizers {
    23  		auth[i] = a.String()
    24  	}
    25  
    26  	return map[string]interface{}{
    27  		"script":             util.ToBase64(tx.Script),
    28  		"arguments":          tx.Arguments,
    29  		"reference_block_id": tx.ReferenceBlockID.String(),
    30  		"gas_limit":          fmt.Sprintf("%d", tx.GasLimit),
    31  		"payer":              tx.Payer.String(),
    32  		"proposal_key": map[string]interface{}{
    33  			"address":         tx.ProposalKey.Address.String(),
    34  			"key_index":       fmt.Sprintf("%d", tx.ProposalKey.KeyIndex),
    35  			"sequence_number": fmt.Sprintf("%d", tx.ProposalKey.SequenceNumber),
    36  		},
    37  		"authorizers": auth,
    38  		"envelope_signatures": []map[string]interface{}{{
    39  			"address":   tx.EnvelopeSignatures[0].Address.String(),
    40  			"key_index": fmt.Sprintf("%d", tx.EnvelopeSignatures[0].KeyIndex),
    41  			"signature": util.ToBase64(tx.EnvelopeSignatures[0].Signature),
    42  		}},
    43  	}
    44  }
    45  
    46  func transactionToReader(tx map[string]interface{}) io.Reader {
    47  	res, _ := json.Marshal(tx)
    48  	return bytes.NewReader(res)
    49  }
    50  
    51  func TestTransaction_InvalidParse(t *testing.T) {
    52  	tests := []struct {
    53  		inputField string
    54  		inputValue string
    55  		output     string
    56  	}{
    57  		{"script", "-1", "invalid transaction script encoding"},
    58  		{"arguments", "-1", `request body contains an invalid value for the "arguments" field (at position 17)`},
    59  		{"reference_block_id", "-1", "invalid reference block ID: invalid ID format"},
    60  		{"gas_limit", "-1", "invalid gas limit: value must be an unsigned 64 bit integer"},
    61  		{"payer", "-1", "invalid payer: invalid address"},
    62  		{"authorizers", "-1", `request body contains an invalid value for the "authorizers" field (at position 34)`},
    63  		{"proposal_key", "-1", `request body contains an invalid value for the "proposal_key" field (at position 288)`},
    64  		{"envelope_signatures", "", `request body contains an invalid value for the "envelope_signatures" field (at position 75)`},
    65  		{"envelope_signatures", "[]", `request body contains an invalid value for the "envelope_signatures" field (at position 77)`},
    66  	}
    67  
    68  	for _, test := range tests {
    69  		tx := buildTransaction()
    70  		tx[test.inputField] = test.inputValue
    71  		input := transactionToReader(tx)
    72  
    73  		var transaction Transaction
    74  		err := transaction.Parse(input, flow.Testnet.Chain())
    75  
    76  		assert.EqualError(t, err, test.output)
    77  	}
    78  
    79  	keyTests := []struct {
    80  		inputField string
    81  		inputValue string
    82  		output     string
    83  	}{
    84  		{"address", "-1", "invalid address"},
    85  		{"key_index", "-1", `invalid key index: value must be an unsigned 64 bit integer`},
    86  		{"sequence_number", "-1", "invalid sequence number: value must be an unsigned 64 bit integer"},
    87  	}
    88  
    89  	for _, test := range keyTests {
    90  		tx := buildTransaction()
    91  		tx["proposal_key"].(map[string]interface{})[test.inputField] = test.inputValue
    92  		input := transactionToReader(tx)
    93  
    94  		var transaction Transaction
    95  		err := transaction.Parse(input, flow.Testnet.Chain())
    96  
    97  		assert.EqualError(t, err, test.output)
    98  	}
    99  
   100  	sigTests := []struct {
   101  		inputField string
   102  		inputValue string
   103  		output     string
   104  	}{
   105  		{"address", "-1", "invalid address"},
   106  		{"key_index", "-1", `invalid key index: value must be an unsigned 64 bit integer`},
   107  		{"signature", "-1", "invalid signature: invalid encoding"},
   108  	}
   109  
   110  	for _, test := range sigTests {
   111  		tx := buildTransaction()
   112  		tx["envelope_signatures"].([]map[string]interface{})[0][test.inputField] = test.inputValue
   113  		input := transactionToReader(tx)
   114  
   115  		var transaction Transaction
   116  		err := transaction.Parse(input, flow.Testnet.Chain())
   117  
   118  		assert.EqualError(t, err, test.output)
   119  	}
   120  }
   121  
   122  func TestTransaction_ValidParse(t *testing.T) {
   123  	script := `access(all) fun main() {}`
   124  	tx := buildTransaction()
   125  	tx["script"] = util.ToBase64([]byte(script))
   126  	input := transactionToReader(tx)
   127  
   128  	var transaction Transaction
   129  	err := transaction.Parse(input, flow.Testnet.Chain())
   130  
   131  	assert.NoError(t, err)
   132  	assert.Equal(t, tx["payer"], transaction.Flow().Payer.String())
   133  	assert.Equal(t, script, string(transaction.Flow().Script))
   134  	assert.Equal(t, tx["reference_block_id"], transaction.Flow().ReferenceBlockID.String())
   135  	assert.Equal(t, tx["gas_limit"], fmt.Sprint(transaction.Flow().GasLimit))
   136  	assert.Equal(t, len(tx["authorizers"].([]string)), len(transaction.Flow().Authorizers))
   137  }