line-bot-sdk-0.6.0: test/Line/Bot/ClientSpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeApplications #-}
module Line.Bot.ClientSpec (spec) where
import Control.DeepSeq (NFData)
import Control.Monad ((>=>))
import Control.Monad.Free
import Control.Monad.Trans.Reader (runReaderT)
import Data.Aeson (Value)
import Data.Aeson.QQ
import Data.ByteString as B (stripPrefix)
import Data.Foldable (toList)
import Data.Text.Encoding
import Data.Time.Calendar (fromGregorian)
import Line.Bot.Client hiding (runLine)
import Line.Bot.Internal.Endpoints
import Line.Bot.Types
import Network.HTTP.Client (newManager)
import Network.HTTP.Client.TLS (tlsManagerSettings)
import Network.HTTP.Types (hAuthorization)
import Network.Wai as Wai (Request,
requestHeaders)
import Network.Wai.Handler.Warp (Port, withApplication)
import Servant
import Servant.Client.Core
import Servant.Client.Free as F
import Servant.Client.Streaming
import Servant.Server.Experimental.Auth (AuthHandler, AuthServerData,
mkAuthHandler)
import Test.Hspec
import Test.Hspec.Expectations.Contrib
type ChannelAuth = AuthProtect "channel-token"
type instance AuthServerData ChannelAuth = ChannelToken
-- a dummy auth handler that returns the channel access token
authHandler :: AuthHandler Wai.Request ChannelToken
authHandler = mkAuthHandler $ \request ->
case lookup hAuthorization (Wai.requestHeaders request) >>= B.stripPrefix "Bearer " of
Nothing -> throwError $ err401 { errBody = "Bad" }
Just t -> return $ ChannelToken $ decodeUtf8 t
serverContext :: Context '[AuthHandler Wai.Request ChannelToken]
serverContext = authHandler :. EmptyContext
type API = GetProfile' Value
:<|> GetGroupMemberProfile' Value
:<|> GetRoomMemberProfile' Value
getReplyMessageCountF :: LineDate -> Free ClientF MessageCount
getReplyMessageCountF = F.client (Proxy @GetReplyMessageCount)
getPushMessageCountF :: LineDate -> Free ClientF MessageCount
getPushMessageCountF = F.client (Proxy @GetPushMessageCount)
getMulticastMessageCountF :: LineDate -> Free ClientF MessageCount
getMulticastMessageCountF = F.client (Proxy @GetMulticastMessageCount)
testProfile :: Value
testProfile = [aesonQQ|
{
displayName: "LINE taro",
userId: "U4af4980629...",
pictureUrl: "https://obs.line-apps.com/...",
statusMessage: "Hello, LINE!"
}
|]
withPort :: Port -> (ClientEnv -> IO a) -> IO a
withPort port app = do
manager <- newManager tlsManagerSettings
app $ mkClientEnv manager $ BaseUrl Http "localhost" port ""
token :: ChannelToken
token = "fake"
runLine :: NFData a => Line a -> Port -> IO (Either ClientError a)
runLine comp port = withPort port $ \env -> runClientM (runReaderT comp token) env
app :: Application
app = serveWithContext (Proxy :: Proxy API) serverContext $
(\_ -> return testProfile)
:<|> (\_ _ -> return testProfile)
:<|> (\_ _ -> return testProfile)
spec :: Spec
spec = describe "Line client" $ do
it "should return user profile" $
withApplication (pure app) $
runLine (getProfile "1") >=> (`shouldSatisfy` isRight)
it "should return group user profile" $
withApplication (pure app) $
runLine (getGroupMemberProfile "1" "1") >=> (`shouldSatisfy` isRight)
it "should return room user profile" $
withApplication (pure app) $
runLine (getRoomMemberProfile "1" "1") >=> (`shouldSatisfy` isRight)
it "should send `date` query param for push message count" $ do
let Free (RunRequest Request{..} _) = getPushMessageCountF date
toList requestQueryString `shouldBe` [("date", Just "20190407")]
it "should send `date` query param for reply message count" $ do
let Free (RunRequest Request{..} _) = getReplyMessageCountF date
toList requestQueryString `shouldBe` [("date", Just "20190407")]
it "should send `date` query param for multicast message count" $ do
let Free (RunRequest Request{..} _) = getMulticastMessageCountF date
toList requestQueryString `shouldBe` [("date", Just "20190407")]
where
date = LineDate $ fromGregorian 2019 4 7