github.com/algorand/go-algorand-sdk@v1.24.0/test/responses_unit_test.go (about)

     1  package test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"path"
     7  	"strings"
     8  
     9  	"github.com/cucumber/godog"
    10  
    11  	"github.com/algorand/go-algorand-sdk/client/v2/algod"
    12  	"github.com/algorand/go-algorand-sdk/client/v2/common/models"
    13  	"github.com/algorand/go-algorand-sdk/client/v2/indexer"
    14  	"github.com/algorand/go-algorand-sdk/encoding/json"
    15  	"github.com/algorand/go-algorand-sdk/types"
    16  )
    17  
    18  var algodC *algod.Client
    19  var indexerC *indexer.Client
    20  var baselinePath string
    21  var expectedStatus int
    22  var response interface{}
    23  
    24  // @unit
    25  // @unit.responses
    26  
    27  func mockHttpResponsesInLoadedFromWithStatus(jsonfile, loadedFrom string, status int) error {
    28  	directory := path.Join("./features/resources/", loadedFrom)
    29  	baselinePath = path.Join(directory, jsonfile)
    30  	var err error
    31  	expectedStatus = status
    32  	err = mockHttpResponsesInLoadedFromHelper(jsonfile, directory, status)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	algodC, err = algod.MakeClient(mockServer.URL, "")
    37  	if err != nil {
    38  		return err
    39  	}
    40  	indexerC, err = indexer.MakeClient(mockServer.URL, "")
    41  	return err
    42  }
    43  
    44  func weMakeAnyCallTo(client /* algod/indexer */, endpoint string) (err error) {
    45  	var round uint64
    46  	var something interface{}
    47  
    48  	switch client {
    49  	case "indexer":
    50  		switch endpoint {
    51  		case "lookupAccountByID":
    52  			round, something, err = indexerC.LookupAccountByID("").Do(context.Background())
    53  			response = models.AccountResponse{
    54  				CurrentRound: round,
    55  				Account:      something.(models.Account),
    56  			}
    57  		case "searchForAccounts":
    58  			response, err = indexerC.SearchAccounts().Do(context.Background())
    59  		case "lookupApplicationByID":
    60  			response, err = indexerC.LookupApplicationByID(10).Do(context.Background())
    61  		case "searchForApplications":
    62  			response, err = indexerC.SearchForApplications().Do(context.Background())
    63  		case "lookupAssetBalances":
    64  			response, err = indexerC.LookupAssetBalances(10).Do(context.Background())
    65  		case "lookupAssetByID":
    66  			round, something, err = indexerC.LookupAssetByID(10).Do(context.Background())
    67  			response = models.AssetResponse{
    68  				CurrentRound: round,
    69  				Asset:        something.(models.Asset),
    70  			}
    71  		case "searchForAssets":
    72  			response, err = indexerC.SearchForAssets().Do(context.Background())
    73  		case "lookupAccountTransactions":
    74  			response, err = indexerC.LookupAccountTransactions("").Do(context.Background())
    75  		case "lookupAssetTransactions":
    76  			response, err = indexerC.LookupAssetTransactions(10).Do(context.Background())
    77  		case "searchForTransactions":
    78  			response, err = indexerC.SearchForTransactions().Do(context.Background())
    79  		case "lookupBlock":
    80  			response, err = indexerC.LookupBlock(10).Do(context.Background())
    81  		case "lookupTransaction":
    82  			response, err = indexerC.LookupTransaction("").Do(context.Background())
    83  		case "lookupAccountAppLocalStates":
    84  			response, err = indexerC.LookupAccountAppLocalStates("").Do(context.Background())
    85  		case "lookupAccountCreatedApplications":
    86  			response, err =
    87  				indexerC.LookupAccountCreatedApplications("").Do(context.Background())
    88  		case "lookupAccountAssets":
    89  			response, err = indexerC.LookupAccountAssets("").Do(context.Background())
    90  		case "lookupAccountCreatedAssets":
    91  			response, err = indexerC.LookupAccountCreatedAssets("").Do(context.Background())
    92  		case "lookupApplicationLogsByID":
    93  			response, err = indexerC.LookupApplicationLogsByID(10).Do(context.Background())
    94  		case "any":
    95  			// This is an error case
    96  			// pickup the error as the response
    97  			_, response = indexerC.SearchForTransactions().Do(context.Background())
    98  		default:
    99  			err = fmt.Errorf("unknown indexer endpoint: %s", endpoint)
   100  		}
   101  	case "algod":
   102  		switch endpoint {
   103  		case "GetStatus":
   104  			response, err = algodC.Status().Do(context.Background())
   105  		case "GetBlock":
   106  			response, err = algodC.Block(10).Do(context.Background())
   107  		case "WaitForBlock":
   108  			response, err = algodC.StatusAfterBlock(10).Do(context.Background())
   109  		case "TealCompile":
   110  			response, err = algodC.TealCompile([]byte{}).Do(context.Background())
   111  		case "RawTransaction":
   112  			var returnedTxid string
   113  			returnedTxid, err = algodC.SendRawTransaction([]byte{}).Do(context.Background())
   114  			response = txidresponse{TxID: returnedTxid}
   115  		case "GetSupply":
   116  			response, err = algodC.Supply().Do(context.Background())
   117  		case "TransactionParams":
   118  			var sParams types.SuggestedParams
   119  			sParams, err = algodC.SuggestedParams().Do(context.Background())
   120  			response = models.TransactionParametersResponse{
   121  				ConsensusVersion: sParams.ConsensusVersion,
   122  				Fee:              uint64(sParams.Fee),
   123  				GenesisId:        sParams.GenesisID,
   124  				GenesisHash:      sParams.GenesisHash,
   125  				LastRound:        uint64(sParams.FirstRoundValid),
   126  				MinFee:           sParams.MinFee,
   127  			}
   128  		case "AccountInformation":
   129  			response, err = algodC.AccountInformation("acct").Do(context.Background())
   130  		case "GetApplicationByID":
   131  			response, err = algodC.GetApplicationByID(10).Do(context.Background())
   132  		case "GetAssetByID":
   133  			response, err = algodC.GetAssetByID(10).Do(context.Background())
   134  		case "PendingTransactionInformation":
   135  			response, _, err = algodC.PendingTransactionInformation("transaction").Do(context.Background())
   136  		case "GetPendingTransactions":
   137  			var total uint64
   138  			var top []types.SignedTxn
   139  			total, top, err = algodC.PendingTransactions().Do(context.Background())
   140  			response = models.PendingTransactionsResponse{
   141  				TopTransactions:   top,
   142  				TotalTransactions: total,
   143  			}
   144  		case "GetPendingTransactionsByAddress":
   145  			var total uint64
   146  			var top []types.SignedTxn
   147  			total, top, err = algodC.PendingTransactionsByAddress("address").Do(context.Background())
   148  			response = models.PendingTransactionsResponse{
   149  				TopTransactions:   top,
   150  				TotalTransactions: total,
   151  			}
   152  		case "DryRun":
   153  			response, err = algodC.TealDryrun(models.DryrunRequest{}).Do(context.Background())
   154  		case "GetTransactionProof":
   155  			fallthrough
   156  		case "Proof":
   157  			response, err = algodC.GetTransactionProof(10, "asdf").Do(context.Background())
   158  		case "GetGenesis":
   159  			response, err = algodC.GetGenesis().Do(context.Background())
   160  		case "AccountApplicationInformation":
   161  			response, err =
   162  				algodC.AccountApplicationInformation("abc", 123).Do(context.Background())
   163  		case "AccountAssetInformation":
   164  			response, err =
   165  				algodC.AccountAssetInformation("abc", 123).Do(context.Background())
   166  		case "GetLightBlockHeaderProof":
   167  			response, err =
   168  				algodC.GetLightBlockHeaderProof(123).Do(context.Background())
   169  		case "GetStateProof":
   170  			response, err =
   171  				algodC.GetStateProof(123).Do(context.Background())
   172  		case "GetBlockHash":
   173  			response, err =
   174  				algodC.GetBlockHash(123).Do(context.Background())
   175  		case "any":
   176  			// This is an error case
   177  			// pickup the error as the response
   178  			_, response = indexerC.SearchForTransactions().Do(context.Background())
   179  		default:
   180  			err = fmt.Errorf("unknown algod endpoint: %s", endpoint)
   181  		}
   182  	}
   183  	return err
   184  }
   185  
   186  type txidresponse struct {
   187  	TxID string `json:"txId"`
   188  }
   189  
   190  func theParsedResponseShouldEqualTheMockResponse() error {
   191  	var responseJson string
   192  
   193  	if expectedStatus != 200 {
   194  		responseJson = response.(error).Error()
   195  		// The error message is not a well formed Json.
   196  		// Verify the expected status code, and remove the json corrupting message
   197  		statusCode := fmt.Sprintf("%d", expectedStatus)
   198  		if !strings.Contains(responseJson, statusCode) {
   199  			return fmt.Errorf("Expected error code: %d, got otherwise", expectedStatus)
   200  		}
   201  		parts := strings.SplitAfterN(responseJson, ":", 2)
   202  		responseJson = parts[1]
   203  	} else {
   204  		if responseStr, ok := response.(string); ok {
   205  			responseJson = responseStr
   206  		} else {
   207  			responseJson = string(json.Encode(response))
   208  		}
   209  	}
   210  
   211  	return VerifyResponse(baselinePath, responseJson)
   212  }
   213  
   214  func ResponsesContext(s *godog.Suite) {
   215  	s.Step(`^mock http responses in "([^"]*)" loaded from "([^"]*)" with status (\d+)\.$`, mockHttpResponsesInLoadedFromWithStatus)
   216  	s.Step(`^we make any "([^"]*)" call to "([^"]*)"\.$`, weMakeAnyCallTo)
   217  	s.Step(`^the parsed response should equal the mock response\.$`, theParsedResponseShouldEqualTheMockResponse)
   218  }