| 
									
										
										
										
											2019-07-22 12:17:27 +03:00
										 |  |  | // Copyright 2019 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2019-01-21 06:38:13 -08:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package graphql | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2020-08-03 19:40:46 +02:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2019-01-21 06:38:13 -08:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2020-08-03 19:40:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/eth" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/node" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/assert" | 
					
						
							| 
									
										
										
										
											2019-01-21 06:38:13 -08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestBuildSchema(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2020-08-03 19:40:46 +02:00
										 |  |  | 	stack, err := node.New(&node.DefaultConfig) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not create new node: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-01-21 06:38:13 -08:00
										 |  |  | 	// Make sure the schema can be parsed and matched up to the object model. | 
					
						
							| 
									
										
										
										
											2020-08-03 19:40:46 +02:00
										 |  |  | 	if err := newHandler(stack, nil, []string{}, []string{}); err != nil { | 
					
						
							| 
									
										
										
										
											2019-01-21 06:38:13 -08:00
										 |  |  | 		t.Errorf("Could not construct GraphQL handler: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-03 19:40:46 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Tests that a graphQL request is successfully handled when graphql is enabled on the specified endpoint | 
					
						
							|  |  |  | func TestGraphQLHTTPOnSamePort_GQLRequest_Successful(t *testing.T) { | 
					
						
							|  |  |  | 	stack := createNode(t, true) | 
					
						
							|  |  |  | 	defer stack.Close() | 
					
						
							|  |  |  | 	// start node | 
					
						
							|  |  |  | 	if err := stack.Start(); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not start node: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// create http request | 
					
						
							|  |  |  | 	body := strings.NewReader("{\"query\": \"{block{number}}\",\"variables\": null}") | 
					
						
							|  |  |  | 	gqlReq, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s/graphql", "127.0.0.1:9393"), body) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Error("could not issue new http request ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	gqlReq.Header.Set("Content-Type", "application/json") | 
					
						
							|  |  |  | 	// read from response | 
					
						
							|  |  |  | 	resp := doHTTPRequest(t, gqlReq) | 
					
						
							|  |  |  | 	bodyBytes, err := ioutil.ReadAll(resp.Body) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not read from response body: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	expected := "{\"data\":{\"block\":{\"number\":\"0x0\"}}}" | 
					
						
							|  |  |  | 	assert.Equal(t, expected, string(bodyBytes)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Tests that a graphQL request is not handled successfully when graphql is not enabled on the specified endpoint | 
					
						
							|  |  |  | func TestGraphQLHTTPOnSamePort_GQLRequest_Unsuccessful(t *testing.T) { | 
					
						
							|  |  |  | 	stack := createNode(t, false) | 
					
						
							|  |  |  | 	defer stack.Close() | 
					
						
							|  |  |  | 	if err := stack.Start(); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not start node: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create http request | 
					
						
							|  |  |  | 	body := strings.NewReader("{\"query\": \"{block{number}}\",\"variables\": null}") | 
					
						
							|  |  |  | 	gqlReq, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s/graphql", "127.0.0.1:9393"), body) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Error("could not issue new http request ", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	gqlReq.Header.Set("Content-Type", "application/json") | 
					
						
							|  |  |  | 	// read from response | 
					
						
							|  |  |  | 	resp := doHTTPRequest(t, gqlReq) | 
					
						
							|  |  |  | 	bodyBytes, err := ioutil.ReadAll(resp.Body) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not read from response body: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// make sure the request is not handled successfully | 
					
						
							|  |  |  | 	assert.Equal(t, 404, resp.StatusCode) | 
					
						
							|  |  |  | 	assert.Equal(t, "404 page not found\n", string(bodyBytes)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func createNode(t *testing.T, gqlEnabled bool) *node.Node { | 
					
						
							|  |  |  | 	stack, err := node.New(&node.Config{ | 
					
						
							|  |  |  | 		HTTPHost: "127.0.0.1", | 
					
						
							|  |  |  | 		HTTPPort: 9393, | 
					
						
							|  |  |  | 		WSHost:   "127.0.0.1", | 
					
						
							|  |  |  | 		WSPort:   9393, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not create node: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !gqlEnabled { | 
					
						
							|  |  |  | 		return stack | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	createGQLService(t, stack, "127.0.0.1:9393") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return stack | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func createGQLService(t *testing.T, stack *node.Node, endpoint string) { | 
					
						
							|  |  |  | 	// create backend | 
					
						
							|  |  |  | 	ethBackend, err := eth.New(stack, ð.DefaultConfig) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not create eth backend: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create gql service | 
					
						
							|  |  |  | 	err = New(stack, ethBackend.APIBackend, []string{}, []string{}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("could not create graphql service: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func doHTTPRequest(t *testing.T, req *http.Request) *http.Response { | 
					
						
							|  |  |  | 	client := &http.Client{} | 
					
						
							|  |  |  | 	resp, err := client.Do(req) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal("could not issue a GET request to the given endpoint", err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return resp | 
					
						
							|  |  |  | } |