eventium-memory-0.3.2: tests/Eventium/MetadataEnrichmentSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Eventium.MetadataEnrichmentSpec (spec) where
import Control.Concurrent.STM
import Data.IORef
import Data.Maybe (isJust)
import Eventium
import Eventium.Store.Memory
import Test.Hspec
spec :: Spec
spec = describe "Metadata enrichment" $ do
describe "metadataEnrichingEventStoreWriter" $ do
it "populates event type name from Typeable" $ do
tvar <- eventMapTVar
let taggedWriter = tvarTaggedEventStoreWriter tvar
enrichedWriter = metadataEnrichingEventStoreWriter testCodec (runEventStoreWriterUsing atomically taggedWriter)
reader = runEventStoreReaderUsing atomically (tvarEventStoreReader tvar)
uuid = uuidFromInteger 1
_ <- enrichedWriter.storeEvents uuid NoStream [42 :: Int, 99]
events <- reader.getEvents (allEvents uuid)
map (\e -> e.metadata.eventType) events `shouldBe` ["Int", "Int"]
it "populates createdAt timestamp" $ do
tvar <- eventMapTVar
let taggedWriter = tvarTaggedEventStoreWriter tvar
enrichedWriter = metadataEnrichingEventStoreWriter testCodec (runEventStoreWriterUsing atomically taggedWriter)
reader = runEventStoreReaderUsing atomically (tvarEventStoreReader tvar)
uuid = uuidFromInteger 1
_ <- enrichedWriter.storeEvents uuid NoStream [42 :: Int]
events <- reader.getEvents (allEvents uuid)
all (\e -> isJust e.metadata.createdAt) events `shouldBe` True
describe "metadataEnrichingEventStoreWriterWithEnricher" $ do
it "applies MetadataEnricher to set correlationId" $ do
tvar <- eventMapTVar
let corrId = uuidFromInteger 99
enricher m = m {correlationId = Just corrId}
taggedWriter = tvarTaggedEventStoreWriter tvar
enrichedWriter = metadataEnrichingEventStoreWriterWithEnricher enricher testCodec (runEventStoreWriterUsing atomically taggedWriter)
reader = runEventStoreReaderUsing atomically (tvarEventStoreReader tvar)
uuid = uuidFromInteger 1
_ <- enrichedWriter.storeEvents uuid NoStream [42 :: Int]
events <- reader.getEvents (allEvents uuid)
map (\e -> e.metadata.correlationId) events `shouldBe` [Just corrId]
it "leaves correlationId unset when enricher is id" $ do
tvar <- eventMapTVar
let taggedWriter = tvarTaggedEventStoreWriter tvar
enrichedWriter = metadataEnrichingEventStoreWriterWithEnricher id testCodec (runEventStoreWriterUsing atomically taggedWriter)
reader = runEventStoreReaderUsing atomically (tvarEventStoreReader tvar)
uuid = uuidFromInteger 1
_ <- enrichedWriter.storeEvents uuid NoStream [42 :: Int]
events <- reader.getEvents (allEvents uuid)
map (\e -> e.metadata.correlationId) events `shouldBe` [Nothing]
describe "backward compatibility" $ do
it "non-tagged writer still uses empty metadata" $ do
tvar <- eventMapTVar
let writer = runEventStoreWriterUsing atomically (tvarEventStoreWriter tvar)
reader = runEventStoreReaderUsing atomically (tvarEventStoreReader tvar)
uuid = uuidFromInteger 1
_ <- writer.storeEvents uuid NoStream [42 :: Int]
events <- reader.getEvents (allEvents uuid)
map (\e -> e.metadata.eventType) events `shouldBe` [""]
describe "publishingTaggedCodecEventStoreWriter" $ do
it "propagates metadata to published StreamEvents" $ do
tvar <- eventMapTVar
publishedRef <- newIORef []
let taggedWriter = runEventStoreWriterUsing atomically (tvarTaggedEventStoreWriter tvar)
handler = EventHandler $ \(StreamEvent _ _ meta _) ->
modifyIORef publishedRef (++ [meta.eventType])
publisher = synchronousPublisher handler
pubWriter = publishingTaggedCodecEventStoreWriter testCodec taggedWriter publisher
enrichedWriter = metadataEnrichingEventStoreWriter testCodec pubWriter
uuid = uuidFromInteger 1
_ <- enrichedWriter.storeEvents uuid NoStream [42 :: Int, 99]
published <- readIORef publishedRef
published `shouldBe` ["Int", "Int"]
-- A simple test codec for Int
testCodec :: Codec Int Int
testCodec = Codec id Just