{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module MessageSpec where
import Test.Hspec
import Ssb.Types.Message
import Ssb.Types.Key
import Ssb.Types.Link
import Data.Aeson
import Data.ByteString.Lazy
import Data.Maybe
import Prelude hiding (sequence)
spec :: Spec
spec = do
messageSpec
postSpec
aboutSpec
contactSpec
voteSpec
privateContentSpec
pubSpec
originalMessage :: ByteString
originalMessage = "\
\{\
\ \"previous\": \"%3AWRZYdDHKOmLOWvzHbwJFjx9g8hOQH/NXZkwciA63Y=.sha256\",\
\ \"author\": \"@EMovhfIrFk4NihAKnRNhrfRaqIhBv1Wj8pTxJNgvCCY=.ed25519\",\
\ \"sequence\": 184,\
\ \"timestamp\": 1449954503740,\
\ \"hash\": \"sha256\",\
\ \"content\": {\
\ \"type\": \"post\",\
\ \"text\": \"@johnny use https://github.com/ssbc/ssb-msgs and https://github.com/ssbc/ssb-ref is probably useful too.\",\
\ \"root\": \"%rf1JvoFg1pHE6TkuuMxsjBNevFck7LQvXGhkLMNlaYs=.sha256\",\
\ \"branch\": \"%G37a4PUTbysiETQazyYATwLkfn/ZzigmIheAx905MLU=.sha256\",\
\ \"mentions\": [\
\ {\
\ \"link\": \"@dnr1swLSAgf36g+FzGjNLgmytj2IIyDaYeKZ7F5GdzY=.ed25519\",\
\ \"name\": \"johnny\"\
\ }\
\ ]\
\ },\
\ \"signature\": \"28GiO52GFjJnrwpKo359FamEes7JB9gTiiZaidKLL1C1NRueqGq2IAYQ1V+T2AnBgUJLRZUIyNtLTlBcx4RGAA==.sig.ed25519\"\
\}"
messageSpec :: Spec
messageSpec = describe "message" $ do
it "extracts message content" $ do
let (Just message) = (decode originalMessage) :: Maybe (Message AnyContent)
previous message `shouldBe` Just "%3AWRZYdDHKOmLOWvzHbwJFjx9g8hOQH/NXZkwciA63Y=.sha256"
author message `shouldBe` fromJust (FeedLink <$> parseEd25519PublicKey "EMovhfIrFk4NihAKnRNhrfRaqIhBv1Wj8pTxJNgvCCY=")
sequence message `shouldBe` 184
timestamp message `shouldBe` 1449954503740
hash message `shouldBe` "sha256"
signature message `shouldBe` "28GiO52GFjJnrwpKo359FamEes7JB9gTiiZaidKLL1C1NRueqGq2IAYQ1V+T2AnBgUJLRZUIyNtLTlBcx4RGAA==.sig.ed25519"
postSpec :: Spec
postSpec = describe "post" $ do
it "extracts message post" $ do
let (Just message) = (decode originalMessage) :: Maybe (Message Post)
content message `shouldBe` Post
{ text = "@johnny use https://github.com/ssbc/ssb-msgs and https://github.com/ssbc/ssb-ref is probably useful too."
, channel = Nothing
, root = Just "%rf1JvoFg1pHE6TkuuMxsjBNevFck7LQvXGhkLMNlaYs=.sha256"
, branch = Just "%G37a4PUTbysiETQazyYATwLkfn/ZzigmIheAx905MLU=.sha256"
, recps = Nothing
, mentions = Just
[ Mention { mentionLink = "@dnr1swLSAgf36g+FzGjNLgmytj2IIyDaYeKZ7F5GdzY=.ed25519" }
]
}
it "does not parse content that is not a post" $ do
(decode originalAbout :: Maybe (Message Post)) `shouldBe` Nothing
originalAbout :: ByteString
originalAbout = "\
\{\
\ \"previous\": \"%6+FS+LB8nDkgHZKanIB6kK5AYBK2SZYH55q5zv/5XIQ=.sha256\",\
\ \"author\": \"@4RUNgFpvI4ZHH6mPPC9GLzsdv33Cs2JGMMcs8rJSMuU=.ed25519\",\
\ \"sequence\": 5,\
\ \"timestamp\": 1464267463411,\
\ \"hash\": \"sha256\",\
\ \"content\": {\
\ \"type\": \"about\",\
\ \"about\": \"@4RUNgFpvI4ZHH6mPPC9GLzsdv33Cs2JGMMcs8rJSMuU=.ed25519\",\
\ \"image\": {\
\ \"link\": \"&Ro1xCJNDIwwKul2SLSU1e4hrwekPcBI6OrBFN0JWnQM=.sha256\",\
\ \"size\": 502712,\
\ \"type\": \"image/png\",\
\ \"width\": 512,\
\ \"height\": 512\
\ }\
\ },\
\ \"signature\": \"mPC156lndHN2oES/UE0GPK/Z8QgFLG8B/bba2TycXzPZZ7IShQhmFiasE0r0ZBTfRmU9KyuVdfwVYogkY2IACA==.sig.ed25519\"\
\}"
aboutSpec :: Spec
aboutSpec = describe "about" $ do
it "extracts message about" $ do
let Just message = (decode originalAbout) :: Maybe (Message About)
about (content message) `shouldBe` "@4RUNgFpvI4ZHH6mPPC9GLzsdv33Cs2JGMMcs8rJSMuU=.ed25519"
name (content message) `shouldBe` Nothing
fmap aboutImageLink (image (content message)) `shouldBe`
Just "&Ro1xCJNDIwwKul2SLSU1e4hrwekPcBI6OrBFN0JWnQM=.sha256"
fmap aboutImageSize (image (content message)) `shouldBe`
Just (Just 502712)
fmap aboutImageType (image (content message)) `shouldBe`
Just (Just "image/png")
fmap aboutImageWidth (image (content message)) `shouldBe`
Just (Just 512)
fmap aboutImageHeight (image (content message)) `shouldBe`
Just (Just 512)
originalContact :: ByteString
originalContact = "\
\{\
\ \"previous\": \"%kLJuVKntE9LsPeTSyiVSNnb2vkiGXzBUMeDPoGr6BBw=.sha256\",\
\ \"author\": \"@ye+QM09iPcDJD6YvQYjoQc7sLF/IFhmNbEqgdzQo3lQ=.ed25519\",\
\ \"sequence\": 5442,\
\ \"timestamp\": 1488618790507,\
\ \"hash\": \"sha256\",\
\ \"content\": {\
\ \"type\": \"contact\",\
\ \"contact\": \"@o91tsjBgL0l0zs475aRWYSAXFxvirZS7VrXmirY/msI=.ed25519\",\
\ \"following\": true\
\ },\
\ \"signature\": \"zknuPbUwMeBaDZzZ9iBETOPbZ7SYqetd3RVkq2mYSyr4QI/7uwho3GnerIF3fLcvW3MgRM5SvFvSTnpxxQFoCg==.sig.ed25519\"\
\}"
contactSpec :: Spec
contactSpec = describe "contact" $ do
it "extracts message contact" $ do
let Just message = (decode originalContact) :: Maybe (Message Contact)
content message `shouldBe` Contact
{ contact = fromJust $ FeedLink <$> parseEd25519PublicKey "o91tsjBgL0l0zs475aRWYSAXFxvirZS7VrXmirY/msI="
, following = True
, blocking = False
}
originalVote :: ByteString
originalVote = "\
\{\
\ \"previous\": \"%jiyo59Or2Rrm+05QJIZ/fLfCeBhiaJ+tjJgW/USgtYs=.sha256\",\
\ \"author\": \"@/02iw6SFEPIHl8nMkYSwcCgRWxiG6VP547Wcp1NW8Bo=.ed25519\",\
\ \"sequence\": 3304,\
\ \"timestamp\": 1459235596255,\
\ \"hash\": \"sha256\",\
\ \"content\": {\
\ \"type\": \"vote\",\
\ \"vote\": {\
\ \"link\": \"%lu9JsdUl4astKykyaVFdkLb7//tS0K08BMs6dT+fErA=.sha256\",\
\ \"value\": 1\
\ }\
\ },\
\ \"signature\": \"iw/wREQJ4UEecnfuFNIiZt9kMZXkQc8SP2jmhVbUvPj9Eo50D2yJKfza+Qf/tYwOuFaE9et4pbucPD/4OMlbAg==.sig.ed25519\"\
\}"
voteSpec :: Spec
voteSpec = describe "vote" $ do
it "extracts message vote" $ do
let Just message = (decode originalVote) :: Maybe (Message Vote)
content message `shouldBe` Vote
{ voteLink = "%lu9JsdUl4astKykyaVFdkLb7//tS0K08BMs6dT+fErA=.sha256"
, voteValue = 1
, voteExpression = Nothing
}
-- Not a real private message content, because the test couldn't decrypt it anyway.
originalPrivateContent :: ByteString
originalPrivateContent = "\
\{\
\ \"previous\": \"%RFY6DRn3syOm7GodwpNTePx0I4ZWyZMVsmZ4V1QqiDQ=.sha256\",\
\ \"author\": \"@9nTgtYmvW4HID6ayt6Icwc8WZxdifx5SlSKKIX/X/1g=.ed25519\",\
\ \"sequence\": 245,\
\ \"timestamp\": 1481349557377,\
\ \"hash\": \"sha256\",\
\ \"content\": \"dummy\",\
\ \"signature\": \"2urg9PG4+esti1DIf4DnFfsUXXnOzwXHv+QnflKQQ0145pNw+SIXeYkhNhzqdFm2fz7wzWb7YVlFMPIL11EaBQ==.sig.ed25519\"\
\}"
privateContentSpec :: Spec
privateContentSpec = describe "private" $ do
it "extracts message private" $ do
let Just message = (decode originalPrivateContent) :: Maybe (Message PrivateContent)
author message `shouldBe` fromJust (FeedLink <$> parseEd25519PublicKey "9nTgtYmvW4HID6ayt6Icwc8WZxdifx5SlSKKIX/X/1g=")
content message `shouldBe` PrivateContent "dummy"
originalPub :: ByteString
originalPub = "\
\{\
\ \"previous\": \"%qYdhzyTbQwrdTOpKVvFS0nFCOvK5SekDhxLjHs6i1jo=.sha256\",\
\ \"author\": \"@26RTWG0+zR1DLO43p4VjB/UzTNKgQ+TNvLey37E/YdI=.ed25519\",\
\ \"sequence\": 3,\
\ \"timestamp\": 1497928539321,\
\ \"hash\": \"sha256\",\
\ \"content\": {\
\ \"type\": \"pub\",\
\ \"address\": {\
\ \"host\": \"ssb.hypersignal.xyz\",\
\ \"port\": 8008,\
\ \"key\": \"@XRg7pXoQqsWDDk4dmgvSWHUqzwS6BmqMo4IdbMKPjWA=.ed25519\"\
\ }\
\ },\
\ \"signature\": \"nWBpjqbnw4sGkaD+0OpxzmTo5VeGOnRcj2hxWjATlO9e7F9eK2yJACOaa5hzGT1E967uFhwmvwUA6FMq3Z0MBQ==.sig.ed25519\"\
\}"
pubSpec :: Spec
pubSpec = describe "pub" $ do
it "extracts message pub" $ do
let Just message = (decode originalPub) :: Maybe (Message Pub)
pubHost (content message) `shouldBe` "ssb.hypersignal.xyz"
pubPort (content message) `shouldBe` 8008
Just (pubKey (content message)) `shouldBe`
parseEd25519PublicKey "XRg7pXoQqsWDDk4dmgvSWHUqzwS6BmqMo4IdbMKPjWA="