-- | Drives the WAI application in-process, against a fresh in-memory -- database for each test. module Main (main) where import Control.Exception (bracket) import Control.Monad.IO.Class (liftIO) import Data.ByteString (ByteString) import Data.ByteString qualified as BS import Data.ByteString.Lazy qualified as BL import Data.Text qualified as T import Data.Text.Encoding qualified as T import Network.HTTP.Types import Network.Wai (Application, requestHeaders, requestMethod) import Network.Wai.Test import Test.Hspec import Todo.App import Todo.Db qualified as Db origin :: ByteString origin = "http://127.0.0.1:8080" withApp :: (Application -> IO a) -> IO a withApp run = bracket (Db.open ":memory:") Db.close $ \db -> run (app (Config (Just origin) False) db) get :: ByteString -> Session SResponse get path = request (setPath defaultRequest path) post :: ByteString -> [(ByteString, ByteString)] -> [Header] -> Session SResponse post path form headers = srequest $ SRequest (setPath defaultRequest {requestMethod = methodPost, requestHeaders = (hContentType, "application/x-www-form-urlencoded") : headers} path) (BL.fromStrict (BS.drop 1 (renderSimpleQuery True form))) body :: SResponse -> T.Text body = T.decodeUtf8 . BL.toStrict . simpleBody -- | Labels on the page, in order. labels :: SResponse -> [T.Text] labels r = [ T.takeWhile (/= '<') (T.drop 1 (T.dropWhile (/= '>') chunk)) | chunk <- drop 1 (T.splitOn "data-action=\"edit\"" (body r)) ] main :: IO () main = hspec $ around withApp $ do describe "pages" $ do it "serves an empty list and hands out a cookie" $ runSession $ do r <- get "/" assertStatus 200 r let cookie = lookup hSetCookie (simpleHeaders r) liftIO $ do cookie `shouldSatisfy` maybe False ("todo_list=" `BS.isPrefixOf`) cookie `shouldSatisfy` maybe False ("HttpOnly" `BS.isInfixOf`) cookie `shouldSatisfy` maybe False ("SameSite=Lax" `BS.isInfixOf`) cookie `shouldSatisfy` maybe False ("Path=/" `BS.isInfixOf`) assertBodyContains "