summaryrefslogtreecommitdiff
path: root/tests/Test/FragmentSpec.hs
blob: 7b2bb929c59a2a9dac054eaa96984c4d62625c48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
module Test.FragmentSpec
    ( spec
    ) where

import Data.Aeson (Value(..), object, (.=))
import qualified Data.HashMap.Strict as HashMap
import Data.List.NonEmpty (NonEmpty(..))
import Data.Text (Text)
import Language.GraphQL
import qualified Language.GraphQL.Schema as Schema
import Test.Hspec (Spec, describe, it, shouldBe, shouldNotSatisfy)
import Text.RawString.QQ (r)

size :: Schema.Resolver IO
size = Schema.scalar "size" $ return ("L" :: Text)

circumference :: Schema.Resolver IO
circumference = Schema.scalar "circumference" $ return (60 :: Int)

garment :: Text -> Schema.Resolver IO
garment typeName = Schema.object "garment" $ return
    [ if typeName == "Hat" then circumference else size
    , Schema.scalar "__typename" $ return typeName
    ]

inlineQuery :: Text
inlineQuery = [r|{
  garment {
    ... on Hat {
      circumference
    }
    ... on Shirt {
      size
    }
  }
}|]

spec :: Spec
spec = describe "Inline fragment executor" $ do
    it "chooses the first selection if the type matches" $ do
        actual <- graphql (garment "Hat" :| []) inlineQuery
        let expected = object
                [ "data" .= object
                    [ "garment" .= object
                        [ "circumference" .= (60 :: Int)
                        ]
                    ]
                ]
         in actual `shouldBe` expected

    it "chooses the last selection if the type matches" $ do
        actual <- graphql (garment "Shirt" :| []) inlineQuery
        let expected = object
                [ "data" .= object
                    [ "garment" .= object
                        [ "size" .= ("L" :: Text)
                        ]
                    ]
                ]
         in actual `shouldBe` expected

    it "embeds inline fragments without type" $ do
        let query = [r|{
          garment {
            circumference
            ... {
              size
            }
          }
        }|]
            resolvers = Schema.object "garment" $ return [circumference,  size]

        actual <- graphql (resolvers :| []) query
        let expected = object
                [ "data" .= object
                    [ "garment" .= object
                        [ "circumference" .= (60 :: Int)
                        , "size" .= ("L" :: Text)
                        ]
                    ]
                ]
         in actual `shouldBe` expected

    it "evaluates fragments on Query" $ do
        let query = [r|{
          ... {
            size
          }
        }|]

        actual <- graphql (size :| []) query
        actual `shouldNotSatisfy` hasErrors
      where
        hasErrors (Object object') = HashMap.member "errors" object'
        hasErrors _ = True