diff options
Diffstat (limited to 'tests/FundLab.Api.Tests')
| -rw-r--r-- | tests/FundLab.Api.Tests/BondQuoteProbeTests.fs | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/tests/FundLab.Api.Tests/BondQuoteProbeTests.fs b/tests/FundLab.Api.Tests/BondQuoteProbeTests.fs index bed590a..1e19f77 100644 --- a/tests/FundLab.Api.Tests/BondQuoteProbeTests.fs +++ b/tests/FundLab.Api.Tests/BondQuoteProbeTests.fs @@ -6,19 +6,35 @@ open Xunit open FundLab.Api module BondQuoteProbeSupport = - let payload (code: string) (name: string option) (price: string option) (maturity: string option) = - let optionalText = - function - | Some value -> sprintf "\"%s\"" value - | None -> "null" - + let private optionalText = + function + | Some value -> sprintf "\"%s\"" value + | None -> "null" + + let payloadWith + (code: string) + (name: string option) + (price: string option) + (maturity: string option) + (cleanPrice: string option) + (accruedInterest: string option) + (date: string option) + (sourceRevision: string) + = sprintf - "{\"schema_version\":\"fund-lab.akshare.v1\",\"operation\":\"bond-quote\",\"source\":\"akshare\",\"source_revision\":\"akshare-test/eastmoney\",\"collected_at\":\"2026-09-21T08:00:00Z\",\"instrument\":{\"code\":\"%s\"},\"quote\":{\"name\":%s,\"price\":%s,\"maturity_date\":%s}}" + "{\"schema_version\":\"fund-lab.akshare.v1\",\"operation\":\"bond-quote\",\"source\":\"akshare\",\"source_revision\":\"%s\",\"collected_at\":\"2026-09-21T08:00:00Z\",\"instrument\":{\"code\":\"%s\"},\"quote\":{\"name\":%s,\"price\":%s,\"clean_price\":%s,\"accrued_interest\":%s,\"date\":%s,\"maturity_date\":%s}}" + sourceRevision code (optionalText name) (optionalText price) + (optionalText cleanPrice) + (optionalText accruedInterest) + (optionalText date) (optionalText maturity) + let payload (code: string) (name: string option) (price: string option) (maturity: string option) = + payloadWith code name price maturity None None None "akshare-test/eastmoney" + let collectorReturning (fetch: unit -> Result<string, string>) = { new IMarketDataCollector with member _.Search(_, _) = Ok "" @@ -89,15 +105,51 @@ type BondQuoteProbeTests(fixture: PostgresFixture) = | Error failure -> failwithf "expected a bond quote, got %A" failure [<Fact>] + member _.``probe parses clean price, accrued interest and date when present``() = + let json = + BondQuoteProbeSupport.payloadWith + "019547" + None + (Some "119.858") + None + (Some "119.858") + (Some "0.5000") + (Some "2026-09-21") + "akshare-test/eastmoney/hs-bond-daily" + + let probe = + AkshareBondQuoteProbe(BondQuoteProbeSupport.collectorReturning (fun () -> Ok json)) :> IBondQuoteProbe + + match probe.GetQuote("019547", CancellationToken.None) with + | Ok quote -> + Assert.Equal<decimal option>(Some 119.858m, quote.Price) + Assert.Equal<decimal option>(Some 119.858m, quote.CleanPrice) + Assert.Equal<decimal option>(Some 0.5m, quote.AccruedInterest) + Assert.Equal<DateOnly option>(Some(DateOnly(2026, 9, 21)), quote.Date) + Assert.Equal("akshare-test/eastmoney/hs-bond-daily", quote.SourceRevision) + | Error failure -> failwithf "expected a bond quote, got %A" failure + + [<Fact>] + member _.``probe rejects a payload whose code disagrees with the request``() = + let json = BondQuoteProbeSupport.payload "123121" (Some "帝尔转债") (Some "101.5000") None + + let probe = + AkshareBondQuoteProbe(BondQuoteProbeSupport.collectorReturning (fun () -> Ok json)) :> IBondQuoteProbe + + match probe.GetQuote("110075", CancellationToken.None) with + | Error(InvalidMarketDataPayload message) -> Assert.Contains("does not match requested code", message) + | other -> failwithf "expected InvalidMarketDataPayload, got %A" other + + [<Fact>] member _.``probe surfaces a no valid quote collector failure``() = let probe = AkshareBondQuoteProbe( - BondQuoteProbeSupport.collectorReturning (fun () -> Error "AKShare collector failed: no valid quote for 999999") + BondQuoteProbeSupport.collectorReturning (fun () -> Error "AKShare collector failed: no valid bond quote for 999999") ) :> IBondQuoteProbe match probe.GetQuote("999999", CancellationToken.None) with - | Error(MarketDataCollectorUnavailable message) -> Assert.Contains("no valid quote for 999999", message) + | Error(MarketDataCollectorUnavailable message) -> Assert.Contains("no valid bond quote for 999999", message) | other -> failwithf "expected MarketDataCollectorUnavailable, got %A" other [<Fact>] @@ -166,8 +218,12 @@ type BondQuoteProbeTests(fixture: PostgresFixture) = Ok { Code = "123121" + SourceRevision = "akshare-test/eastmoney/hs-cov-spot" Name = Some "帝尔转债" Price = Some 101.5m + CleanPrice = Some 101.5m + AccruedInterest = None + Date = None MaturityDate = Some(DateOnly(2026, 6, 3)) }) |
