packages feed

plaid-0.1.0.0: test/Plaid/PlaidSpec.hs

module Plaid.PlaidSpec (spec) where

import qualified Control.Error            as ER
import           Data.Api.TestByteStrings
import           Data.ByteString.Char8    (unpack)
import           Data.Common
import           Data.Either              (isRight)
import           Data.Plaid
import qualified Data.Text                as T
import           Data.Time                (fromGregorian)
import           Debug.Trace
import           Test.Hspec

_runTestGetRequest :: PlaidHttp m => Text -> m ByteString
_runTestGetRequest url = executeGet url

runTestPostRequest :: (PlaidHttp m, ToJSON a) => Text -> a -> m ByteString
runTestPostRequest url postBody = executePost url postBody

checkResult :: FromJSON a => ByteString -> Either PlaidError a
checkResult result =
  case result of
    "" -> Left (PlaidError $ T.pack $ "Failed to decode bytestring " ++ (unpack $ toStrict result))
    _  ->
      case eitherDecode' result of
        Left e   -> Left $ PlaidError (T.pack e)
        Right ok -> Right ok

env :: PlaidEnv
env = PlaidEnv "" (ClientId "") (Secret "") Sandbox

publicTokenBody :: Either PlaidError (PlaidBody PublicTokenCreate)
publicTokenBody =
  mkCreatePublicTokenEnv env
    (InstitutionId "ins_3")
    ["transactions"]
    Nothing
    -- (Just $
    --   PlaidOptions
    --   "http://bogicevicsasa.com"
    --   "user_good"
    --   "pass_good"
    -- )
    
spec :: Spec
spec = do
  describe "Create public token" $ do
    it "/public_token/create" $ do
      let result = runTestPlaid $ runTestPostRequest "/public_token/create" publicTokenBody
          testResult = checkResult result :: Either PlaidError PlaidPublicTokenResponse
      isRight testResult `shouldBe` True

  describe "Exchange public token" $ do
    it "/item/public_token/exchange" $ do
      let result = runTestPlaid $ runTestPostRequest "/public_token/create" publicTokenBody
      testResult <- ER.runExceptT $ do
        PlaidPublicTokenResponse {..} <- ER.hoistEither (checkResult result :: Either PlaidError PlaidPublicTokenResponse)
        exchangeBody <- ER.hoistEither (mkExchangePublicTokenEnv env _plaidPublicTokenResponsePublicToken)
        let result' = runTestPlaid $ runTestPostRequest "/item/public_token/exchange" exchangeBody
        ER.hoistEither (checkResult result' :: Either PlaidError PlaidAccessTokenResponse)
      isRight testResult `shouldBe` True

  describe "Auth get" $ do
    it "/auth/get" $ do
      let result = runTestPlaid $ runTestPostRequest "/public_token/create" publicTokenBody
      testResult <- ER.runExceptT $ do
        PlaidPublicTokenResponse {..} <- ER.hoistEither (checkResult result :: Either PlaidError PlaidPublicTokenResponse)
        exchangeBody <- ER.hoistEither (mkExchangePublicTokenEnv env _plaidPublicTokenResponsePublicToken)
        let result' = runTestPlaid $ runTestPostRequest "/item/public_token/exchange" exchangeBody
        PlaidAccessTokenResponse {..} <- ER.hoistEither (checkResult result' :: Either PlaidError PlaidAccessTokenResponse)
        authBody <- ER.hoistEither (mkGetAuthEnv env _plaidAccessTokenResponseAccessToken)
        let authGetResult = runTestPlaid $ runTestPostRequest "/auth/get" authBody
        ER.hoistEither (checkResult authGetResult :: Either PlaidError PlaidAuthGetResponse)
      isRight testResult `shouldBe` True

  describe "Identity get" $ do
    it "/identity/get" $ do
      let result = runTestPlaid $ runTestPostRequest "/public_token/create" publicTokenBody
      testResult <- ER.runExceptT $ do
        PlaidPublicTokenResponse {..} <- ER.hoistEither (checkResult result :: Either PlaidError PlaidPublicTokenResponse)
        exchangeBody <- ER.hoistEither (mkExchangePublicTokenEnv env _plaidPublicTokenResponsePublicToken)
        let result' = runTestPlaid $ runTestPostRequest "/item/public_token/exchange" exchangeBody
        PlaidAccessTokenResponse {..} <- ER.hoistEither (checkResult result' :: Either PlaidError PlaidAccessTokenResponse)
        identityBody <- ER.hoistEither (mkCreateIdentityGetEnv env _plaidAccessTokenResponseAccessToken)
        let identityGetResult = runTestPlaid $ runTestPostRequest "/identity/get" identityBody
        ER.hoistEither (checkResult identityGetResult :: Either PlaidError PlaidIdentityGetResponse)
      isRight testResult `shouldBe` True
  describe "Transactions get" $ do
    it "/transactions/get" $ do
      let result = runTestPlaid $ runTestPostRequest "/public_token/create" publicTokenBody
      testResult <- ER.runExceptT $ do
        PlaidPublicTokenResponse {..} <- ER.hoistEither (checkResult result :: Either PlaidError PlaidPublicTokenResponse)
        exchangeBody <- ER.hoistEither (mkExchangePublicTokenEnv env _plaidPublicTokenResponsePublicToken)
        let result' = runTestPlaid $ runTestPostRequest "/item/public_token/exchange" exchangeBody
        PlaidAccessTokenResponse {..} <- ER.hoistEither (checkResult result' :: Either PlaidError PlaidAccessTokenResponse)
        authBody <- ER.hoistEither (mkGetAuthEnv env _plaidAccessTokenResponseAccessToken)
        let authGetResult = runTestPlaid $ runTestPostRequest "/auth/get" authBody
        PlaidAuthGetResponse {..} <- ER.hoistEither (checkResult authGetResult :: Either PlaidError PlaidAuthGetResponse)
        let startTime = fromGregorian 2018 1 1
        let endTime   = fromGregorian 2019 1 1
        transactionBody <-
          ER.hoistEither (mkCreateTransactionsGetEnv
                           env
                           _plaidAccessTokenResponseAccessToken
                           startTime
                           endTime
                           Nothing
                           Nothing
                         )

        let transactionsGetResult =
              runTestPlaid $ runTestPostRequest "/transactions/get" transactionBody
        ER.hoistEither (checkResult transactionsGetResult :: Either PlaidError PlaidTransactionsGetResponse)
      isRight testResult `shouldBe` True
  describe "Balance json" $ do
    it "should be able to decode Balance" $ do
      let result = eitherDecode' balanceJson :: Either String Balance
      isRight result `shouldBe` True
  describe "Account json" $ do
    it "should be able to decode Account" $ do
      let result = eitherDecode' accountJson :: Either String Account
      isRight result `shouldBe` True
  describe "Account list json" $ do
    it "should be able to decode Account list" $ do
      let result = eitherDecode' accountListJson :: Either String [Account]
      isRight result `shouldBe` True
  describe "PaymentMeta json" $ do
    it "should be able to decode PaymentMeta" $ do
      let result = eitherDecode' accountJson :: Either String PaymentMeta
      isRight result `shouldBe` True
  describe "Item json" $ do
    it "should be able to decode Item" $ do
      let result = eitherDecode' itemJson :: Either String Item
      isRight result `shouldBe` True
  describe "Transaction json" $ do
    it "should be able to decode Transaction" $ do
      let result = eitherDecode' transactionJson :: Either String Transaction
      isRight result `shouldBe` True
  describe "TransactionLocation json" $ do
    it "should be able to decode TransactionLocation" $ do
      let result = eitherDecode' transactionLocationJson :: Either String TransactionLocation
      isRight result `shouldBe` True
  describe "email json" $ do
    it "should be able to decode Email" $ do
      let result = eitherDecode' emailJson :: Either String Email
      isRight result `shouldBe` True
  describe "phone json" $ do
    it "should be able to decode Phone" $ do
      let result = eitherDecode' phoneNumberJson :: Either String PhoneNumber
      isRight result `shouldBe` True
  describe "address json" $ do
    it "should be able to decode Addresses" $ do
      let result = eitherDecode' addressesJson :: Either String Addresses
      isRight result `shouldBe` True
  describe "Accounts json" $ do
    it "should be able to decode Accounts" $ do
      let result = eitherDecode' accountsJson :: Either String Accounts
      isRight result `shouldBe` True
  describe "Owners json" $ do
    it "should be able to decode Owners" $ do
      let result = eitherDecode' ownersJson :: Either String Owners
      isRight result `shouldBe` True