| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- using Infrastructure.StockData;
- namespace Application.Tests;
- [TestClass]
- public sealed class DartDisclosureParserTests
- {
- [TestMethod]
- public void Parse_Success_MapsAllFieldsAndMeta()
- {
- // OpenDART list.json 실검증 shape — status "000", 상장(stock_code 6자리) 항목
- const string json = """
- {"status":"000","message":"정상","page_no":1,"page_count":100,"total_count":1178,"total_page":12,
- "list":[
- {"corp_code":"00126380","corp_name":"삼성전자","stock_code":"005930","corp_cls":"Y","report_nm":"주요사항보고서(자기주식취득결정)","rcept_no":"20250103000123","flr_nm":"삼성전자","rcept_dt":"20250103","rm":""}
- ]}
- """;
- var result = DartDisclosureParser.Parse(json);
- Assert.AreEqual("000", result.Status);
- Assert.AreEqual("정상", result.Message);
- Assert.AreEqual(1, result.PageNo);
- Assert.AreEqual(12, result.TotalPage);
- Assert.AreEqual(1178, result.TotalCount);
- Assert.AreEqual(1, result.Rows.Count);
- var d = result.Rows[0];
- Assert.AreEqual("20250103000123", d.RceptNo, "접수번호 14자리");
- Assert.AreEqual("00126380", d.CorpCode, "고유번호 8자리");
- Assert.AreEqual("삼성전자", d.CorpName);
- Assert.AreEqual("005930", d.StockCode, "상장 종목코드 6자리");
- Assert.AreEqual("Y", d.CorpCls, "유가증권시장");
- Assert.AreEqual("주요사항보고서(자기주식취득결정)", d.ReportNm);
- Assert.AreEqual("삼성전자", d.FlrNm);
- Assert.AreEqual(new DateOnly(2025, 1, 3), d.RceptDt, "rcept_dt YYYYMMDD → DateOnly");
- Assert.IsNull(d.Rm, "빈 rm 은 null");
- }
- [TestMethod]
- public void Parse_EmptyStockCode_BecomesNull()
- {
- // 비상장(자산운용 등) — stock_code "" → null, corp_cls "E"(기타), rm "정"(정정)
- const string json = """
- {"status":"000","message":"정상","page_no":1,"page_count":100,"total_count":1,"total_page":1,
- "list":[
- {"corp_code":"00380942","corp_name":"카디안자산운용","stock_code":"","corp_cls":"E","report_nm":"[기재정정]일괄신고서(집합투자증권-신탁형)","rcept_no":"20250103000294","flr_nm":"카디안자산운용","rcept_dt":"20250103","rm":"정"}
- ]}
- """;
- var result = DartDisclosureParser.Parse(json);
- Assert.AreEqual(1, result.Rows.Count);
- var d = result.Rows[0];
- Assert.IsNull(d.StockCode, "비상장 stock_code \"\" 는 null");
- Assert.AreEqual("E", d.CorpCls);
- Assert.AreEqual("정", d.Rm, "비고(rm) 유지");
- }
- [TestMethod]
- public void Parse_Status013_NoData_ReturnsEmptyRows()
- {
- // 013 = 조회된 데이터 없음 — list 노드 없이 status/message 만
- const string json = """
- {"status":"013","message":"조회된 데이터가 없습니다."}
- """;
- var result = DartDisclosureParser.Parse(json);
- Assert.AreEqual("013", result.Status);
- Assert.AreEqual(0, result.Rows.Count, "013 은 빈 목록");
- }
- [TestMethod]
- public void Parse_KeyError_Status020_ReturnsEmptyRows()
- {
- // 020 = 등록되지 않은 키 등 오류 — status != "000" 이면 rows 비움
- const string json = """
- {"status":"020","message":"등록되지 않은 키입니다."}
- """;
- var result = DartDisclosureParser.Parse(json);
- Assert.AreEqual("020", result.Status);
- Assert.AreEqual(0, result.Rows.Count);
- }
- [TestMethod]
- public void Parse_MultipleRows_DateParsing()
- {
- // 여러 행 — 각기 다른 접수일 파싱 확인
- const string json = """
- {"status":"000","message":"정상","page_no":1,"page_count":100,"total_count":2,"total_page":1,
- "list":[
- {"corp_code":"00111111","corp_name":"에이","stock_code":"111111","corp_cls":"K","report_nm":"분기보고서","rcept_no":"20250102000001","flr_nm":"에이","rcept_dt":"20250102","rm":""},
- {"corp_code":"00222222","corp_name":"비","stock_code":"222222","corp_cls":"N","report_nm":"사업보고서","rcept_no":"20250103000002","flr_nm":"비","rcept_dt":"20250103","rm":"첨부추가"}
- ]}
- """;
- var result = DartDisclosureParser.Parse(json);
- Assert.AreEqual(2, result.Rows.Count);
- Assert.AreEqual(new DateOnly(2025, 1, 2), result.Rows[0].RceptDt);
- Assert.AreEqual("K", result.Rows[0].CorpCls, "코스닥");
- Assert.AreEqual(new DateOnly(2025, 1, 3), result.Rows[1].RceptDt);
- Assert.AreEqual("N", result.Rows[1].CorpCls, "코넥스");
- Assert.AreEqual("첨부추가", result.Rows[1].Rm);
- }
- [TestMethod]
- public void Parse_MissingRequiredField_RowSkipped()
- {
- // 필수(rcept_no/corp_code/report_nm/rcept_dt) 결측 행은 건너뜀 — 방어
- const string json = """
- {"status":"000","message":"정상","page_no":1,"page_count":100,"total_count":2,"total_page":1,
- "list":[
- {"corp_code":"00333333","corp_name":"씨","stock_code":"333333","corp_cls":"Y","report_nm":"","rcept_no":"20250103000003","flr_nm":"씨","rcept_dt":"20250103","rm":""},
- {"corp_code":"00444444","corp_name":"디","stock_code":"444444","corp_cls":"Y","report_nm":"정기보고서","rcept_no":"20250103000004","flr_nm":"디","rcept_dt":"20250103","rm":""}
- ]}
- """;
- var result = DartDisclosureParser.Parse(json);
- Assert.AreEqual(1, result.Rows.Count, "report_nm 빈 행은 skip");
- Assert.AreEqual("20250103000004", result.Rows[0].RceptNo);
- }
- }
|