{-# LANGUAGE OverloadedStrings #-} module Eventium.Store.PostgresqlSpec (spec) where import Data.ByteString (ByteString) import qualified Data.ByteString.UTF8 as UTF8 import Database.Persist.Postgresql import Eventium.Store.Postgresql import Eventium.Testkit import System.Environment (lookupEnv) import Test.Hspec spec :: Spec spec = do describe "Postgres event store" $ do eventStoreSpec postgresStoreRunner globalStreamEventStoreSpec postgresStoreGlobalRunner makeStore :: (MonadIO m) => m ( VersionedEventStoreWriter (SqlPersistT m) CounterEvent, VersionedEventStoreReader (SqlPersistT m) CounterEvent, ConnectionPool ) makeStore = do let makeConnString host port user pass db = "host=" <> host <> " port=" <> port <> " user=" <> user <> " dbname=" <> db <> " password=" <> pass writer = codecEventStoreWriter jsonStringCodec $ postgresqlEventStoreWriter defaultSqlEventStoreConfig reader = codecVersionedEventStoreReader jsonStringCodec $ sqlEventStoreReader defaultSqlEventStoreConfig connString <- makeConnString <$> getEnvDef "POSTGRES_HOST" "127.0.0.1" <*> getEnvDef "POSTGRES_PORT" "5432" <*> getEnvDef "POSTGRES_USER" "postgres" <*> getEnvDef "POSTGRES_PASSWORD" "password" <*> getEnvDef "POSTGRES_DBNAME" "eventium_test" pool <- liftIO $ runNoLoggingT (createPostgresqlPool connString 1) liftIO $ flip runSqlPool pool $ do void $ runMigrationSilent migrateSqlEvent truncateTables return (writer, reader, pool) getEnvDef :: (MonadIO m) => String -> ByteString -> m ByteString getEnvDef name def = liftIO $ maybe def UTF8.fromString <$> lookupEnv name truncateTables :: (MonadIO m) => SqlPersistT m () truncateTables = do -- Ensure both rows and the sequence are reset between tests rawExecute "TRUNCATE TABLE events RESTART IDENTITY" [] postgresStoreRunner :: EventStoreRunner (SqlPersistT IO) postgresStoreRunner = EventStoreRunner $ \action -> do (writer, reader, pool) <- makeStore runSqlPool (action writer reader) pool postgresStoreGlobalRunner :: GlobalStreamEventStoreRunner (SqlPersistT IO) postgresStoreGlobalRunner = GlobalStreamEventStoreRunner $ \action -> do (writer, _, pool) <- makeStore let globalReader = codecGlobalEventStoreReader jsonStringCodec (sqlGlobalEventStoreReader defaultSqlEventStoreConfig) runSqlPool (action writer globalReader) pool