packages feed

servant-util-0.3: tests/Test/Servant/Pagination/ImplSpec.hs

{-# LANGUAGE OverloadedLists #-}

module Test.Servant.Pagination.ImplSpec where

import Universum

import qualified Data.Aeson as Aeson
import Servant.API (Get, JSON, (:>))
import Servant.API.Generic (ToServantApi, (:-))
import Servant.Server.Generic (AsServer)
import Servant.OpenApi (toOpenApi)
import Servant.Swagger (toSwagger)

import Test.Hspec (Spec, aroundAll, describe, it)
import Test.Hspec.Expectations (shouldBe)

import Servant.Util
import Servant.Util.Dummy

import Test.Servant.Helpers

-- Server
---------------------------------------------------------------------------

data ApiMethods route = ApiMethods
  { amSimplePaginate
      :: route
      :- "simple"
      :> PaginationParams 'DefUnlimitedPageSize
      :> Get '[JSON] [Int]

  , amDefPageSizePaginate
      :: route
      :- "defPageSize"
      :> PaginationParams ('DefPageSize 3)
      :> Get '[JSON] [Int]

  } deriving Generic

apiHandlers :: ApiMethods AsServer
apiHandlers = ApiMethods
  { amSimplePaginate = \paginationSpec -> do
      return $ paginate paginationSpec [1..10]

  , amDefPageSizePaginate = \paginationSpec -> do
      return $ paginate paginationSpec [1..10]
  }

-- Swagger
---------------------------------------------------------------------------

-- You can try this with ghci
printPaginationSwagger :: IO ()
printPaginationSwagger =
  writeFile "pagination-test-swagger.json" $
    decodeUtf8 . Aeson.encode $
    toSwagger $ Proxy @(ToServantApi ApiMethods)

-- OpenApi
---------------------------------------------------------------------------

-- You can try this with ghci
printPaginationOpenApi :: IO ()
printPaginationOpenApi =
  writeFile "pagination-test-openapi.json" $
    decodeUtf8 . Aeson.encode $
    toOpenApi $ Proxy @(ToServantApi ApiMethods)

-- Tests
---------------------------------------------------------------------------

spec :: Spec
spec =
  aroundAll (runTestServer apiHandlers) $ do

    describe "Simple pagination" $ do

      it "No specific pagination" $
        \ApiMethods{..} -> do
          res <- amSimplePaginate defPageSize
          res `shouldBe` [1..10]

      it "Set page size" $
        \ApiMethods{..} -> do
          res <- amSimplePaginate (itemsOnPage 2)
          res `shouldBe` [1..2]

      it "Set offset" $
        \ApiMethods{..} -> do
          res <- amSimplePaginate (skipping 5 defPageSize)
          res `shouldBe` [6..10]

      it "Set page size and offset" $
        \ApiMethods{..} -> do
          res <- amSimplePaginate (skipping 5 $ itemsOnPage 3)
          res `shouldBe` [6..8]

    describe "Simple pagination" $ do

      it "No specific pagination" $
        \ApiMethods{..} -> do
          res <- amDefPageSizePaginate defPageSize
          res `shouldBe` [1..3]

      it "Set page size" $
        \ApiMethods{..} -> do
          res <- amDefPageSizePaginate (itemsOnPage 5)
          res `shouldBe` [1..5]

      it "Set offset" $
        \ApiMethods{..} -> do
          res <- amDefPageSizePaginate (skipping 5 defPageSize)
          res `shouldBe` [6..8]

      it "Set page size and offset" $
        \ApiMethods{..} -> do
          res <- amDefPageSizePaginate (skipping 5 $ itemsOnPage 1)
          res `shouldBe` [6]