...

Source file src/github.com/cli/shurcooL-graphql/graphql_test.go

Documentation: github.com/cli/shurcooL-graphql

     1  package graphql_test
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"testing"
     9  
    10  	graphql "github.com/cli/shurcooL-graphql"
    11  )
    12  
    13  func TestClient_Query_partialDataWithErrorResponse(t *testing.T) {
    14  	mux := http.NewServeMux()
    15  	mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
    16  		w.Header().Set("Content-Type", "application/json")
    17  		mustWrite(w, `{
    18  			"data": {
    19  				"node1": {
    20  					"id": "MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng=="
    21  				},
    22  				"node2": null
    23  			},
    24  			"errors": [
    25  				{
    26  					"message": "Could not resolve to a node with the global id of 'NotExist'",
    27  					"type": "NOT_FOUND",
    28  					"path": [
    29  						"node2"
    30  					],
    31  					"locations": [
    32  						{
    33  							"line": 10,
    34  							"column": 4
    35  						}
    36  					]
    37  				}
    38  			]
    39  		}`)
    40  	})
    41  	client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
    42  
    43  	var q struct {
    44  		Node1 *struct {
    45  			ID graphql.ID
    46  		} `graphql:"node1: node(id: \"MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng==\")"`
    47  		Node2 *struct {
    48  			ID graphql.ID
    49  		} `graphql:"node2: node(id: \"NotExist\")"`
    50  	}
    51  	err := client.Query(context.Background(), &q, nil)
    52  	if err == nil {
    53  		t.Fatal("got error: nil, want: non-nil")
    54  	}
    55  	if got, want := err.Error(), "Message: Could not resolve to a node with the global id of 'NotExist', Locations: [{Line:10 Column:4}]"; got != want {
    56  		t.Errorf("got error: %v, want: %v", got, want)
    57  	}
    58  	if q.Node1 == nil || q.Node1.ID != "MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng==" {
    59  		t.Errorf("got wrong q.Node1: %v", q.Node1)
    60  	}
    61  	if q.Node2 != nil {
    62  		t.Errorf("got non-nil q.Node2: %v, want: nil", *q.Node2)
    63  	}
    64  }
    65  
    66  func TestClient_Query_noDataWithErrorResponse(t *testing.T) {
    67  	mux := http.NewServeMux()
    68  	mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
    69  		w.Header().Set("Content-Type", "application/json")
    70  		mustWrite(w, `{
    71  			"errors": [
    72  				{
    73  					"message": "Field 'user' is missing required arguments: login",
    74  					"locations": [
    75  						{
    76  							"line": 7,
    77  							"column": 3
    78  						}
    79  					]
    80  				}
    81  			]
    82  		}`)
    83  	})
    84  	client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
    85  
    86  	var q struct {
    87  		User struct {
    88  			Name graphql.String
    89  		}
    90  	}
    91  	err := client.Query(context.Background(), &q, nil)
    92  	if err == nil {
    93  		t.Fatal("got error: nil, want: non-nil")
    94  	}
    95  	if got, want := err.Error(), "Message: Field 'user' is missing required arguments: login, Locations: [{Line:7 Column:3}]"; got != want {
    96  		t.Errorf("got error: %v, want: %v", got, want)
    97  	}
    98  	if q.User.Name != "" {
    99  		t.Errorf("got non-empty q.User.Name: %v", q.User.Name)
   100  	}
   101  }
   102  
   103  func TestClient_Query_errorStatusCode(t *testing.T) {
   104  	mux := http.NewServeMux()
   105  	mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
   106  		http.Error(w, "important message", http.StatusInternalServerError)
   107  	})
   108  	client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
   109  
   110  	var q struct {
   111  		User struct {
   112  			Name graphql.String
   113  		}
   114  	}
   115  	err := client.Query(context.Background(), &q, nil)
   116  	if err == nil {
   117  		t.Fatal("got error: nil, want: non-nil")
   118  	}
   119  	if got, want := err.Error(), `non-200 OK status code: 500 Internal Server Error body: "important message\n"`; got != want {
   120  		t.Errorf("got error: %v, want: %v", got, want)
   121  	}
   122  	if q.User.Name != "" {
   123  		t.Errorf("got non-empty q.User.Name: %v", q.User.Name)
   124  	}
   125  }
   126  
   127  // Test that an empty (but non-nil) variables map is
   128  // handled no differently than a nil variables map.
   129  func TestClient_Query_emptyVariables(t *testing.T) {
   130  	mux := http.NewServeMux()
   131  	mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
   132  		body := mustRead(req.Body)
   133  		if got, want := body, `{"query":"{user{name}}"}`+"\n"; got != want {
   134  			t.Errorf("got body: %v, want %v", got, want)
   135  		}
   136  		w.Header().Set("Content-Type", "application/json")
   137  		mustWrite(w, `{"data": {"user": {"name": "Gopher"}}}`)
   138  	})
   139  	client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
   140  
   141  	var q struct {
   142  		User struct {
   143  			Name string
   144  		}
   145  	}
   146  	err := client.Query(context.Background(), &q, map[string]any{})
   147  	if err != nil {
   148  		t.Fatal(err)
   149  	}
   150  	if got, want := q.User.Name, "Gopher"; got != want {
   151  		t.Errorf("got q.User.Name: %q, want: %q", got, want)
   152  	}
   153  }
   154  
   155  // localRoundTripper is an http.RoundTripper that executes HTTP transactions
   156  // by using handler directly, instead of going over an HTTP connection.
   157  type localRoundTripper struct {
   158  	handler http.Handler
   159  }
   160  
   161  func (l localRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
   162  	w := httptest.NewRecorder()
   163  	l.handler.ServeHTTP(w, req)
   164  	return w.Result(), nil
   165  }
   166  
   167  func mustRead(r io.Reader) string {
   168  	b, err := io.ReadAll(r)
   169  	if err != nil {
   170  		panic(err)
   171  	}
   172  	return string(b)
   173  }
   174  
   175  func mustWrite(w io.Writer, s string) {
   176  	_, err := io.WriteString(w, s)
   177  	if err != nil {
   178  		panic(err)
   179  	}
   180  }
   181  

View as plain text