KosisSyncTests.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using Domain.Entities.Stocks;
  2. using Infrastructure.StockData;
  3. using Microsoft.EntityFrameworkCore;
  4. using SharedKernel;
  5. namespace Application.Tests;
  6. /// <summary>
  7. /// KosisImport 의 DB 반영 로직(config ClassCode 필터 + Code+Period upsert) 통합 검증 — HTTP 는 파서 입력을 fixture/합성으로 대체
  8. /// (SeibroDividendSyncTests 방식 미러링). 실제 SQL Server(LocalDB)로 UQ upsert·idempotency 확인.
  9. /// </summary>
  10. [TestClass]
  11. public sealed class KosisSyncTests
  12. {
  13. private static string FixtureRoot => Path.Combine(AppContext.BaseDirectory, "Fixtures", "Kosis");
  14. private static AppSettings.KosisSection.KosisIndicator Cpi(string classCode = "T10") => new()
  15. {
  16. Code = $"CPI-{Guid.NewGuid():N}",
  17. Name = "소비자물가지수",
  18. OrgId = "101",
  19. TblId = "DT_1J22003",
  20. ItmId = "T",
  21. ObjL1 = "ALL",
  22. Cycle = "M",
  23. ClassCode = classCode
  24. };
  25. [TestMethod]
  26. public async Task Upsert_CpiFixture_FiltersToNationalSeries_ThenIdempotent()
  27. {
  28. // 기대: CPI fixture(전국 T10 2행 + 서울 11 1행 + 빈DT 1행)에서 ClassCode=T10 필터로 전국 2행만 적재. 재실행은 무변경.
  29. var rows = KosisParser.Parse(File.ReadAllText(Path.Combine(FixtureRoot, "cpi.json")));
  30. var indicator = Cpi();
  31. using (var db = TestDb.Create())
  32. {
  33. var (inserted, updated) = await KosisImport.UpsertAsync(db, indicator, rows, CancellationToken.None);
  34. Assert.AreEqual(2, inserted, "ClassCode=T10(전국) 계열만, DT 빈값 제외 → 2행");
  35. Assert.AreEqual(0, updated);
  36. }
  37. using (var db = TestDb.Create())
  38. {
  39. var (inserted, updated) = await KosisImport.UpsertAsync(db, indicator, rows, CancellationToken.None);
  40. Assert.AreEqual(0, inserted, "동일 스냅샷 재실행은 insert 없음");
  41. Assert.AreEqual(0, updated, "무변경 행은 update 로 세지 않는다");
  42. var saved = await db.MacroIndicator.AsNoTracking().Where(c => c.Code == indicator.Code && c.Period == "202401").SingleAsync();
  43. Assert.AreEqual(113.17m, saved.Value);
  44. Assert.AreEqual("2020=100", saved.Unit);
  45. var count = await db.MacroIndicator.AsNoTracking().CountAsync(c => c.Code == indicator.Code);
  46. Assert.AreEqual(2, count, "서울(11) 계열은 적재되지 않음");
  47. }
  48. }
  49. [TestMethod]
  50. public async Task Upsert_EmptyClassCode_AutoLocksToFirstSeries()
  51. {
  52. // ClassCode 미지정이면 응답 첫 계열(첫 등장 C1=T10)로 자동 고정 — 서울(11) 혼입 배제
  53. var rows = KosisParser.Parse(File.ReadAllText(Path.Combine(FixtureRoot, "cpi.json")));
  54. var indicator = Cpi(classCode: "");
  55. using var db = TestDb.Create();
  56. var (inserted, _) = await KosisImport.UpsertAsync(db, indicator, rows, CancellationToken.None);
  57. Assert.AreEqual(2, inserted, "첫 계열(T10)만 2행");
  58. }
  59. [TestMethod]
  60. public async Task Upsert_ChangedValue_UpdatesRow()
  61. {
  62. var indicator = Cpi();
  63. var original = new List<KosisParser.Row> { new("202501", 120.0m, "2020=100", "소비자물가지수(총지수)", "T10", "전국") };
  64. var changed = new List<KosisParser.Row> { new("202501", 121.5m, "2020=100", "소비자물가지수(총지수)", "T10", "전국") };
  65. using (var db = TestDb.Create())
  66. {
  67. await KosisImport.UpsertAsync(db, indicator, original, CancellationToken.None);
  68. }
  69. using (var db = TestDb.Create())
  70. {
  71. var (inserted, updated) = await KosisImport.UpsertAsync(db, indicator, changed, CancellationToken.None);
  72. Assert.AreEqual(0, inserted);
  73. Assert.AreEqual(1, updated, "수치 변경 → update");
  74. var saved = await db.MacroIndicator.AsNoTracking().Where(c => c.Code == indicator.Code && c.Period == "202501").SingleAsync();
  75. Assert.AreEqual(121.5m, saved.Value);
  76. }
  77. }
  78. [TestMethod]
  79. public async Task Upsert_NoMatchingClassCode_InsertsNothing()
  80. {
  81. var indicator = Cpi(classCode: "ZZZ");
  82. var rows = KosisParser.Parse(File.ReadAllText(Path.Combine(FixtureRoot, "cpi.json")));
  83. using var db = TestDb.Create();
  84. var (inserted, updated) = await KosisImport.UpsertAsync(db, indicator, rows, CancellationToken.None);
  85. Assert.AreEqual(0, inserted);
  86. Assert.AreEqual(0, updated);
  87. }
  88. }