hurriyet-0.2.0.0: tests/Spec.hs
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
--------------------------------------------------------------------------------
import Test.Hspec
import Data.String
import Data.Aeson
import Data.Text.Lazy.Encoding (encodeUtf8)
import Data.Text.Lazy (Text, pack)
import Data.Either (isLeft)
import Data.Monoid ((<>))
import Control.Monad (when)
import Data.Proxy (Proxy(..))
import Data.Foldable (forM_)
--------------------------------------------------------------------------------
import qualified Hurriyet as H
import qualified Hurriyet.Services as HS
--------------------------------------------------------------------------------
testApiKey :: IsString s => s
testApiKey = "some_api_key"
testClient :: H.Client
testClient = H.getClient testApiKey
{- Beware: anyone using this function should annotate return
- value, since we are doing json decoding.
-}
testDecoding :: forall proxy a. (Show a, FromJSON a) => proxy a -> Text -> IO ()
testDecoding _ str = do
let result = eitherDecode (encodeUtf8 str) :: Either String a
when (isLeft result) $
expectationFailure $ "Could not decode service: " <> fromLeft result
return ()
fromLeft :: Show b => Either a b -> a
fromLeft (Right x) = error $ "Should not have got a right value: " ++ show x
fromLeft (Left x) = x
data Operation = List H.Resource
| Show H.Resource
stubbedResponseFilename :: Operation -> String
stubbedResponseFilename (List resource) = show resource <> "_list_response"
stubbedResponseFilename (Show resource) = show resource <> "_show_response"
stubbedResponse :: Operation -> IO Text
stubbedResponse op =
let
filepath = "tests/static/" <> stubbedResponseFilename op <> ".json"
in
pack <$> readFile filepath
serviceTestMapping ::
[
( String -- Name of the resource test. Will be used as description
, ( (H.Operation, String) -- Endpoint check for list operation
, (H.Operation, String) -- Endpoint check for show operation
, (Operation, Text -> IO ()) -- List operation and its response decoder
, (Operation, Text -> IO ()) -- Show operation and its response decoder
)
)
]
serviceTestMapping =
[ ("article", ( (H.List H.ArticleResource, "articles")
, (H.Show H.ArticleResource "3", "articles/3")
, (List H.ArticleResource, testDecoding (Proxy :: Proxy [HS.Article]))
, (Show H.ArticleResource, testDecoding (Proxy :: Proxy HS.Article))
)
)
, ("column", ( (H.List H.ColumnResource, "columns")
, (H.Show H.ColumnResource "3", "columns/3")
, (List H.ColumnResource, testDecoding (Proxy :: Proxy [HS.Column]))
, (Show H.ColumnResource, testDecoding (Proxy :: Proxy HS.Column))
)
)
, ("news_photo_gallery", ( (H.List H.NewsPhotoGalleryResource, "newsphotogalleries")
, (H.Show H.NewsPhotoGalleryResource "3", "newsphotogalleries/3")
, (List H.NewsPhotoGalleryResource, testDecoding (Proxy :: Proxy [HS.NewsPhotoGallery]))
, (Show H.NewsPhotoGalleryResource, testDecoding (Proxy :: Proxy HS.NewsPhotoGallery))
)
)
-- Pages endpoint is inaccessible at the moment of testing
-- , ("page", ( (H.List H.PageResource, "pages")
-- , (H.Show H.PageResource "3", "pages/3")
-- , (List H.PageResource, testDecoding (Proxy :: Proxy [HS.Page]))
-- , (Show H.PageResource, testDecoding (Proxy :: Proxy HS.Page))
-- )
-- )
, ("path", ( (H.List H.PathResource, "paths")
, (H.Show H.PathResource "3", "paths/3")
, (List H.PathResource, testDecoding (Proxy :: Proxy [HS.Path]))
, (Show H.PathResource, testDecoding (Proxy :: Proxy HS.Path))
)
)
, ("writer", ( (H.List H.WriterResource, "writers")
, (H.Show H.WriterResource "3", "writers/3")
, (List H.WriterResource, testDecoding (Proxy :: Proxy [HS.Writer]))
, (Show H.WriterResource, testDecoding (Proxy :: Proxy HS.Writer))
)
)
]
main :: IO ()
main = hspec $ do
describe "client" $ do
it "saves the api key" $
H.apiKey testClient `shouldBe` testApiKey
it "reads" $ do
_ <- H.withClient testClient H.getArticles
return ()
describe "resources" $
forM_ serviceTestMapping $ \resource ->
context (fst resource) $ do
let (listUrl, showUrl, (listOperation, listDecodeTester), (showOperation, showDecodeTester)) = snd resource
context "list" $
it "has the right endpoint" $
H.getUrl (fst listUrl) `shouldBe` H.baseUrl ++ snd listUrl
it "parses response" $
listDecodeTester =<< stubbedResponse listOperation
context "show" $
it "has the right endpoint" $
H.getUrl (fst showUrl) `shouldBe` H.baseUrl ++ snd showUrl
it "parses response" $
showDecodeTester =<< stubbedResponse showOperation