nakadi-client-0.5.0.0: tests/Network/Nakadi/MonadicAPI/Test.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Network.Nakadi.MonadicAPI.Test where
import ClassyPrelude
import Control.Lens
import Control.Monad.Logger
import Control.Monad.State.Strict
import Control.Monad.Trans.Resource
import Control.Retry
import Network.HTTP.Client
import qualified Network.Nakadi as Nakadi
import Network.Nakadi.Base
import qualified Network.Nakadi.Lenses as L
import Network.Nakadi.Tests.Common
import Test.Tasty
import Test.Tasty.HUnit
httpErrorCallback :: Request -> HttpException -> RetryStatus -> Bool -> App ()
httpErrorCallback _req exn _retryStatus _isFinalFailure =
putStrLn $ "nakadi-client triggered exception: " <> tshow exn
testMonadicAPI :: Nakadi.Config App -> TestTree
testMonadicAPI conf = testGroup "Monadic API"
[ testCase "Simple Monadic API" (testSimpleMonadicAPI conf')
, testCase "Simple NakadiBaseT" (testSimpleNakadiBaseT confLifted)
, testCase "NakadiBaseT with non-trivial stack" (testNonTrivNakadiBaseT confLifted)
, testCase "MonadNakadi instance for ReaderT" (testReaderT conf)
]
where conf' = Nakadi.setHttpErrorCallback httpErrorCallback conf
confLifted = Nakadi.newConfig Nakadi.httpBackendIO (conf^.L.requestTemplate)
testSimpleMonadicAPI :: Nakadi.Config App -> Assertion
testSimpleMonadicAPI conf = runApp . Nakadi.runNakadiT conf $ do
-- Tests Nakadi call within NakadiT monad transformer
_events <- Nakadi.eventTypesList
-- But we can also call Nakadi from within monad transformers on top of NakadiT:
void $ flip runStateT () $ do
_events <- Nakadi.eventTypesList
pure ()
-- Required for consuming via subscription API is the ability to
-- call Nakadi from within ResourceT:
runResourceT $ do
_partitionStrategies <- Nakadi.registryPartitionStrategies
pure ()
-- We can retrieve the configuration using nakadiAsk:
_conf <- Nakadi.nakadiAsk
pure ()
testSimpleNakadiBaseT :: Nakadi.Config (NakadiBaseT App) -> Assertion
testSimpleNakadiBaseT conf = runApp . Nakadi.runNakadiWithBase conf $ do
_events <- Nakadi.eventTypesList
pure ()
-- | This tests the verbose but more general method of seperating
-- runNakadiBaseT from runNakadiT, changing the monad transformer
-- stack inbetween (by adding NoLoggingT).
testNonTrivNakadiBaseT :: Nakadi.Config (NakadiBaseT App) -> Assertion
testNonTrivNakadiBaseT conf =
runApp . Nakadi.runNakadiBaseT . runNoLoggingT . Nakadi.runNakadiT conf $ do
_events <- Nakadi.eventTypesList
pure ()
data Env = Env { nakadiConfiguration :: Nakadi.Config App }
instance Nakadi.HasNakadiConfig App Env where
nakadiConfig = nakadiConfiguration
-- | This test uses the 'MonadNakadi' instance for 'ReaderT' with a
-- 'HasNakadiConfig' constraint.
testReaderT :: Nakadi.Config App -> Assertion
testReaderT conf = runApp . flip runReaderT (Env conf) $ do
_events <- Nakadi.eventTypesList
pure ()