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