graphql-engine/server/tests-hspec/Harness/Test/Introspection.hs

89 lines
2.7 KiB
Haskell
Raw Normal View History

{-# LANGUAGE QuasiQuotes #-}
-- | This module contains functions that help defining tests in terms the
-- results of GraphQL introspection queries.
module Harness.Test.Introspection
( introspectTypes,
introspectEnums,
)
where
import Data.Aeson.Types (Parser, Value, listParser, parseEither, withObject, (.:), (.:?))
import Data.Text
import Data.Text.Encoding (encodeUtf8)
import Harness.GraphqlEngine qualified as GraphqlEngine
import Harness.Quoter.Graphql
import Harness.TestEnvironment (TestEnvironment)
import Hasura.Prelude
----------------------------------
-- Test helpers
-- | Query the names of all known types by a GraphQL introspection query against
-- a 'TestEnvironment' under a specific role.
introspectTypes :: TestEnvironment -> Text -> IO [Text]
introspectTypes env role = do
res <-
GraphqlEngine.postGraphqlWithHeaders
env
[("X-Hasura-Role", encodeUtf8 role)]
[graphql|
query IntrospectTypes { __schema {
types { name }
}}
|]
onLeft (parseEither getTypes res) fail
where
getTypes :: Value -> Parser [Text]
getTypes = withObject "introspection top-level" $ \top -> do
d <- top .: "data"
sch <- d .: "__schema"
types <- sch .: "types"
listParser parseType types
parseType :: Value -> Parser Text
parseType = withObject "a 'types' element" $ \types -> types .: "name"
-- | Query all known enum types by a GraphQL introspection query against
-- a 'TestEnvironment' under a specific role.
--
-- Returns the names and enum values '(enumName :: Text, enumValues :: [Text])'
-- of all known enums.
introspectEnums :: TestEnvironment -> Text -> IO [(Text, [Text])]
introspectEnums env role = do
res <-
GraphqlEngine.postGraphqlWithHeaders
env
[("X-Hasura-Role", encodeUtf8 role)]
[graphql|
query IntrospectEnums {
__schema {
types {
enumValues {
name
}
name
}
}
}
|]
onLeft (parseEither getEnums res) fail
where
getEnums :: Value -> Parser [(Text, [Text])]
getEnums = withObject "introspection top-level" $ \top -> do
d <- top .: "data"
sch <- d .: "__schema"
types <- sch .: "types"
catMaybes <$> listParser parseEnum types
parseEnum :: Value -> Parser (Maybe (Text, [Text]))
parseEnum = withObject "a 'types' element" $ \types -> do
name <- types .: "name"
maybeVals <- types .:? "enumValues"
case maybeVals of
Nothing -> return Nothing
Just vals -> Just . (name,) <$> listParser parseEnumValue vals
parseEnumValue :: Value -> Parser Text
parseEnumValue = withObject "enumValue" (.: "name")