{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE DeriveGeneric #-} module MessageSpec where import Test.Hspec import Ssb.Types.Message import Ssb.Types.Link import Ssb.Types.Key import Ssb.Types.Hash import Data.Aeson import Data.ByteString.Lazy (ByteString) 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` MessageLink <$> parseSha256 "3AWRZYdDHKOmLOWvzHbwJFjx9g8hOQH/NXZkwciA63Y=" 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) text (content message) `shouldBe` "@johnny use https://github.com/ssbc/ssb-msgs and https://github.com/ssbc/ssb-ref is probably useful too." channel (content message) `shouldBe` Nothing root (content message) `shouldBe` MessageLink <$> parseSha256 "rf1JvoFg1pHE6TkuuMxsjBNevFck7LQvXGhkLMNlaYs=" branch (content message) `shouldBe` Just (Branch [fromJust $ MessageLink <$> parseSha256 "G37a4PUTbysiETQazyYATwLkfn/ZzigmIheAx905MLU="]) recps (content message) `shouldBe` Nothing map (linkTo . mentionLink) . fromMentions <$> (mentions (content message)) `shouldBe` Just [ "dnr1swLSAgf36g+FzGjNLgmytj2IIyDaYeKZ7F5GdzY=" ] 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\"\ \}" altAbout :: ByteString altAbout = "\ \{\ \ \"previous\": null,\ \ \"author\": \"@t0/CL/qifMsFniGq7fZ0KNjmC5/MLpJpuxPi/fFNvzU=.ed25519\",\ \ \"sequence\": 1,\ \ \"timestamp\": 1491509688475,\ \ \"hash\": \"sha256\",\ \ \"content\": {\ \ \"type\": \"about\",\ \ \"about\": \"@t0/CL/qifMsFniGq7fZ0KNjmC5/MLpJpuxPi/fFNvzU=.ed25519\",\ \ \"image\": \"&+FICZpX7m4zJE99OVgBj/0IPaIH23T9ea8bBDazMsTw=.sha256\",\ \ \"name\": \"jlipps\"\ \ },\ \ \"signature\": \"Qji3DvYtHu5kLs86Cxcor0jNrIC13qGrzqoIrSPCf750WrRKpdbqmFGKOqSiIUVT713i7BSnX7thrc7dXBkKDA==.sig.ed25519\"\ \}" aboutSpec :: Spec aboutSpec = describe "about" $ do it "extracts message about" $ do let Just message = (decode originalAbout) :: Maybe (Message About) linkTo (about (content message)) `shouldBe` "4RUNgFpvI4ZHH6mPPC9GLzsdv33Cs2JGMMcs8rJSMuU=" name (content message) `shouldBe` Nothing fmap aboutImageLink (image (content message)) `shouldBe` BlobLink <$> parseSha256 "Ro1xCJNDIwwKul2SLSU1e4hrwekPcBI6OrBFN0JWnQM=" 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) it "extracts message about with short AboutImage" $ do let Just message = (decode altAbout) :: Maybe (Message About) fmap aboutImageLink (image (content message)) `shouldBe` BlobLink <$> parseSha256 "+FICZpX7m4zJE99OVgBj/0IPaIH23T9ea8bBDazMsTw=" name (content message) `shouldBe` Just "jlipps" 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) voteValue (content message) `shouldBe` 1 voteExpression (content message) `shouldBe` Nothing linkTo (voteLink (content message)) `shouldBe` "lu9JsdUl4astKykyaVFdkLb7//tS0K08BMs6dT+fErA=" -- 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 (unFeedLink (pubKey (content message))) `shouldBe` parseEd25519PublicKey "XRg7pXoQqsWDDk4dmgvSWHUqzwS6BmqMo4IdbMKPjWA="