DbT.hs
1 module DbT where 2 import Test.Hspec 3 import Prelude as P 4 import Nostr.Filter 5 import Nostr.Db.Schema 6 import Nostr.Db.Fetch 7 import Nostr.Db.Insert 8 import Nostr.Db.Create 9 import Golden 10 import Database.SQLite.Simple 11 import Control.Monad as M 12 import Control.Concurrent 13 import Control.Monad.IO.Class 14 import Nostr.Event 15 import Nostr.Keys 16 import Data.Time.Clock.POSIX 17 import Data.Time.Clock 18 import Data.Time.LocalTime 19 import Data.Time 20 import Data.Maybe 21 import Database.Beam 22 import Database.Beam.Sqlite 23 import Database.Beam.Migrate 24 import Database.Beam.Backend.SQL 25 import Database.Beam.Sqlite.Syntax 26 import Data.Text as T 27 28 getDbTest = do 29 kp <- genKeyPair 30 p1 <- exportPub kp 31 sec :: Integer <- round <$> getPOSIXTime 32 let keyless = Content 11111 33 [AZTag 't' "butterflies"] 34 "first" 35 sec 36 37 let keyless2 = Content 11111 38 [AZTag 't' "butterflies"] 39 "second" 40 sec 41 42 let keyless3 = Content 33333 43 [AZTag 'd' "butts"] 44 "first" 45 sec 46 47 let keyless4 = Content 33333 48 [AZTag 'd' "butts"] 49 "second" 50 sec 51 52 let keyless5 = Content 22222 53 [] 54 "first" 55 sec 56 57 let keyless6 = Content 1 [] "oops" sec 58 59 let keyless7 = Content 0 [] "" sec 60 61 let keyless8 = Content 0 [] "u" sec 62 63 64 mE :: Event <- signE kp keyless 65 mE2 <- signE kp keyless2 66 mE3 <- signE kp keyless3 67 mE4 <- signE kp keyless4 68 mE5 <- signE kp keyless5 69 mE6 <- signE kp keyless6 70 mE7 <- signE kp keyless7 71 mE8 <- signE kp keyless8 72 o <- open "./test.sqlite" 73 f <- createDb o 74 insertEv o wev 75 insertEv o mE 76 insertEv o mE2 77 insertEv o mE3 78 insertEv o mE4 79 insertEv o mE5 80 insertEv o mE6 81 insertEv o mE7 82 insertEv o mE8 83 84 return $ describe "relay" do 85 it "replacable" $ do 86 f' <- content . con . P.head 87 <$> fetch o emptyF{kindsF=(Just . Kinds $ [11111])} 88 shouldBe "second" f' 89 it "replacable 0" $ do 90 f' <- content . con . P.head 91 <$> fetch o emptyF{kindsF=(Just . Kinds $ [0]), authorsF=(Just . Authors $ [wq p1])} 92 shouldBe "u" f' 93 94 it "parameterized replaceable" $ do 95 f' <- content . con . P.head <$> fetch o emptyF{kindsF=(Just . Kinds $ [33333])} 96 shouldBe "second" f' 97 98 99 100 it "expires shortly?" $ do 101 Just (Just f') <- runBeamSqlite o $ runSelectReturningOne $ select $ do 102 ee <- all_ (_events spec') 103 guard_ (_eid ee ==. val_ (wq $ eid mE5)) 104 pure (_expires ee) 105 zo <- getCurrentTimeZone 106 ti <- getCurrentTime 107 let ow = zonedTimeToLocalTime $ utcToZonedTime zo ti 108 let expiresIn = diffLocalTime f' ow 109 shouldBe True (fifteen > expiresIn) 110 111 it "use limit" $ do 112 f' <- P.length <$> fetch o fl 113 shouldBe 2 f' 114 void $ flip M.mapM ff \(fi, ti) -> do 115 it ("got some" <> ti) $ do 116 ex <- fetch o fi 117 shouldBe (True) ((>0) . P.length $ ex) 118 it "got expected count" $ do 119 ex <- fetch o fi 120 c : _ <- countFx o fi 121 fromIntegral c `shouldBe` P.length ex 122 123 it "deletes by etag" $ do 124 mmE7 <- signE kp $ Content 5 [ETag (eid mE6) Nothing Nothing] "oooops" sec 125 insertEv o mmE7 126 aFx <- P.length 127 <$> fetch o emptyF{ idsF=Just (Ids [T.take 19 . T.drop 1 . wq $ eid mE6]) } 128 shouldBe 0 aFx 129 it "deletes by atag" $ do 130 mmE8 <- signE kp $ Content 5 [ATag (ARef 33333 p1 (Just "butts")) Nothing] "oooops" sec 131 insertEv o mmE8 132 133 aFx <- P.length 134 <$> fetch o emptyF{aztagF = [AZTag 'd' "butts" ] } 135 aFx `shouldBe` 0 136 137 138 139 140 fl = emptyF {kindsF = Just (Kinds [0,1]), limitF = Just (Limit 2)} 141 142 ff = P.zip 143 [ emptyF {idsF = Just . Ids $ [ 144 "4376c65d2f232afbe9b882a35baa4f6fe8667c4e684749af565f981833ed6a65" ]} 145 , emptyF {idsF = Just . Ids $ ["0"]} 146 , emptyF {authorsF = Just . Authors $ ["6"]} 147 , emptyF {etagF = Just . ETagM $ [evref]} 148 , emptyF {ptagF = Just . PTagM $ [pub, keyref]} 149 , emptyF {kindsF = Just . Kinds $ [0]} 150 , emptyF {aztagF = [AZTag 't' "butterflies"]} 151 152 ] [ 153 "Ids1", "Ids2" 154 , "Authors" 155 , "ETags" 156 , "PTags" 157 , "Kind 0" 158 , "t tag" 159 ]