github.com/core-coin/go-core/v2@v2.1.9/graphql/graphql_test.go (about) 1 // Copyright 2019 by the Authors 2 // This file is part of the go-core library. 3 // 4 // The go-core library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-core library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-core library. If not, see <http://www.gnu.org/licenses/>. 16 17 package graphql 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "net/http" 23 "strings" 24 "testing" 25 "time" 26 27 "github.com/stretchr/testify/assert" 28 29 "github.com/core-coin/go-core/v2/consensus/cryptore" 30 31 "github.com/core-coin/go-core/v2/common" 32 "github.com/core-coin/go-core/v2/core" 33 "github.com/core-coin/go-core/v2/miner" 34 "github.com/core-coin/go-core/v2/node" 35 "github.com/core-coin/go-core/v2/xcb" 36 ) 37 38 func TestBuildSchema(t *testing.T) { 39 stack, err := node.New(&node.DefaultConfig) 40 if err != nil { 41 t.Fatalf("could not create new node: %v", err) 42 } 43 // Make sure the schema can be parsed and matched up to the object model. 44 if err := newHandler(stack, nil, []string{}, []string{}); err != nil { 45 t.Errorf("Could not construct GraphQL handler: %v", err) 46 } 47 } 48 49 // Tests that a graphQL request is successfully handled when graphql is enabled on the specified endpoint 50 func TestGraphQLHTTPOnSamePort_GQLRequest_Successful(t *testing.T) { 51 stack := createNode(t, true) 52 defer stack.Close() 53 // start node 54 if err := stack.Start(); err != nil { 55 t.Fatalf("could not start node: %v", err) 56 } 57 // create http request 58 body := strings.NewReader("{\"query\": \"{block{number}}\",\"variables\": null}") 59 gqlReq, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s/graphql", "127.0.0.1:9393"), body) 60 if err != nil { 61 t.Error("could not issue new http request ", err) 62 } 63 gqlReq.Header.Set("Content-Type", "application/json") 64 // read from response 65 resp := doHTTPRequest(t, gqlReq) 66 bodyBytes, err := ioutil.ReadAll(resp.Body) 67 if err != nil { 68 t.Fatalf("could not read from response body: %v", err) 69 } 70 expected := "{\"data\":{\"block\":{\"number\":\"0x0\"}}}" 71 assert.Equal(t, 200, resp.StatusCode) 72 assert.Equal(t, expected, string(bodyBytes)) 73 } 74 75 // Tests that a graphQL request is not handled successfully when graphql is not enabled on the specified endpoint 76 func TestGraphQLHTTPOnSamePort_GQLRequest_Unsuccessful(t *testing.T) { 77 stack := createNode(t, false) 78 defer stack.Close() 79 if err := stack.Start(); err != nil { 80 t.Fatalf("could not start node: %v", err) 81 } 82 83 // create http request 84 body := strings.NewReader("{\"query\": \"{block{number}}\",\"variables\": null}") 85 gqlReq, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s/graphql", "127.0.0.1:9393"), body) 86 if err != nil { 87 t.Error("could not issue new http request ", err) 88 } 89 gqlReq.Header.Set("Content-Type", "application/json") 90 // read from response 91 resp := doHTTPRequest(t, gqlReq) 92 // make sure the request is not handled successfully 93 assert.Equal(t, http.StatusNotFound, resp.StatusCode) 94 } 95 96 // Tests that 400 is returned when an invalid RPC request is made. 97 func TestGraphQL_BadRequest(t *testing.T) { 98 stack := createNode(t, true) 99 defer stack.Close() 100 // start node 101 if err := stack.Start(); err != nil { 102 t.Fatalf("could not start node: %v", err) 103 } 104 // create http request 105 body := strings.NewReader("{\"query\": \"{bleh{number}}\",\"variables\": null}") 106 gqlReq, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s/graphql", "127.0.0.1:9393"), body) 107 if err != nil { 108 t.Error("could not issue new http request ", err) 109 } 110 gqlReq.Header.Set("Content-Type", "application/json") 111 // read from response 112 resp := doHTTPRequest(t, gqlReq) 113 bodyBytes, err := ioutil.ReadAll(resp.Body) 114 if err != nil { 115 t.Fatalf("could not read from response body: %v", err) 116 } 117 expected := "{\"errors\":[{\"message\":\"Cannot query field \\\"bleh\\\" on type \\\"Query\\\".\",\"locations\":[{\"line\":1,\"column\":2}]}]}" 118 assert.Equal(t, expected, string(bodyBytes)) 119 assert.Equal(t, 400, resp.StatusCode) 120 } 121 122 func createNode(t *testing.T, gqlEnabled bool) *node.Node { 123 stack, err := node.New(&node.Config{ 124 HTTPHost: "127.0.0.1", 125 HTTPPort: 9393, 126 WSHost: "127.0.0.1", 127 WSPort: 9393, 128 }) 129 if err != nil { 130 t.Fatalf("could not create node: %v", err) 131 } 132 if !gqlEnabled { 133 return stack 134 } 135 136 createGQLService(t, stack, "127.0.0.1:9393") 137 138 return stack 139 } 140 141 func createGQLService(t *testing.T, stack *node.Node, endpoint string) { 142 addr, err := common.HexToAddress("cb27de521e43741cf785cbad450d5649187b9612018f") 143 if err != nil { 144 t.Error(err) 145 } 146 // create backend (use a config which is light on mem consumption) 147 xcbConf := &xcb.Config{ 148 Genesis: core.DeveloperGenesisBlock(15, common.Address{}), 149 Miner: miner.Config{ 150 Corebase: addr, 151 }, 152 Cryptore: cryptore.Config{ 153 PowMode: cryptore.ModeTest, 154 }, 155 NetworkId: 1, 156 TrieCleanCache: 5, 157 TrieCleanCacheJournal: "triecache", 158 TrieCleanCacheRejournal: 60 * time.Minute, 159 TrieDirtyCache: 5, 160 TrieTimeout: 60 * time.Minute, 161 SnapshotCache: 5, 162 } 163 xcbBackend, err := xcb.New(stack, xcbConf) 164 if err != nil { 165 t.Fatalf("could not create xcb backend: %v", err) 166 } 167 168 // create gql service 169 err = New(stack, xcbBackend.APIBackend, []string{}, []string{}) 170 if err != nil { 171 t.Fatalf("could not create graphql service: %v", err) 172 } 173 } 174 175 func doHTTPRequest(t *testing.T, req *http.Request) *http.Response { 176 client := &http.Client{} 177 resp, err := client.Do(req) 178 if err != nil { 179 t.Fatal("could not issue a GET request to the given endpoint", err) 180 181 } 182 return resp 183 }