using Infrastructure.StockData; namespace Application.Tests; [TestClass] public sealed class SeibroDivInfoParserTests { [TestMethod] public void Parse_FromSampleXml_MapsFields_AndNoIssucoCustno() { // SEIBro getDivInfo 실응답 fixture (삼성전자/삼성전자1우) — 18행. ISSUCO_CUSTNO 는 응답에 없어 Isin 으로만 조인. var rows = SeibroDivInfoParser.Parse(SeibroXml.Parse(SeibroFixtures.Read("getDivInfo.xml"))); Assert.AreEqual(18, rows.Count); var first = rows.Single(c => c.Isin == "KR7005930003" && c.RgtStdDt == new DateOnly(2016, 12, 31)); Assert.AreEqual("삼성전자", first.KorSecnNm); Assert.AreEqual("보통주", first.SecnKacdNm); Assert.AreEqual(100m, first.Pval, "액면가 PVAL"); Assert.AreEqual(0m, first.StkAllocRatio, "주식배정비율 0 (현금배당)"); Assert.AreEqual(550m, first.CashAllocRatio); Assert.AreEqual(27500m, first.CashAllocAmt, "1주당 현금배당금"); Assert.AreEqual(1.53m, first.MartpDivRate, "시가배당율"); Assert.AreEqual(new DateOnly(2017, 4, 24), first.Th1PayTermBeginDt, "배당지급일 — 스펙·샘플 모두 존재"); Assert.IsNull(first.DeliDt, "DELI_DT value=\"\" → null"); Assert.IsFalse(first.MajshrEtcDiffAllocYn!.Value, "MAJSHR_ETC_DIFF_ALOC_YN=N"); Assert.IsTrue(first.TstkNoagnYn!.Value, "TSTK_NOAGN_YN=Y"); } [TestMethod] public void Parse_DifferentialDividendFields_Null_WhenEmpty() { // 기대 행위: 차등배당 4필드(CASH_DIFF_*, STK_DIFF_*, MARTP_DIFF_*)는 무차등 종목에서 빈값 → null var rows = SeibroDivInfoParser.Parse(SeibroXml.Parse(SeibroFixtures.Read("getDivInfo.xml"))); var row = rows[0]; Assert.IsNull(row.CashDiffDiviAmt); Assert.IsNull(row.CashDiffDiviRate); Assert.IsNull(row.StkDiffDiviRate); Assert.IsNull(row.MartpDiffDiviRate); } [TestMethod] public void Parse_FractionalRate_WithLeadingDot() { // 기대 행위: ".34" 같은 소수점 선행 표기도 decimal 파싱 (0.34) const string xml = """ """; var rows = SeibroDivInfoParser.Parse(SeibroXml.Parse(xml)); Assert.AreEqual(0.34m, rows[0].MartpDivRate); Assert.AreEqual(1.5m, rows[0].CashDiffDiviRate, "차등배당 있는 종목은 값 파싱"); } }