    module Network.Wai.Test.Internal where

    import Network.Wai
    import qualified Control.Monad.Trans.State as ST
    import Control.Monad.Trans.Reader (ReaderT, runReaderT)
    import Data.Map (Map)
    import qualified Data.Map as Map
    import qualified Web.Cookie as Cookie
    import Data.ByteString (ByteString)

    type Session = ReaderT Application (ST.StateT ClientState IO)

    -- |
    --
    -- Since 3.0.6
    type ClientCookies = Map ByteString Cookie.SetCookie

    data ClientState = ClientState
        { ClientState -> ClientCookies
    clientCookies :: ClientCookies
        }

    -- |
    --
    -- Since 3.0.20.0
    initState :: ClientState
    initState :: ClientState
    initState = ClientCookies -> ClientState
    ClientState ClientCookies
    forall k a. Map k a
    Map.empty

    -- | Like 'runSession', but if allows you to hand in cookies and get
    -- the updated cookies back.  One use case for this is writing tests
    -- that address the application under test alternatingly through rest
    -- api and through db handle.
    --
    -- Since 3.0.20.0
    runSessionWith :: ClientState -> Session a -> Application -> IO (a, ClientState)
    runSessionWith :: ClientState -> Session a -> Application -> IO (a, ClientState)
    runSessionWith st :: ClientState
    st session :: Session a
    session app :: Application
    app = StateT ClientState IO a -> ClientState -> IO (a, ClientState)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    ST.runStateT (Session a -> Application -> StateT ClientState IO a
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT Session a
    session Application
    app) ClientState
    st