Merge pull request #410 from meteficha/runFakeHandler
New function runFakeHandler.
This commit is contained in:
commit
a9b10ce0bc
@ -40,6 +40,7 @@ module Yesod.Core
|
|||||||
-- * Misc
|
-- * Misc
|
||||||
, yesodVersion
|
, yesodVersion
|
||||||
, yesodRender
|
, yesodRender
|
||||||
|
, runFakeHandler
|
||||||
-- * Re-exports
|
-- * Re-exports
|
||||||
, module Yesod.Content
|
, module Yesod.Content
|
||||||
, module Yesod.Dispatch
|
, module Yesod.Dispatch
|
||||||
|
|||||||
@ -36,6 +36,7 @@ module Yesod.Internal.Core
|
|||||||
, resolveApproot
|
, resolveApproot
|
||||||
, Approot (..)
|
, Approot (..)
|
||||||
, FileUpload (..)
|
, FileUpload (..)
|
||||||
|
, runFakeHandler
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Yesod.Content
|
import Yesod.Content
|
||||||
@ -55,6 +56,7 @@ import Yesod.Internal.Request
|
|||||||
import qualified Web.ClientSession as CS
|
import qualified Web.ClientSession as CS
|
||||||
import qualified Data.ByteString.Char8 as S8
|
import qualified Data.ByteString.Char8 as S8
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
|
import qualified Data.IORef as I
|
||||||
import Data.Monoid
|
import Data.Monoid
|
||||||
import Text.Hamlet
|
import Text.Hamlet
|
||||||
import Text.Julius
|
import Text.Julius
|
||||||
@ -64,6 +66,7 @@ import Data.Text.Lazy.Builder (toLazyText)
|
|||||||
import Data.Text.Lazy.Encoding (encodeUtf8)
|
import Data.Text.Lazy.Encoding (encodeUtf8)
|
||||||
import Data.Maybe (fromMaybe, isJust)
|
import Data.Maybe (fromMaybe, isJust)
|
||||||
import Control.Monad.IO.Class (MonadIO (liftIO))
|
import Control.Monad.IO.Class (MonadIO (liftIO))
|
||||||
|
import Control.Monad.Trans.Resource (runResourceT)
|
||||||
import Web.Cookie (parseCookies)
|
import Web.Cookie (parseCookies)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.Time
|
import Data.Time
|
||||||
@ -752,3 +755,82 @@ loadClientSession key timeout sessionName master req now = return (sess, save)
|
|||||||
expires = fromIntegral (timeout * 60) `addUTCTime` now'
|
expires = fromIntegral (timeout * 60) `addUTCTime` now'
|
||||||
sessionVal iv = encodeClientSession key iv expires host sess'
|
sessionVal iv = encodeClientSession key iv expires host sess'
|
||||||
|
|
||||||
|
|
||||||
|
-- | Run a 'GHandler' completely outside of Yesod. This
|
||||||
|
-- function comes with many caveats and you shouldn't use it
|
||||||
|
-- unless you fully understand what it's doing and how it works.
|
||||||
|
--
|
||||||
|
-- As of now, there's only one reason to use this function at
|
||||||
|
-- all: in order to run unit tests of functions inside 'GHandler'
|
||||||
|
-- but that aren't easily testable with a full HTTP request.
|
||||||
|
-- Even so, it's better to use @wai-test@ or @yesod-test@ instead
|
||||||
|
-- of using this function.
|
||||||
|
--
|
||||||
|
-- This function will create a fake HTTP request (both @wai@'s
|
||||||
|
-- 'W.Request' and @yesod@'s 'Request') and feed it to the
|
||||||
|
-- @GHandler@. The only useful information the @GHandler@ may
|
||||||
|
-- get from the request is the session map, which you must supply
|
||||||
|
-- as argument to @runFakeHandler@. All other fields contain
|
||||||
|
-- fake information, which means that they can be accessed but
|
||||||
|
-- won't have any useful information. The response of the
|
||||||
|
-- @GHandler@ is completely ignored, including changes to the
|
||||||
|
-- session, cookies or headers. We only return you the
|
||||||
|
-- @GHandler@'s return value.
|
||||||
|
runFakeHandler :: (Yesod master, MonadIO m) =>
|
||||||
|
SessionMap
|
||||||
|
-> (master -> Logger)
|
||||||
|
-> master
|
||||||
|
-> GHandler master master a
|
||||||
|
-> m (Either ErrorResponse a)
|
||||||
|
runFakeHandler fakeSessionMap logger master handler = liftIO $ do
|
||||||
|
ret <- I.newIORef (Left $ InternalError "runFakeHandler: no result")
|
||||||
|
let handler' = do liftIO . I.writeIORef ret . Right =<< handler
|
||||||
|
return ()
|
||||||
|
let YesodApp yapp =
|
||||||
|
runHandler
|
||||||
|
handler'
|
||||||
|
(yesodRender master "")
|
||||||
|
Nothing
|
||||||
|
id
|
||||||
|
master
|
||||||
|
master
|
||||||
|
(fileUpload master)
|
||||||
|
(messageLogger master $ logger master)
|
||||||
|
errHandler err =
|
||||||
|
YesodApp $ \_ _ _ session -> do
|
||||||
|
liftIO $ I.writeIORef ret (Left err)
|
||||||
|
return $ YARPlain
|
||||||
|
H.status500
|
||||||
|
[]
|
||||||
|
typePlain
|
||||||
|
(toContent ("runFakeHandler: errHandler" :: S8.ByteString))
|
||||||
|
session
|
||||||
|
fakeWaiRequest =
|
||||||
|
W.Request
|
||||||
|
{ W.requestMethod = "POST"
|
||||||
|
, W.httpVersion = H.http11
|
||||||
|
, W.rawPathInfo = "/runFakeHandler/pathInfo"
|
||||||
|
, W.rawQueryString = ""
|
||||||
|
, W.serverName = "runFakeHandler-serverName"
|
||||||
|
, W.serverPort = 80
|
||||||
|
, W.requestHeaders = []
|
||||||
|
, W.isSecure = False
|
||||||
|
, W.remoteHost = error "runFakeHandler-remoteHost"
|
||||||
|
, W.pathInfo = ["runFakeHandler", "pathInfo"]
|
||||||
|
, W.queryString = []
|
||||||
|
, W.requestBody = mempty
|
||||||
|
, W.vault = mempty
|
||||||
|
}
|
||||||
|
fakeRequest =
|
||||||
|
Request
|
||||||
|
{ reqGetParams = []
|
||||||
|
, reqCookies = []
|
||||||
|
, reqWaiRequest = fakeWaiRequest
|
||||||
|
, reqLangs = []
|
||||||
|
, reqToken = Just "NaN" -- not a nonce =)
|
||||||
|
, reqBodySize = 0
|
||||||
|
}
|
||||||
|
fakeContentType = []
|
||||||
|
_ <- runResourceT $ yapp errHandler fakeRequest fakeContentType fakeSessionMap
|
||||||
|
I.readIORef ret
|
||||||
|
{-# WARNING runFakeHandler "Usually you should *not* use runFakeHandler unless you really understand how it works and why you need it." #-}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user