KoreaEximExchangeParserTests.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using Infrastructure.StockData;
  2. namespace Application.Tests;
  3. [TestClass]
  4. public sealed class KoreaEximExchangeParserTests
  5. {
  6. [TestMethod]
  7. public void Parse_UsdAndJpy100_MapsUnitNameRateAndTtbTts()
  8. {
  9. // 수출입은행 AP01 응답 골격 — 최상위 배열, 값은 전부 문자열, 천단위 콤마 포함. JPY(100)/IDR(100) 등 "(100)" 단위 원문 보존
  10. const string json = """
  11. [
  12. {"result":1,"cur_unit":"USD","cur_nm":"미국 달러","ttb":"1,382.10","tts":"1,410.30","deal_bas_r":"1,396.20","bkpr":"1,396","kftc_deal_bas_r":"1,396.20"},
  13. {"result":1,"cur_unit":"JPY(100)","cur_nm":"일본 옌","ttb":"905.11","tts":"923.55","deal_bas_r":"914.33","bkpr":"914","kftc_deal_bas_r":"914.33"}
  14. ]
  15. """;
  16. var rows = KoreaEximExchangeParser.Parse(json);
  17. Assert.AreEqual(2, rows.Count);
  18. var usd = rows[0];
  19. Assert.AreEqual("USD", usd.CurrencyUnit);
  20. Assert.AreEqual("미국 달러", usd.CurrencyName);
  21. Assert.AreEqual(1396.20m, usd.DealBasRate, "deal_bas_r 천단위 콤마 제거");
  22. Assert.AreEqual(1382.10m, usd.Ttb);
  23. Assert.AreEqual(1410.30m, usd.Tts);
  24. var jpy = rows[1];
  25. Assert.AreEqual("JPY(100)", jpy.CurrencyUnit, "\"(100)\" 단위 표기 원문 보존");
  26. Assert.AreEqual(914.33m, jpy.DealBasRate);
  27. }
  28. [TestMethod]
  29. public void Parse_RowWithFailedResultCode_IsSkipped()
  30. {
  31. // result != 1 인 행은 skip (여기선 3=인증코드 오류). 성공(1) 행만 남는다.
  32. const string json = """
  33. [
  34. {"result":3,"cur_unit":"USD","cur_nm":"미국 달러","deal_bas_r":"1,396.20"},
  35. {"result":1,"cur_unit":"EUR","cur_nm":"유로","ttb":"","tts":"","deal_bas_r":"1,502.44"}
  36. ]
  37. """;
  38. var rows = KoreaEximExchangeParser.Parse(json);
  39. Assert.AreEqual(1, rows.Count, "result=3 행은 제외");
  40. Assert.AreEqual("EUR", rows[0].CurrencyUnit);
  41. Assert.AreEqual(1502.44m, rows[0].DealBasRate);
  42. Assert.IsNull(rows[0].Ttb, "빈 ttb 는 null");
  43. Assert.IsNull(rows[0].Tts, "빈 tts 는 null");
  44. }
  45. [TestMethod]
  46. public void Parse_MissingDealBasRate_RowIsSkipped()
  47. {
  48. // deal_bas_r 파싱 실패(빈값) 행은 매매기준율이 없으므로 skip
  49. const string json = """
  50. [
  51. {"result":1,"cur_unit":"XDR","cur_nm":"SDR","ttb":"","tts":"","deal_bas_r":""}
  52. ]
  53. """;
  54. Assert.AreEqual(0, KoreaEximExchangeParser.Parse(json).Count);
  55. }
  56. [TestMethod]
  57. public void Parse_EmptyArrayOrNonArrayOrBlank_ReturnsEmpty()
  58. {
  59. // koreaexim quirk: 주말/공휴일·오전 이전엔 빈 배열([]) → 0건
  60. Assert.AreEqual(0, KoreaEximExchangeParser.Parse("[]").Count);
  61. // 오류/빈 응답도 예외 없이 0건
  62. Assert.AreEqual(0, KoreaEximExchangeParser.Parse("").Count);
  63. Assert.AreEqual(0, KoreaEximExchangeParser.Parse("{\"result\":4}").Count, "배열이 아니면 0건");
  64. }
  65. }