github.com/HaswinVidanage/gqlgen@v0.8.1-0.20220609041233-69528c1bf712/example/starwars/starwars_test.go (about) 1 package starwars 2 3 import ( 4 "net/http/httptest" 5 "testing" 6 7 "github.com/HaswinVidanage/gqlgen/client" 8 "github.com/HaswinVidanage/gqlgen/example/starwars/generated" 9 "github.com/HaswinVidanage/gqlgen/graphql/introspection" 10 "github.com/HaswinVidanage/gqlgen/handler" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestStarwars(t *testing.T) { 15 srv := httptest.NewServer(handler.GraphQL(generated.NewExecutableSchema(NewResolver()))) 16 c := client.New(srv.URL) 17 18 t.Run("Lukes starships", func(t *testing.T) { 19 var resp struct { 20 Search []struct{ Starships []struct{ Name string } } 21 } 22 c.MustPost(`{ search(text:"Luke") { ... on Human { starships { name } } } }`, &resp) 23 24 require.Equal(t, "X-Wing", resp.Search[0].Starships[0].Name) 25 require.Equal(t, "Imperial shuttle", resp.Search[0].Starships[1].Name) 26 }) 27 28 t.Run("get character", func(t *testing.T) { 29 var resp struct { 30 Character struct { 31 Name string 32 Typename string `json:"__typename"` 33 } 34 } 35 c.MustPost(`{ character(id:"2001") { name, __typename } }`, &resp) 36 37 require.Equal(t, "R2-D2", resp.Character.Name) 38 require.Equal(t, "Droid", resp.Character.Typename) 39 }) 40 41 t.Run("missing character", func(t *testing.T) { 42 var resp struct { 43 Character *struct{ Name string } 44 } 45 c.MustPost(`{ character(id:"2002") { name } }`, &resp) 46 47 require.Nil(t, resp.Character) 48 }) 49 50 t.Run("get droid", func(t *testing.T) { 51 var resp struct { 52 Droid struct{ PrimaryFunction string } 53 } 54 c.MustPost(`{ droid(id:"2001") { primaryFunction } }`, &resp) 55 56 require.Equal(t, "Astromech", resp.Droid.PrimaryFunction) 57 }) 58 59 t.Run("get human", func(t *testing.T) { 60 var resp struct { 61 Human struct { 62 Starships []struct { 63 Name string 64 Length float64 65 } 66 } 67 } 68 c.MustPost(`{ human(id:"1000") { starships { name length(unit:FOOT) } } }`, &resp) 69 70 require.Equal(t, "X-Wing", resp.Human.Starships[0].Name) 71 require.Equal(t, 41.0105, resp.Human.Starships[0].Length) 72 73 require.Equal(t, "Imperial shuttle", resp.Human.Starships[1].Name) 74 require.Equal(t, 65.6168, resp.Human.Starships[1].Length) 75 }) 76 77 t.Run("hero height", func(t *testing.T) { 78 var resp struct { 79 Hero struct { 80 Height float64 81 } 82 } 83 c.MustPost(`{ hero(episode:EMPIRE) { ... on Human { height(unit:METER) } } }`, &resp) 84 85 require.Equal(t, 1.72, resp.Hero.Height) 86 }) 87 88 t.Run("default hero episode", func(t *testing.T) { 89 var resp struct { 90 Hero struct { 91 Name string 92 } 93 } 94 c.MustPost(`{ hero { ... on Droid { name } } }`, &resp) 95 96 require.Equal(t, "R2-D2", resp.Hero.Name) 97 }) 98 99 t.Run("friends", func(t *testing.T) { 100 var resp struct { 101 Human struct { 102 Friends []struct { 103 Name string 104 } 105 } 106 } 107 c.MustPost(`{ human(id: "1001") { friends { name } } }`, &resp) 108 109 require.Equal(t, "Wilhuff Tarkin", resp.Human.Friends[0].Name) 110 }) 111 112 t.Run("friendsConnection.friends", func(t *testing.T) { 113 var resp struct { 114 Droid struct { 115 FriendsConnection struct { 116 Friends []struct { 117 Name string 118 } 119 } 120 } 121 } 122 c.MustPost(`{ droid(id:"2001") { friendsConnection { friends { name } } } }`, &resp) 123 124 require.Equal(t, "Luke Skywalker", resp.Droid.FriendsConnection.Friends[0].Name) 125 require.Equal(t, "Han Solo", resp.Droid.FriendsConnection.Friends[1].Name) 126 require.Equal(t, "Leia Organa", resp.Droid.FriendsConnection.Friends[2].Name) 127 }) 128 129 t.Run("friendsConnection.edges", func(t *testing.T) { 130 var resp struct { 131 Droid struct { 132 FriendsConnection struct { 133 Edges []struct { 134 Cursor string 135 Node struct { 136 Name string 137 } 138 } 139 } 140 } 141 } 142 c.MustPost(`{ droid(id:"2001") { friendsConnection { edges { cursor, node { name } } } } }`, &resp) 143 144 require.Equal(t, "Y3Vyc29yMQ==", resp.Droid.FriendsConnection.Edges[0].Cursor) 145 require.Equal(t, "Luke Skywalker", resp.Droid.FriendsConnection.Edges[0].Node.Name) 146 require.Equal(t, "Y3Vyc29yMg==", resp.Droid.FriendsConnection.Edges[1].Cursor) 147 require.Equal(t, "Han Solo", resp.Droid.FriendsConnection.Edges[1].Node.Name) 148 require.Equal(t, "Y3Vyc29yMw==", resp.Droid.FriendsConnection.Edges[2].Cursor) 149 require.Equal(t, "Leia Organa", resp.Droid.FriendsConnection.Edges[2].Node.Name) 150 }) 151 152 t.Run("unset optional arguments", func(t *testing.T) { 153 var resp struct { 154 Hero struct { 155 FriendsConnection struct { 156 Friends []struct { 157 Name string 158 } 159 } 160 } 161 } 162 query := ` 163 query a($first:Int, $after:ID) { 164 hero { 165 friendsConnection(first:$first, after:$after) { 166 friends { name } 167 } 168 } 169 }` 170 c.MustPost(query, &resp) 171 172 require.Len(t, resp.Hero.FriendsConnection.Friends, 3) 173 }) 174 175 t.Run("mutations must be run in sequence", func(t *testing.T) { 176 var resp struct { 177 A struct{ Time string } 178 B struct{ Time string } 179 C struct{ Time string } 180 } 181 182 c.MustPost(`mutation f{ 183 a:createReview(episode: NEWHOPE, review:{stars:1, commentary:"Blah blah"}) { 184 time 185 } 186 b:createReview(episode: NEWHOPE, review:{stars:1, commentary:"Blah blah"}) { 187 time 188 } 189 c:createReview(episode: NEWHOPE, review:{stars:1, commentary:"Blah blah"}) { 190 time 191 } 192 }`, &resp) 193 194 require.NotEqual(t, resp.A.Time, resp.B.Time) 195 require.NotEqual(t, resp.C.Time, resp.B.Time) 196 }) 197 198 t.Run("multidimensional arrays", func(t *testing.T) { 199 var resp struct { 200 Starship struct { 201 History [][]int 202 } 203 } 204 c.MustPost(`{ starship(id:"3001") { history } }`, &resp) 205 206 require.Len(t, resp.Starship.History, 4) 207 require.Len(t, resp.Starship.History[0], 2) 208 }) 209 210 t.Run("invalid enums in variables", func(t *testing.T) { 211 var resp struct{} 212 213 err := c.Post(`mutation($episode: Episode!) { 214 createReview(episode: $episode, review:{stars:1, commentary:"Blah blah"}) { 215 time 216 } 217 }`, &resp, client.Var("episode", "INVALID")) 218 219 require.EqualError(t, err, `[{"message":"INVALID is not a valid Episode","path":["createReview"]}]`) 220 }) 221 222 t.Run("introspection", func(t *testing.T) { 223 // Make sure we can run the graphiql introspection query without errors 224 var resp interface{} 225 c.MustPost(introspection.Query, &resp) 226 }) 227 228 t.Run("aliased field and non-aliased field", func(t *testing.T) { 229 var resp struct { 230 Character struct { 231 Name string 232 } 233 AliasedCharacter struct { 234 Name string 235 } 236 } 237 c.MustPost(`{ 238 character(id: "2001") { name } 239 aliasedCharacter: character(id: "2001") { name } 240 }`, &resp) 241 require.Equal(t, resp.Character, resp.AliasedCharacter) 242 }) 243 }