{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-} module APIConstraints ( runAPIConstraints, ) where import Data.Aeson (Value (..)) import qualified Data.ByteString.Lazy.Char8 as LBS import Data.Morpheus.App ( APIConstraint, App, mkApp, runApp, withConstraint, ) import Data.Morpheus.App.Internal.Resolving (resultOr) import Data.Morpheus.App.NamedResolvers ( RootResolverValue, object, queryResolvers, ) import Data.Morpheus.Core ( parseSchema, ) import Data.Morpheus.Types.IO ( GQLRequest, GQLResponse, ) import Data.Morpheus.Types.Internal.AST ( Schema, VALID, ) import Data.Morpheus.Types.SelectionTree ( SelectionTree (..), ) import Relude hiding (ByteString) import Test.Morpheus ( FileUrl, testApi, ) import Test.Tasty ( TestTree, ) resolvers :: Monad m => RootResolverValue e m resolvers = queryResolvers [ ( "Query", traverse ( const $ object [ ("success", pure "success"), ("forbidden", pure "forbidden!"), ("limited", pure "num <= 5") ] ) ) ] getSchema :: String -> IO (Schema VALID) getSchema url = LBS.readFile url >>= resultOr (fail . show) pure . parseSchema getApp :: FileUrl -> IO (App e IO) getApp _ = (`mkApp` resolvers) <$> getSchema "test/api-constraints/schema.gql" forbidden :: APIConstraint forbidden _ query | hasChild ("forbidden" :: String) query = Left "no forbidden field!" | otherwise = Right () max5 :: APIConstraint max5 _ query = case getChild ("limited" :: Text) query >>= getArgument ("num" :: Text) of Just (Number n) | n > 5 -> Left ("num " <> show n <> " is greater then 5! but found ") _ -> pure () runAPIConstraints :: FileUrl -> FileUrl -> TestTree runAPIConstraints url = testApi api where api :: GQLRequest -> IO GQLResponse api req = do app <- withConstraint max5 . withConstraint forbidden <$> getApp url runApp app req