github.com/koko1123/flow-go-1@v0.29.6/engine/access/rest/scripts_test.go (about)

     1  package rest
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"encoding/json"
     7  	"fmt"
     8  	"net/http"
     9  	"net/url"
    10  	"testing"
    11  
    12  	"github.com/koko1123/flow-go-1/engine/access/rest/util"
    13  
    14  	mocks "github.com/stretchr/testify/mock"
    15  	"google.golang.org/grpc/codes"
    16  	"google.golang.org/grpc/status"
    17  
    18  	"github.com/koko1123/flow-go-1/access/mock"
    19  	"github.com/koko1123/flow-go-1/model/flow"
    20  )
    21  
    22  func scriptReq(id string, height string, body interface{}) *http.Request {
    23  	u, _ := url.ParseRequestURI("/v1/scripts")
    24  	q := u.Query()
    25  
    26  	if id != "" {
    27  		q.Add("block_id", id)
    28  	}
    29  	if height != "" {
    30  		q.Add("block_height", height)
    31  	}
    32  
    33  	u.RawQuery = q.Encode()
    34  
    35  	jsonBody, _ := json.Marshal(body)
    36  	req, _ := http.NewRequest("POST", u.String(), bytes.NewBuffer(jsonBody))
    37  
    38  	return req
    39  }
    40  
    41  func TestScripts(t *testing.T) {
    42  	validCode := []byte(`pub fun main(foo: String): String { return foo }`)
    43  	validArgs := []byte(`{ "type": "String", "value": "hello world" }`)
    44  	validBody := map[string]interface{}{
    45  		"script":    util.ToBase64(validCode),
    46  		"arguments": []string{util.ToBase64(validArgs)},
    47  	}
    48  
    49  	t.Run("get by Latest height", func(t *testing.T) {
    50  		backend := &mock.API{}
    51  		backend.Mock.
    52  			On("ExecuteScriptAtLatestBlock", mocks.Anything, validCode, [][]byte{validArgs}).
    53  			Return([]byte("hello world"), nil)
    54  
    55  		req := scriptReq("", sealedHeightQueryParam, validBody)
    56  		assertOKResponse(t, req, fmt.Sprintf(
    57  			"\"%s\"",
    58  			base64.StdEncoding.EncodeToString([]byte(`hello world`)),
    59  		), backend)
    60  	})
    61  
    62  	t.Run("get by height", func(t *testing.T) {
    63  		backend := &mock.API{}
    64  		height := uint64(1337)
    65  
    66  		backend.Mock.
    67  			On("ExecuteScriptAtBlockHeight", mocks.Anything, height, validCode, [][]byte{validArgs}).
    68  			Return([]byte("hello world"), nil)
    69  
    70  		req := scriptReq("", fmt.Sprintf("%d", height), validBody)
    71  		assertOKResponse(t, req, fmt.Sprintf(
    72  			"\"%s\"",
    73  			base64.StdEncoding.EncodeToString([]byte(`hello world`)),
    74  		), backend)
    75  	})
    76  
    77  	t.Run("get by ID", func(t *testing.T) {
    78  		backend := &mock.API{}
    79  		id, _ := flow.HexStringToIdentifier("222dc5dd51b9e4910f687e475f892f495f3352362ba318b53e318b4d78131312")
    80  
    81  		backend.Mock.
    82  			On("ExecuteScriptAtBlockID", mocks.Anything, id, validCode, [][]byte{validArgs}).
    83  			Return([]byte("hello world"), nil)
    84  
    85  		req := scriptReq(id.String(), "", validBody)
    86  		assertOKResponse(t, req, fmt.Sprintf(
    87  			"\"%s\"",
    88  			base64.StdEncoding.EncodeToString([]byte(`hello world`)),
    89  		), backend)
    90  	})
    91  
    92  	t.Run("get error", func(t *testing.T) {
    93  		backend := &mock.API{}
    94  		backend.Mock.
    95  			On("ExecuteScriptAtBlockHeight", mocks.Anything, uint64(1337), validCode, [][]byte{validArgs}).
    96  			Return(nil, status.Error(codes.Internal, "internal server error"))
    97  
    98  		req := scriptReq("", "1337", validBody)
    99  		assertResponse(
   100  			t,
   101  			req,
   102  			http.StatusBadRequest,
   103  			`{"code":400, "message":"Invalid Flow request: internal server error"}`,
   104  			backend,
   105  		)
   106  	})
   107  
   108  	t.Run("get invalid", func(t *testing.T) {
   109  		backend := &mock.API{}
   110  		backend.Mock.
   111  			On("ExecuteScriptAtBlockHeight", mocks.Anything, mocks.Anything, mocks.Anything, mocks.Anything).
   112  			Return(nil, nil)
   113  
   114  		tests := []struct {
   115  			id     string
   116  			height string
   117  			body   map[string]interface{}
   118  			out    string
   119  			status int
   120  		}{
   121  			{"invalidID", "", validBody, `{"code":400,"message":"invalid ID format"}`, http.StatusBadRequest},
   122  			{"", "invalid", validBody, `{"code":400,"message":"invalid height format"}`, http.StatusBadRequest},
   123  			{"", "-1", validBody, `{"code":400,"message":"invalid height format"}`, http.StatusBadRequest},
   124  			{"", "1337", nil, `{"code":400,"message":"request body must not be empty"}`, http.StatusBadRequest},
   125  		}
   126  
   127  		for _, test := range tests {
   128  			req := scriptReq(test.id, test.height, test.body)
   129  			assertResponse(t, req, http.StatusBadRequest, test.out, backend)
   130  		}
   131  	})
   132  }