summaryrefslogtreecommitdiff
path: root/tests/FundLab.Api.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/FundLab.Api.Tests')
-rw-r--r--tests/FundLab.Api.Tests/CashReconciliationTests.fs43
1 files changed, 43 insertions, 0 deletions
diff --git a/tests/FundLab.Api.Tests/CashReconciliationTests.fs b/tests/FundLab.Api.Tests/CashReconciliationTests.fs
index 59f6fd6..d8dc7bb 100644
--- a/tests/FundLab.Api.Tests/CashReconciliationTests.fs
+++ b/tests/FundLab.Api.Tests/CashReconciliationTests.fs
@@ -2,6 +2,7 @@ namespace FundLab.Api.Tests
open System
open System.Text.Json
+open Npgsql
open Xunit
open FundLab.Api
open FundLab.Domain
@@ -201,6 +202,20 @@ type CashReconciliationTests(fixture: PostgresFixture) =
|> Seq.filter (fun entry -> entry.GetProperty("source").GetString() = source)
|> Seq.length
+ let deleteLedgerEvents fundId =
+ use connection = new NpgsqlConnection(fixture.ConnectionString)
+ connection.Open()
+ use command = new NpgsqlCommand("DELETE FROM cash_ledger_events WHERE fund_id = @fund_id", connection)
+ command.Parameters.AddWithValue("fund_id", fundId) |> ignore
+ command.ExecuteNonQuery() |> ignore
+
+ let ledgerEventCount fundId =
+ use connection = new NpgsqlConnection(fixture.ConnectionString)
+ connection.Open()
+ use command = new NpgsqlCommand("SELECT count(*) FROM cash_ledger_events WHERE fund_id = @fund_id", connection)
+ command.Parameters.AddWithValue("fund_id", fundId) |> ignore
+ command.ExecuteScalar() :?> int64
+
[<Fact>]
member _.``cash reconciliation balances across every source category``() =
let fundId = createFund 10000.00m
@@ -252,3 +267,31 @@ type CashReconciliationTests(fixture: PostgresFixture) =
let status, body = reconciliation (Guid.NewGuid())
Assert.Equal(404, status)
Assert.Contains("FUND_NOT_FOUND", body)
+
+ [<Fact>]
+ member _.``backfill rebuilds the ledger for history written before it existed``() =
+ let fundId = createFund 10000.00m
+ deposit fundId 5000.00m (fixture.Key "cash-backfill-deposit")
+ buyStockDebit fundId "600519" 100m 10.00m (fixture.Key "cash-backfill-buy")
+ sellStock fundId "600519" 40m 10.00m (fixture.Key "cash-backfill-sell")
+ buyBond fundId "110075" 10m 100.00m
+ recordBondCoupon fundId "110075" 50.00m (fixture.Key "cash-backfill-coupon")
+ subscribe fundId (seedInstrument ()) 1000.00m (fixture.Key "cash-backfill-subscribe")
+
+ // deposit + stock buy + stock sell + bond coupon + subscription settle
+ let expected = 5L
+
+ // simulate a database that predates the ledger: drop the hook-written events
+ deleteLedgerEvents fundId
+ Assert.Equal(0L, ledgerEventCount fundId)
+
+ repository().BackfillCashLedger() |> ignore
+
+ Assert.Equal(expected, ledgerEventCount fundId)
+ Assert.Equal(0.00m, (repository().GetCashReconciliation fundId |> Result.defaultWith failwith).Difference)
+
+ // re-running must be a no-op: same event count, same reconciled balance
+ repository().BackfillCashLedger() |> ignore
+
+ Assert.Equal(expected, ledgerEventCount fundId)
+ Assert.Equal(0.00m, (repository().GetCashReconciliation fundId |> Result.defaultWith failwith).Difference)