summaryrefslogtreecommitdiff
path: root/tests/Language/GraphQL/Execute/CoerceSpec.hs
blob: 339c2e3232f9c9c8436554a943287722a60066ab (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
{-# LANGUAGE OverloadedStrings #-}
module Language.GraphQL.Execute.CoerceSpec
    ( spec
    ) where

import Data.Aeson as Aeson ((.=))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson
import qualified Data.HashMap.Strict as HashMap
import Data.Maybe (isNothing)
import Data.Scientific (scientific)
import qualified Language.GraphQL.Execute.Coerce as Coerce
import Language.GraphQL.Type
import qualified Language.GraphQL.Type.In as In
import Prelude hiding (id)
import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy)

direction :: EnumType
direction = EnumType "Direction" Nothing  $ HashMap.fromList
    [ ("NORTH", EnumValue Nothing)
    , ("EAST", EnumValue Nothing)
    , ("SOUTH", EnumValue Nothing)
    , ("WEST", EnumValue Nothing)
    ]

singletonInputObject :: In.Type
singletonInputObject = In.NamedInputObjectType type'
  where
    type' = In.InputObjectType "ObjectName" Nothing inputFields
    inputFields = HashMap.singleton "field" field
    field = In.InputField Nothing (In.NamedScalarType string) Nothing

namedIdType :: In.Type
namedIdType = In.NamedScalarType id

spec :: Spec
spec = do
    describe "VariableValue Aeson" $ do
        it "coerces strings" $
            let expected = Just (String "asdf")
                actual = Coerce.coerceVariableValue
                    (In.NamedScalarType string) (Aeson.String "asdf")
             in actual `shouldBe` expected
        it "coerces non-null strings" $
            let expected = Just (String "asdf")
                actual = Coerce.coerceVariableValue
                    (In.NonNullScalarType string) (Aeson.String "asdf")
             in actual `shouldBe` expected
        it "coerces booleans" $
            let expected = Just (Boolean True)
                actual = Coerce.coerceVariableValue
                    (In.NamedScalarType boolean) (Aeson.Bool True)
             in actual `shouldBe` expected
        it "coerces zero to an integer" $
            let expected = Just (Int 0)
                actual = Coerce.coerceVariableValue
                    (In.NamedScalarType int) (Aeson.Number 0)
             in actual `shouldBe` expected
        it "rejects fractional if an integer is expected" $
            let actual = Coerce.coerceVariableValue
                    (In.NamedScalarType int) (Aeson.Number $ scientific 14 (-1))
             in actual `shouldSatisfy` isNothing
        it "coerces float numbers" $
            let expected = Just (Float 1.4)
                actual = Coerce.coerceVariableValue
                    (In.NamedScalarType float) (Aeson.Number $ scientific 14 (-1))
             in actual `shouldBe` expected
        it "coerces IDs" $
            let expected = Just (String "1234")
                json = Aeson.String "1234"
                actual = Coerce.coerceVariableValue namedIdType json
             in actual `shouldBe` expected
        it "coerces input objects" $
            let actual = Coerce.coerceVariableValue singletonInputObject
                    $ Aeson.object ["field" .= ("asdf" :: Aeson.Value)]
                expected = Just $ Object $ HashMap.singleton "field" "asdf"
             in actual `shouldBe` expected
        it "skips the field if it is missing in the variables" $
            let actual = Coerce.coerceVariableValue
                    singletonInputObject Aeson.emptyObject
                expected = Just $ Object HashMap.empty
             in actual `shouldBe` expected
        it "fails if input object value contains extra fields" $
            let actual = Coerce.coerceVariableValue singletonInputObject
                    $ Aeson.object variableFields
                variableFields =
                    [ "field" .= ("asdf" :: Aeson.Value)
                    , "extra" .= ("qwer" :: Aeson.Value)
                    ]
             in actual `shouldSatisfy` isNothing
        it "preserves null" $
            let actual = Coerce.coerceVariableValue namedIdType Aeson.Null
             in actual `shouldBe` Just Null
        it "preserves list order" $
            let list = Aeson.toJSONList ["asdf" :: Aeson.Value, "qwer"]
                listType = (In.ListType $ In.NamedScalarType string)
                actual = Coerce.coerceVariableValue listType list
                expected = Just $ List [String "asdf", String "qwer"]
             in actual `shouldBe` expected

    describe "coerceInputLiteral" $ do
        it "coerces enums" $
            let expected = Just (Enum "NORTH")
                actual = Coerce.coerceInputLiteral
                    (In.NamedEnumType direction) (Enum "NORTH")
             in actual `shouldBe` expected
        it "fails with non-existing enum value" $
            let actual = Coerce.coerceInputLiteral
                    (In.NamedEnumType direction) (Enum "NORTH_EAST")
             in actual `shouldSatisfy` isNothing
        it "coerces integers to IDs" $
            let expected = Just (String "1234")
                actual = Coerce.coerceInputLiteral namedIdType (Int 1234)
             in actual `shouldBe` expected
        it "coerces nulls" $ do
            let actual = Coerce.coerceInputLiteral namedIdType Null
             in actual `shouldBe` Just Null
        it "wraps singleton lists" $ do
            let expected = Just $ List [List [String "1"]]
                embeddedType = In.ListType $ In.ListType namedIdType
                actual = Coerce.coerceInputLiteral embeddedType (String "1")
             in actual `shouldBe` expected