assumpta-core-0.1.0.2: src/Network/Mail/Assumpta/Mock.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
Provides 'MockSmtp', a 'mock' instance of 'MonadSmtp', which simply
records (via use of a 'Writer') any bytes sent through it.
(Making it technically a \"spy", I think --
see <https://martinfowler.com/articles/mocksArentStubs.html>.)
Plus a transformer version, 'MockSmtpT'.
Sample use:
>>> runMockSmtp (noop >> quit)
"NOOP\r\nQUIT\r\n"
For a slightly longer example, see \"simple-client-session-mock-bs.hs"
in the \"examples" directory.
-}
module Network.Mail.Assumpta.Mock
where
import Control.Monad.Writer
import Data.Functor.Identity (Identity)
import Data.ByteString ( ByteString )
import Network.Mail.Assumpta.MonadSmtp
-- | Concrete transformer for mock 'MonadSmtp'
-- monads.
newtype MockSmtpT m a = MockSmtpT {
runMockSmtpT :: WriterT ByteString m a
}
deriving (Functor, Applicative, Monad, MonadIO, MonadFix
, MonadWriter ByteString)
-- | Lift into 'MockSmtpT'.
liftMockSmtpT :: Monad m => m a -> MockSmtpT m a
liftMockSmtpT = MockSmtpT . lift
instance MonadTrans MockSmtpT where
lift = liftMockSmtpT
-- | 'MockSmtp' specialized to 'Identity'
type MockSmtp = MockSmtpT Identity
-- | In this mock monad, 'send' writes to the underlying 'Writer';
-- 'expectCode' and 'tlsUpgrade' are no-ops; and 'getReply'
-- returns an empty list. (In breach of the req. that a
-- reply always contains at least one line.)
instance Monad m => MonadSmtp (MockSmtpT m) where
send = MockSmtpT . tell
getReply = return []
expectCode = const $ pure ()
tlsUpgrade = pure ()
-- | Run an 'MonadSmtp' computation using a mock,
-- and return the 'ByteString' content written.
runMockSmtp :: MockSmtp a -> ByteString
runMockSmtp a = execWriter $ runMockSmtpT a