{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-} module NamedResolvers ( runNamedResolversTest, ) where import qualified Data.ByteString.Lazy.Char8 as LBS import Data.Morpheus.App ( App (..), mkApp, runApp, ) import Data.Morpheus.App.Internal.Resolving (resultOr) import Data.Morpheus.App.NamedResolvers ( NamedResolverFunction, RootResolverValue, enum, getArgument, list, object, queryResolvers, ref, refs, variant, ) import Data.Morpheus.Core ( parseSchema, ) import Data.Morpheus.Types.IO ( GQLRequest (..), GQLResponse, ) import Data.Morpheus.Types.Internal.AST ( QUERY, Schema, VALID, ) import Relude hiding (ByteString) import Test.Morpheus ( FileUrl, testApi, ) import Test.Tasty ( TestTree, ) -- DEITIES resolverDeities :: Monad m => RootResolverValue e m resolverDeities = queryResolvers [ ( "Query", traverse ( const $ object [ ("deity", ref "Deity" <$> getArgument "id"), ("deities", pure $ refs "Deity" ["zeus", "morpheus"]) ] ) ), ("Deity", deityResolver) ] deityResolver :: Monad m => NamedResolverFunction QUERY e m deityResolver = traverse deityRes where deityRes "zeus" = object [ ("name", pure "Zeus"), ("power", pure $ list []) ] deityRes _ = object [ ("name", pure "Morpheus"), ("power", pure $ list [enum "Shapeshifting"]) ] -- REALMS resolverRealms :: Monad m => RootResolverValue e m resolverRealms = queryResolvers [ ( "Query", traverse ( const $ object [ ("realm", ref "Realm" <$> getArgument "id"), ("realms", pure $ refs "Realm" ["olympus", "dreams"]) ] ) ), ("Deity", deityResolverExt), ("Realm", realmResolver) ] deityResolverExt :: Monad m => NamedResolverFunction QUERY e m deityResolverExt = traverse deityExt where deityExt "zeus" = object [("realm", pure $ ref "Realm" "olympus")] deityExt "morpheus" = object [("realm", pure $ ref "Realm" "dreams")] deityExt _ = object [] realmResolver :: Monad m => NamedResolverFunction QUERY e m realmResolver = traverse realmResolver' where realmResolver' "olympus" = object [ ("name", pure "Mount Olympus"), ("owner", pure $ ref "Deity" "zeus") ] realmResolver' "dreams" = object [ ("name", pure "Fictional world of dreams"), ("owner", pure $ ref "Deity" "morpheus") ] realmResolver' _ = object [ ("name", pure "None") ] -- ENTITIES resolverEntities :: Monad m => RootResolverValue e m resolverEntities = queryResolvers [ ( "Query", traverse ( const $ object [ ("entity", ref "Entity" <$> getArgument "id"), ( "entities", pure $ refs "Entity" ["zeus", "morpheus", "olympus", "dreams"] ) ] ) ), ("Entity", resolveEntity) ] resolveEntity :: Monad m => NamedResolverFunction QUERY e m resolveEntity = traverse resEntity where resEntity "zeus" = variant "Deity" "zeus" resEntity "morpheus" = variant "Deity" "morpheus" resEntity "olympus" = variant "Realm" "olympus" resEntity "dreams" = variant "Realm" "dreams" resEntity _ = object [] getSchema :: String -> IO (Schema VALID) getSchema url = LBS.readFile url >>= resultOr (fail . show) pure . parseSchema getApps :: FileUrl -> IO (App e IO) getApps _ = do schemaDeities <- getSchema "test/named-resolvers/deities.gql" schemaRealms <- getSchema "test/named-resolvers/realms.gql" schemaEntities <- getSchema "test/named-resolvers/entities.gql" pure $ mkApp schemaDeities resolverDeities <> mkApp schemaRealms resolverRealms <> mkApp schemaEntities resolverEntities runNamedResolversTest :: FileUrl -> FileUrl -> TestTree runNamedResolversTest url = testApi api where api :: GQLRequest -> IO GQLResponse api req = getApps url >>= (`runApp` req)