@@ -8,10 +8,13 @@ module EndToEndTests (tests) where
8
8
9
9
import Protolude
10
10
11
- import Data.Aeson (toJSON , object , (.=) )
12
- import GraphQL (interpretAnonymousQuery )
11
+ import Data.Aeson (Value (Null ), toJSON , object , (.=) )
12
+ import qualified Data.Map as Map
13
+ import GraphQL (compileQuery , executeQuery , interpretAnonymousQuery , interpretQuery )
13
14
import GraphQL.API (Object , Field )
15
+ import GraphQL.Internal.Syntax.AST (Variable (.. ))
14
16
import GraphQL.Resolver ((:<>) (.. ), Handler )
17
+ import GraphQL.Value (makeName )
15
18
import GraphQL.Value.ToValue (ToValue (.. ))
16
19
import Test.Tasty (TestTree )
17
20
import Test.Tasty.Hspec (testSpec , describe , it , shouldBe )
@@ -196,3 +199,93 @@ tests = testSpec "End-to-end tests" $ do
196
199
]
197
200
]
198
201
toJSON (toValue response) `shouldBe` expected
202
+ describe " interpretQuery" $ do
203
+ it " Handles the simplest named query" $ do
204
+ let root = pure (viewServerDog mortgage)
205
+ let query = [r |query myQuery {
206
+ dog {
207
+ name
208
+ }
209
+ }
210
+ |]
211
+ response <- interpretQuery @ QueryRoot root query Nothing mempty
212
+ let expected =
213
+ object
214
+ [ " data" .= object
215
+ [ " dog" .= object
216
+ [ " name" .= (" Mortgage" :: Text )
217
+ ]
218
+ ]
219
+ ]
220
+ toJSON (toValue response) `shouldBe` expected
221
+ it " Allows calling query by name" $ do
222
+ let root = pure (viewServerDog mortgage)
223
+ let query = [r |query myQuery {
224
+ dog {
225
+ name
226
+ }
227
+ }
228
+ |]
229
+ let Right name = makeName " myQuery"
230
+ response <- interpretQuery @ QueryRoot root query (Just name) mempty
231
+ let expected =
232
+ object
233
+ [ " data" .= object
234
+ [ " dog" .= object
235
+ [ " name" .= (" Mortgage" :: Text )
236
+ ]
237
+ ]
238
+ ]
239
+ toJSON (toValue response) `shouldBe` expected
240
+ describe " Handles variables" $ do
241
+ let root = pure (viewServerDog mortgage)
242
+ let Right query =
243
+ compileQuery [r |query myQuery($whichCommand: DogCommand) {
244
+ dog {
245
+ name
246
+ doesKnowCommand(dogCommand: $whichCommand)
247
+ }
248
+ }
249
+ |]
250
+ it " Errors when no variables provided" $ do
251
+ response <- executeQuery @ QueryRoot root query Nothing mempty
252
+ let expected =
253
+ object
254
+ [ " data" .= object
255
+ [ " dog" .= object
256
+ [ " name" .= (" Mortgage" :: Text )
257
+ , " doesKnowCommand" .= Null
258
+ ]
259
+ ]
260
+ , " errors" .=
261
+ [
262
+ object
263
+ -- TODO: This error message is pretty bad. We should define
264
+ -- a typeclass for client-friendly "Show" (separate from
265
+ -- actual Show which remains extremely useful for debugging)
266
+ -- and use that when including values in error messages.
267
+ [ " message" .= (" Could not coerce Name {unName = \" dogCommand\" } to valid value: ValueScalar' ConstNull not an enum: [Right (Name {unName = \" Sit\" }),Right (Name {unName = \" Down\" }),Right (Name {unName = \" Heel\" })]" :: Text )
268
+ ]
269
+ ]
270
+ ]
271
+ toJSON (toValue response) `shouldBe` expected
272
+ it " Substitutes variables when they are provided" $ do
273
+ -- TODO: This is a crummy way to make a variable map. jml doesn't want
274
+ -- to come up with a new API in this PR, but probably we should have a
275
+ -- very simple function to turn a JSON value / object into the
276
+ -- variable map that we desire. Alternatively, we should have APIs
277
+ -- like Aeson does.
278
+ let Right varName = makeName " whichCommand"
279
+ let vars = Map. singleton (Variable varName) (toValue Sit )
280
+ response <- executeQuery @ QueryRoot root query Nothing vars
281
+ let expected =
282
+ object
283
+ [ " data" .= object
284
+ [ " dog" .= object
285
+ [ " name" .= (" Mortgage" :: Text )
286
+ , " doesKnowCommand" .= False
287
+ ]
288
+ ]
289
+ ]
290
+ toJSON (toValue response) `shouldBe` expected
291
+
0 commit comments