From 851a4276560a0963853a3a2b05b3690bdb0e611b Mon Sep 17 00:00:00 2001 From: Toan Nguyen Date: Sat, 1 Jun 2024 11:40:14 +0700 Subject: [PATCH] analyze issue 139 --- graphql_test.go | 134 ++++++++++++++++++++++++++++++++++++++++ pkg/jsonutil/graphql.go | 2 +- 2 files changed, 135 insertions(+), 1 deletion(-) diff --git a/graphql_test.go b/graphql_test.go index 224e926..8fd61fa 100644 --- a/graphql_test.go +++ b/graphql_test.go @@ -7,7 +7,9 @@ import ( "io" "net/http" "net/http/httptest" + "reflect" "testing" + "time" "github.com/hasura/go-graphql-client" ) @@ -470,6 +472,138 @@ func TestClient_Exec_QueryRaw(t *testing.T) { } } +// Issue: https://github.com/hasura/go-graphql-client/issues/139 +func TestUnmarshalGraphQL_unionSlice(t *testing.T) { + + expectedQuery := `query($cursor0: String, $searchQuery: String!) { + search(type: ISSUE, query: $searchQuery, first: 100, after: $cursor0) { + pageInfo { + endCursor + hasNextPage + } + nodes { + ... on Issue { + number + id + createdAt + updatedAt + state + stateReason + closedAt + author { + login + } + authorAssociation + title + body + } + } + }` + + type PageInfo struct { + EndCursor string + HasNextPage bool + } + + type issue struct { + Number int64 + ID string + CreatedAt time.Time + UpdatedAt time.Time + State string + StateReason *string + ClosedAt *time.Time + Author struct { + Login string + } + AuthorAssociation string + Title string + Body string + } + + type querySearch struct { + PageInfo PageInfo + Nodes []issue + } + + type queryIssues struct { + // arguments + repoSlug string `json:"-"` + // results + Search querySearch + } + + want := queryIssues{ + Search: querySearch{ + PageInfo: PageInfo{ + EndCursor: "Y3Vyc29yOjE=", + HasNextPage: false, + }, + Nodes: []issue{ + { + Number: 32, + ID: "I_kwDOJBmYg86J6maD", + CreatedAt: time.Date(2024, 05, 23, 21, 03, 9, 0, time.UTC), + UpdatedAt: time.Date(2024, 05, 28, 15, 42, 2, 0, time.UTC), + State: "OPEN", + Author: struct{ Login string }{ + Login: "drewAdorno", + }, + AuthorAssociation: "NONE", + Title: "subdomains not redirecting", + Body: "Hi,\r\nI was able to configure and successfully use localias in was wsl env (ubuntu 22.04)", + }, + }, + }, + } + + mux := http.NewServeMux() + mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/json") + mustWrite(w, `{ + "data": { + "search": { + "pageInfo": { + "endCursor": "Y3Vyc29yOjE=", + "hasNextPage": false + }, + "nodes": [ + { + "number": 32, + "id": "I_kwDOJBmYg86J6maD", + "createdAt": "2024-05-23T21:03:09Z", + "updatedAt": "2024-05-28T15:42:02Z", + "state": "OPEN", + "stateReason": null, + "closedAt": null, + "author": { + "login": "drewAdorno" + }, + "authorAssociation": "NONE", + "title": "subdomains not redirecting", + "body": "Hi,\r\nI was able to configure and successfully use localias in was wsl env (ubuntu 22.04)" + } + ] + } + } + }`) + }) + client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}}) + + var got queryIssues + err := client.Exec(context.Background(), expectedQuery, &got, map[string]interface{}{ + "searchQuery": "test", + "cursor0": "test", + }) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(want, got) { + t.Errorf("got %+v, want: %+v", got, want) + } +} + // localRoundTripper is an http.RoundTripper that executes HTTP transactions // by using handler directly, instead of going over an HTTP connection. type localRoundTripper struct { diff --git a/pkg/jsonutil/graphql.go b/pkg/jsonutil/graphql.go index 901348b..bd400e3 100644 --- a/pkg/jsonutil/graphql.go +++ b/pkg/jsonutil/graphql.go @@ -163,6 +163,7 @@ func (d *decoder) decode() error { } var f reflect.Value if v.Kind() == reflect.Slice { + someSliceExist = true // we want to append the template item copy // so that all the inner structure gets preserved if v.Len() != 0 { @@ -172,7 +173,6 @@ func (d *decoder) decode() error { } v.Set(reflect.Append(v, copied)) // v = append(v, T). f = v.Index(v.Len() - 1) - someSliceExist = true } } d.vs[i] = append(d.vs[i], f)