json-api-lib-0.1.1.1: test/Network/JSONApi/ResourceSpec.hs
module Network.JSONApi.ResourceSpec where
import qualified Data.Aeson as AE
import qualified Data.ByteString.Lazy.Char8 as BS
import Data.Maybe (isJust, fromJust)
import Data.Text (Text, pack)
import GHC.Generics (Generic)
import Network.JSONApi
import TestHelpers (prettyEncode)
import Test.Hspec
main :: IO ()
main = hspec spec
spec :: Spec
spec = do
describe "JSON serialization" $
it "can be encoded and decoded from JSON" $ do
let encodedJson = BS.unpack . prettyEncode $ toResource testObject
let decodedJson = AE.decode (BS.pack encodedJson) :: Maybe (Resource TestObject)
isJust decodedJson `shouldBe` True
describe "Self links" $
it "can be constructed for a single high level resource" $ do
let links = showLink testObject
links `shouldBe` mkLinks [ ("self", "/TestObject/1") ]
describe "Index links" $ do
it "should always start at page 0" $ do
let links = indexLinks "/TestObject" $ Pagination (PageSize 10) (PageNum 1) (ResourceCount 20)
links `shouldBe` mkLinks [
("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")
, ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")
, ("next","/TestObject?page%5Bnumber%5D=2&page%5Bsize%5D=10")
, ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")
, ("self","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")]
it "should never have a negative prev page" $ do
let links = indexLinks "/TestObject" $ Pagination (PageSize 10) (PageNum 0) (ResourceCount 20)
links `shouldBe` mkLinks [
("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")
, ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")
, ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")
, ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")
, ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")]
it "should handle a page size of 0" $ do
let links = indexLinks "/TestObject" $ Pagination (PageSize 0) (PageNum 0) (ResourceCount 2)
links `shouldBe` mkLinks [
("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")
, ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")
, ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")
, ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")
, ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")]
it "should handle a negative page num" $ do
let links = indexLinks "/TestObject" $ Pagination (PageSize 0) (PageNum $ -1) (ResourceCount 2)
links `shouldBe` mkLinks [
("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")
, ("last","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")
, ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")
, ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")
, ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")]
it "should handle a negative resource count" $ do
let links = indexLinks "/TestObject" $ Pagination (PageSize 1) (PageNum 0) (ResourceCount $ -1)
links `shouldBe` mkLinks [
("first","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")
, ("last","/TestObject?page%5Bnumber%5D=-1&page%5Bsize%5D=1")
, ("next","/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=1")
, ("prev","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")
, ("self","/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=1")]
it "should handle nested resource paths" $ do
let links = indexLinks "/ParentObject/1/TestObject" $ Pagination (PageSize 10) (PageNum 1) (ResourceCount 20)
links `shouldBe` mkLinks [
("first","/ParentObject/1/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")
, ("last","/ParentObject/1/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")
, ("next","/ParentObject/1/TestObject?page%5Bnumber%5D=2&page%5Bsize%5D=10")
, ("prev","/ParentObject/1/TestObject?page%5Bnumber%5D=0&page%5Bsize%5D=10")
, ("self","/ParentObject/1/TestObject?page%5Bnumber%5D=1&page%5Bsize%5D=10")]
data TestObject = TestObject
{ myId :: Int
, myName :: Text
, myAge :: Int
, myFavoriteFood :: Text
} deriving (Show, Generic)
instance AE.ToJSON TestObject
instance AE.FromJSON TestObject
instance ResourcefulEntity TestObject where
resourceIdentifier = pack . show . myId
resourceType _ = "TestObject"
resourceLinks _ = Just myResourceLinks
resourceMetaData _ = Just myResourceMetaData
resourceRelationships _ = Nothing
relationship :: Relationship
relationship =
fromJust $ mkRelationship
(Just $ Identifier "42" "FriendOfTestObject" Nothing)
(Just myResourceLinks)
otherRelationship :: Relationship
otherRelationship =
fromJust $ mkRelationship
(Just $ Identifier "49" "CousinOfTestObject" Nothing)
(Just myResourceLinks)
myResourceLinks :: Links
myResourceLinks =
mkLinks [ ("self", "/me")
, ("related", "/tacos/4")
]
myResourceMetaData :: Meta
myResourceMetaData = mkMeta (Pagination (PageSize 1) (PageNum 1) (ResourceCount 14))
testObject :: TestObject
testObject = TestObject 1 "Fred Armisen" 49 "Pizza"