packages feed

telegram-api-0.7.1.0: test/Spec.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}

module Main (main) where

import           Data.Char                    (isDigit)
import           Data.Maybe                   (fromMaybe)
import           Data.Monoid                  ((<>))
import           Data.Text                    (Text)
import qualified Data.Text                    as T
import qualified JsonSpec
import qualified MainSpec
import           Options.Applicative
import qualified PaymentsSpec
import qualified StickersSpec
import           System.Environment           (lookupEnv, withArgs)
import           Test.Hspec
import qualified Text.PrettyPrint.ANSI.Leijen as PP
import qualified UpdatesSpec
import           Web.Telegram.API.Bot

-- | Command line options for test suite
data Options = Options
  {
    opt_integration :: Bool   -- ^ Run integration tests
  , opt_chatId      :: Maybe String   -- ^ Id of a chat or of your bot
  , opt_botName     :: Maybe String   -- ^ Bot name
  , opt_hSpecOpts   :: Maybe [String] -- ^ Command line options to pass to hSpec
  }

options :: Parser Options
options = Options
    <$> switch
        ( long "integration"
       <> help "Run integration tests" )
    <*> optional ( strOption
         ( long "chatid"
        <> short 'c'
        <> metavar "CHAT_ID"
        <> help "Chat Id" ))
    <*> optional ( strOption
         ( long "botname"
        <> short 'b'
        <> metavar "BOT_NAME"
        <> help "Bot Name" ))
    <*> optional ( some ( argument str
         ( metavar "HSPEC_ARGS"
        <> help "Hspec arguments")))

main :: IO ()
main = do
    tokenEnv <- lookupEnv "BOT_TOKEN"
    paymentTokenEnv <- lookupEnv "PAYMENT_TOKEN"
    Options{..} <- execParser opts
    let integration = opt_integration
        token = (\x -> Token ("bot" <> T.pack x)) <$> tokenEnv
        paymentToken = T.pack <$> paymentTokenEnv
        chatId = readChatId <$> opt_chatId
        botName = T.pack <$> opt_botName
        hspecArgs = fromMaybe [] opt_hSpecOpts
    withArgs hspecArgs $ hspec (runSpec' integration token chatId botName paymentToken)
    where opts = info (helper <*> options)
            ( fullDesc
           <> progDescDoc description)
runSpec' :: Bool -> Maybe Token -> Maybe ChatId -> Maybe Text -> Maybe Text -> SpecWith ()
runSpec' integration token chatId botName paymentToken = do
    describe "Unit tests" $
      describe "Json tests" JsonSpec.spec
    if integration then runIntegrationSpec token chatId botName paymentToken
    else describe "Integration tests" $ it "skipping..." $
        pendingWith "Use --integration switch to run integration tests"


runIntegrationSpec :: Maybe Token -> Maybe ChatId -> Maybe Text -> Maybe Text -> SpecWith ()
runIntegrationSpec (Just token) (Just chatId) (Just botName) (Just paymentToken) = do
        describe "Main integration tests" $ MainSpec.spec token chatId botName
        describe "Payments integration tests" $ PaymentsSpec.spec token chatId botName paymentToken
        describe "Updates API spec" $ UpdatesSpec.spec token botName
        describe "Stickers API spec" $ StickersSpec.spec token chatId botName
            --describe "Inline integration tests" $ InlineSpec.spec token chatId botName
runIntegrationSpec _ _ _ _ = describe "Integration tests" $
        fail "Missing required arguments for integration tests. Run stack test --test-arguments \"--help\" for more info"

description ::  Maybe PP.Doc
description = Just $
           (PP.text "Run the haskell-telegram-api tests")
    PP.<$> ((PP.text "Running with stack: ") PP.<> (PP.text "stack test --test-arguments=\"--integration -c 1235122 -b MyTeleBot -- -m send\""))
    PP.<$> ((PP.red . PP.text $ "WARNING: ") PP.<> (PP.text "the HSPEC_ARGS are optional but if present MUST be at the end and seperated from the other options with a -- "))

readChatId :: String -> ChatId
readChatId s@('@':_) = ChatChannel $ T.pack s
readChatId s         | all isDigit s = ChatId (read s)
readChatId _         = error "ChatId must be either Integer or String in form '@channel'"