{-# LANGUAGE BlockArguments #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedStrings #-} module AgentTests.SQLite where import Control.Monad.Except import qualified Database.SQLite.Simple as DB import Simplex.Messaging.Agent.Store import Simplex.Messaging.Agent.Store.SQLite import Simplex.Messaging.Agent.Transmission import Test.Hspec import UnliftIO.Directory testDB :: String testDB = "smp-agent.test.db" withStore :: SpecWith SQLiteStore -> Spec withStore = before (newSQLiteStore testDB) . after (\store -> DB.close (conn store) >> removeFile testDB) returnsResult :: (Eq a, Eq e, Show a, Show e) => ExceptT e IO a -> a -> Expectation action `returnsResult` r = runExceptT action `shouldReturn` Right r throwsError :: (Eq a, Eq e, Show a, Show e) => ExceptT e IO a -> e -> Expectation action `throwsError` e = runExceptT action `shouldReturn` Left e storeTests :: Spec storeTests = withStore do describe "store methods" do describe "createRcvConn" testCreateRcvConn describe "createSndConn" testCreateSndConn describe "addSndQueue" testAddSndQueue describe "addRcvQueue" testAddRcvQueue describe "deleteConnReceive" do describe "Receive connection" testDeleteConnReceive describe "Send connection" testDeleteConnSend -- describe "deleteConnDuplex" testDeleteConnDuplex testCreateRcvConn :: SpecWith SQLiteStore testCreateRcvConn = do it "should create receive connection and add send queue" $ \store -> do let rcvQueue = ReceiveQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), rcvId = "1234", rcvPrivateKey = "abcd", sndId = Just "2345", sndKey = Nothing, decryptKey = "dcba", verifyKey = Nothing, status = New, ackMode = AckMode On } createRcvConn store "conn1" rcvQueue `returnsResult` () getConn store "conn1" `returnsResult` SomeConn SCReceive (ReceiveConnection "conn1" rcvQueue) let sndQueue = SendQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), sndId = "3456", sndPrivateKey = "abcd", encryptKey = "dcba", signKey = "edcb", status = New, ackMode = AckMode On } addSndQueue store "conn1" sndQueue `returnsResult` () getConn store "conn1" `returnsResult` SomeConn SCDuplex (DuplexConnection "conn1" rcvQueue sndQueue) testCreateSndConn :: SpecWith SQLiteStore testCreateSndConn = do it "should create send connection and add receive queue" $ \store -> do let sndQueue = SendQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), sndId = "1234", sndPrivateKey = "abcd", encryptKey = "dcba", signKey = "edcb", status = New, ackMode = AckMode On } createSndConn store "conn1" sndQueue `returnsResult` () getConn store "conn1" `returnsResult` SomeConn SCSend (SendConnection "conn1" sndQueue) let rcvQueue = ReceiveQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), rcvId = "2345", rcvPrivateKey = "abcd", sndId = Just "3456", sndKey = Nothing, decryptKey = "dcba", verifyKey = Nothing, status = New, ackMode = AckMode On } addRcvQueue store "conn1" rcvQueue `returnsResult` () getConn store "conn1" `returnsResult` SomeConn SCDuplex (DuplexConnection "conn1" rcvQueue sndQueue) testAddSndQueue :: SpecWith SQLiteStore testAddSndQueue = do it "should return error on attempts to add send queue to SendConnection or DuplexConnection" $ \store -> do let sndQueue = SendQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), sndId = "1234", sndPrivateKey = "abcd", encryptKey = "dcba", signKey = "edcb", status = New, ackMode = AckMode On } createSndConn store "conn1" sndQueue `returnsResult` () let anotherSndQueue = SendQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), sndId = "2345", sndPrivateKey = "abcd", encryptKey = "dcba", signKey = "edcb", status = New, ackMode = AckMode On } addSndQueue store "conn1" anotherSndQueue `throwsError` SEBadConnType CSend let rcvQueue = ReceiveQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), rcvId = "3456", rcvPrivateKey = "abcd", sndId = Just "4567", sndKey = Nothing, decryptKey = "dcba", verifyKey = Nothing, status = New, ackMode = AckMode On } addRcvQueue store "conn1" rcvQueue `returnsResult` () addSndQueue store "conn1" anotherSndQueue `throwsError` SEBadConnType CDuplex testAddRcvQueue :: SpecWith SQLiteStore testAddRcvQueue = do it "should return error on attempts to add receive queue to ReceiveConnection or DuplexConnection" $ \store -> do let rcvQueue = ReceiveQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), rcvId = "1234", rcvPrivateKey = "abcd", sndId = Just "2345", sndKey = Nothing, decryptKey = "dcba", verifyKey = Nothing, status = New, ackMode = AckMode On } createRcvConn store "conn1" rcvQueue `returnsResult` () let anotherRcvQueue = ReceiveQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), rcvId = "3456", rcvPrivateKey = "abcd", sndId = Just "4567", sndKey = Nothing, decryptKey = "dcba", verifyKey = Nothing, status = New, ackMode = AckMode On } addRcvQueue store "conn1" anotherRcvQueue `throwsError` SEBadConnType CReceive let sndQueue = SendQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), sndId = "5678", sndPrivateKey = "abcd", encryptKey = "dcba", signKey = "edcb", status = New, ackMode = AckMode On } addSndQueue store "conn1" sndQueue `returnsResult` () addRcvQueue store "conn1" anotherRcvQueue `throwsError` SEBadConnType CDuplex testDeleteConnReceive :: SpecWith SQLiteStore testDeleteConnReceive = do it "should create receive connection and delete it" $ \store -> do let rcvQueue = ReceiveQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), rcvId = "2345", rcvPrivateKey = "abcd", sndId = Just "3456", sndKey = Nothing, decryptKey = "dcba", verifyKey = Nothing, status = New, ackMode = AckMode On } createRcvConn store "conn1" rcvQueue `returnsResult` () getConn store "conn1" `returnsResult` SomeConn SCReceive (ReceiveConnection "conn1" rcvQueue) deleteConn store "conn1" `returnsResult` () getConn store "conn1" `throwsError` SEInternal testDeleteConnSend :: SpecWith SQLiteStore testDeleteConnSend = do it "should create send connection and delete it" $ \store -> do let sndQueue = SendQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), sndId = "2345", sndPrivateKey = "abcd", encryptKey = "dcba", signKey = "edcb", status = New, ackMode = AckMode On } createSndConn store "conn1" sndQueue `returnsResult` () getConn store "conn1" `returnsResult` SomeConn SCSend (SendConnection "conn1" sndQueue) deleteConn store "conn1" `returnsResult` () getConn store "conn1" `throwsError` SEInternal testDeleteConnDuplex :: SpecWith SQLiteStore testDeleteConnDuplex = do it "should create duplex connection and delete it" $ \store -> do let rcvQueue = ReceiveQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), rcvId = "1234", rcvPrivateKey = "abcd", sndId = Just "2345", sndKey = Nothing, decryptKey = "dcba", verifyKey = Nothing, status = New, ackMode = AckMode On } createRcvConn store "conn1" rcvQueue `returnsResult` () let sndQueue = SendQueue { server = SMPServer "smp.simplex.im" (Just "5223") (Just "1234"), sndId = "4567", sndPrivateKey = "abcd", encryptKey = "dcba", signKey = "edcb", status = New, ackMode = AckMode On } addSndQueue store "conn1" sndQueue `returnsResult` () getConn store "conn1" `returnsResult` SomeConn SCDuplex (DuplexConnection "conn1" rcvQueue sndQueue) deleteConn store "conn1" `returnsResult` () getConn store "conn1" `throwsError` SEInternal