SeibroDividendSyncTests.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using Domain.Entities.Stocks;
  2. using Infrastructure.StockData;
  3. using Microsoft.EntityFrameworkCore;
  4. namespace Application.Tests;
  5. /// <summary>
  6. /// SeibroDividendSyncService 의 DB 반영 로직(SeibroDividendImport) 통합 검증 — HTTP 는 파서 입력을 fixture 로 대체
  7. /// (SeibroIssuerSyncTests 방식 미러링). 실제 SQL Server(LocalDB)로 UQ upsert 동작 확인.
  8. /// </summary>
  9. [TestClass]
  10. public sealed class SeibroDividendSyncTests
  11. {
  12. [TestMethod]
  13. public async Task UpsertSchedules_FromSampleXml_InsertsAll_ThenIdempotent()
  14. {
  15. // 기대 행위: getDivSchedulInfo fixture(9행) 전 행 insert → 동일 스냅샷 재실행은 무변경 (UQ IssucoCustno+RgtStdDt+SortCd)
  16. var rows = SeibroDivSchedulParser.Parse(SeibroXml.Parse(SeibroFixtures.Read("getDivSchedulInfo.xml")));
  17. using (var db = TestDb.Create())
  18. {
  19. var (inserted, updated) = await SeibroDividendImport.UpsertSchedulesAsync(db, rows, CancellationToken.None);
  20. Assert.AreEqual(rows.Count, inserted, "첫 실행은 전 행 insert");
  21. Assert.AreEqual(0, updated);
  22. }
  23. using (var db = TestDb.Create())
  24. {
  25. var (inserted, updated) = await SeibroDividendImport.UpsertSchedulesAsync(db, rows, CancellationToken.None);
  26. Assert.AreEqual(0, inserted, "동일 스냅샷 재실행은 insert 없음");
  27. Assert.AreEqual(0, updated, "무변경 행은 update 로 세지 않는다");
  28. var saved = await db.DividendSchedule.AsNoTracking().Where(c => c.IssucoCustno == 593 && c.RgtStdDt == new DateOnly(2018, 3, 31)).SingleAsync();
  29. Assert.AreEqual(new DateOnly(2018, 3, 29), saved.XrgtDt);
  30. Assert.AreEqual("02", saved.RgtRsnDetailSortCd);
  31. }
  32. }
  33. [TestMethod]
  34. public async Task UpsertDividends_FromSampleXml_UpsertsByIsinAndDate()
  35. {
  36. // 기대 행위: getDivInfo fixture(18행) upsert(Isin+RgtStdDt). ISSUCO_CUSTNO 부재라도 Isin 으로 저장된다.
  37. var rows = SeibroDivInfoParser.Parse(SeibroXml.Parse(SeibroFixtures.Read("getDivInfo.xml")));
  38. using (var db = TestDb.Create())
  39. {
  40. var (inserted, _) = await SeibroDividendImport.UpsertDividendsAsync(db, rows, CancellationToken.None);
  41. Assert.AreEqual(18, inserted);
  42. }
  43. using (var db = TestDb.Create())
  44. {
  45. var (inserted, updated) = await SeibroDividendImport.UpsertDividendsAsync(db, rows, CancellationToken.None);
  46. Assert.AreEqual(0, inserted, "재실행 idempotent");
  47. Assert.AreEqual(0, updated);
  48. var saved = await db.Dividend.AsNoTracking().Where(c => c.Isin == "KR7005930003" && c.RgtStdDt == new DateOnly(2016, 12, 31)).SingleAsync();
  49. Assert.AreEqual(27500m, saved.CashAllocAmt);
  50. Assert.AreEqual(1.53m, saved.MartpDivRate);
  51. Assert.AreEqual(new DateOnly(2017, 4, 24), saved.Th1PayTermBeginDt);
  52. }
  53. }
  54. [TestMethod]
  55. public async Task UpsertDividends_ChangedAmount_UpdatesRow()
  56. {
  57. var isin = $"KR7{Guid.NewGuid().ToString("N")[..9]}";
  58. var date = new DateOnly(2022, 12, 31);
  59. var original = new List<SeibroDivInfoParser.Row> { new(isin, "테스트배당", "보통주", date, 500m, 0m, 100m, 1000m, 2.5m, null, null, false, false, null, null, null, null) };
  60. var changed = new List<SeibroDivInfoParser.Row> { new(isin, "테스트배당", "보통주", date, 500m, 0m, 100m, 1500m, 3.0m, null, null, false, false, null, null, null, null) };
  61. using (var db = TestDb.Create())
  62. {
  63. await SeibroDividendImport.UpsertDividendsAsync(db, original, CancellationToken.None);
  64. }
  65. using (var db = TestDb.Create())
  66. {
  67. var (inserted, updated) = await SeibroDividendImport.UpsertDividendsAsync(db, changed, CancellationToken.None);
  68. Assert.AreEqual(0, inserted);
  69. Assert.AreEqual(1, updated, "현금배당금·시가배당율 변경 → update");
  70. var saved = await db.Dividend.AsNoTracking().Where(c => c.Isin == isin).SingleAsync();
  71. Assert.AreEqual(1500m, saved.CashAllocAmt);
  72. }
  73. }
  74. [TestMethod]
  75. public async Task UpsertRightsBaseDates_FromSampleXml_UpsertsByNaturalKey()
  76. {
  77. // 기대 행위: getStddtInfo fixture(3행) upsert(회사번호+기준일+사유코드+세부유형)
  78. var rows = SeibroStddtParser.Parse(SeibroXml.Parse(SeibroFixtures.Read("getStddtInfo.xml")));
  79. using (var db = TestDb.Create())
  80. {
  81. var (inserted, _) = await SeibroDividendImport.UpsertRightsBaseDatesAsync(db, rows, CancellationToken.None);
  82. Assert.AreEqual(3, inserted);
  83. }
  84. using (var db = TestDb.Create())
  85. {
  86. var (inserted, updated) = await SeibroDividendImport.UpsertRightsBaseDatesAsync(db, rows, CancellationToken.None);
  87. Assert.AreEqual(0, inserted, "재실행 idempotent");
  88. Assert.AreEqual(0, updated);
  89. var saved = await db.RightsBaseDate.AsNoTracking().Where(c => c.IssucoCustno == 593 && c.RgtStdDt == new DateOnly(2016, 12, 31) && c.RgtRacd == "001").SingleAsync();
  90. Assert.AreEqual("정기총회", saved.RgtRacdNm);
  91. }
  92. }
  93. }