packages feed

yesod-pagination-0.2.0.0: tests/main.hs

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}

import Control.Monad
import Control.Monad.Logger
import Control.Monad.Trans.Resource
import qualified Data.ByteString.Lazy.UTF8 as B
import Data.Maybe
import Data.Pool
import Data.Text (Text)
import Database.Persist.Sqlite hiding (get)
import Network.Wai.Test
import Test.Hspec
import Text.Shakespeare.Text
import Yesod hiding (get)
import Yesod.Paginate
import Yesod.Test

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Item
    name String
    deriving Eq Read Show
|]

data TestApp = TestApp ConnectionPool
instance Yesod TestApp

mkYesod "TestApp" [parseRoutes|
/items ItemsR GET
|]

instance YesodPersist TestApp where
    type YesodPersistBackend TestApp = SqlPersistT

    runDB act = do
        TestApp p <- getYesod
        runSqlPool act p

getItemsR :: HandlerT TestApp IO TypedContent
getItemsR = do
    (items :: Page (Entity Item)) <- paginate
    selectRep . provideRep $ return [stext|#{show items}|]

main :: IO ()
main = withSqlitePool ":memory:" 1 $ \pool -> do
    runResourceT $ runStderrLoggingT $ flip runSqlPool pool $
        runMigration migrateAll
    hspec $ yesodSpec (TestApp pool) $
        ydescribe "pages" $ do
            yit "with nothing" $ do
                clearOut pool

                get ItemsR
                wantPage $ Page [] 1 Nothing Nothing

            yit "with some items" $ do
                clearOut pool
                k <- liftIO $ runSqlPersistMPool (insert $ Item "hello, world!") pool

                get ItemsR
                wantPage $ Page [Entity k (Item "hello, world!")] 1 Nothing Nothing

            yit "with two pages" $ do
                clearOut pool
                liftIO $ runSqlPersistMPool (replicateM_ 18 $ insert $ Item "hello, world!") pool

                get ItemsR
                cp <- getPage
                liftIO $ length (pageResults cp) `shouldBe` 10
                liftIO $ previousPage cp `shouldBe` Nothing

                get $ fromJust (nextPage cp)
                cp' <- getPage
                liftIO $ length (pageResults cp') `shouldBe` 8
                liftIO $ nextPage cp' `shouldBe` Nothing

            yit "caps at the maximum page" $ do
                clearOut pool
                liftIO $ runSqlPersistMPool (replicateM_ 5 $ insert $ Item "hello, world!") pool

                get ("/items?page=2" :: Text)
                cp <- getPage
                liftIO $ length (pageResults cp) `shouldBe` 5

getPage :: YesodExample TestApp (Page (Entity Item))
getPage = withResponse $ \SResponse { simpleBody } ->
    return $ read (B.toString simpleBody)

wantPage :: Page (Entity Item) -> YesodExample TestApp ()
wantPage p = do
    pg <- getPage
    liftIO $ pg `shouldBe` p

clearOut :: MonadIO m => Pool Connection -> m ()
clearOut pool = liftIO $ runSqlPersistMPool (deleteWhere ([] :: [Filter Item])) pool