hup-0.3.0.2: src-hspec-test/Distribution/Hup/Upload/MockWebApp.hs
{-# LANGUAGE OverloadedStrings #-}
module Distribution.Hup.Upload.MockWebApp
(
webApp
)
where
import Control.Exception (throwIO)
import Control.Monad
import Control.Monad.IO.Class (liftIO, MonadIO)
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as LBS -- pack
import Data.Maybe (fromJust)
import Network.HTTP.Types as T (StdMethod(..))
import Network.Wai.Parse as Parse (FileInfo(..), fileName)
import Web.Simple (ok, respond,Controller, ControllerT, routePattern, queryParam, routeMethod,parseForm, request, rawPathInfo,controllerApp, Application)
import Distribution.Hup.Upload
import Distribution.Hup.Parse
-- | We send the parsed results back as plain text,
-- parseable by 'Text.Read.read'.
webApp :: Application
webApp = controllerApp () $ do
myReq <- request
routeMethod T.POST $ do path <- rawPathInfo <$> request
let isCand = if "/candidates/" `BS.isSuffixOf`path
then CandidatePkg
else NormalPkg
when (path == "/packages/" ||
path == "/packages/candidates/") $ do
(_params, files) <- parseForm
handlePost isCand files
routeMethod T.PUT $ routePattern "/package/:pkgVer/:isCand" $ do
pkgVer <- fromJust <$> queryParam "pkgVer"
let filename = pkgVer :: String
isCand <- fromJust <$> queryParam "isCand"
let isCand' = if ("candidate" :: String) == isCand
then CandidatePkg
else NormalPkg
let remainingBit = if "candidate"== isCand
then "docs"
else ""
routePattern remainingBit $
handlePut isCand' filename
where
handlePost :: IsCandidate -> [(a, FileInfo c)] -> ControllerT s IO b
handlePost isCand files = do
ioAssert (length files == 1)
"posted package should have exactly 1 file"
let filename = BS.unpack $ Parse.fileName $ snd $ head files
parsed :: Either String (IsDocumentation, Package)
parsed = parseTgzFilename' filename
respond $ ok "text/plain" $ LBS.pack $ show (IsPackage, isCand, parsed)
handlePut :: IsCandidate -> FilePath -> Controller s a
handlePut isCand filename = do
let parsed :: Either String (IsDocumentation, Package)
parsed = parseTgzFilename' (filename ++ "-docs.tar.gz")
respond $ ok "text/plain" $ LBS.pack $
show (IsDocumentation, isCand, parsed)
-- duplicated code from Hup.UploadSpec, remove
-- or refactor
ioAssert :: MonadIO f => Bool -> String -> f ()
ioAssert pred mesg =
unless pred $
liftIO $ throwIO $ userError mesg