using Infrastructure.StockData; namespace Application.Tests; [TestClass] public sealed class YahooChartParserTests { [TestMethod] public void Parse_MapsMetaFields_LowercasesSymbol() { // Yahoo v8 chart 표준 응답 축약 (meta 만) — 실제 ^GSPC 응답 형태 const string json = """ {"chart":{"result":[{"meta":{"symbol":"^GSPC","regularMarketTime":1783543721,"gmtoffset":-14400,"regularMarketPrice":7482.71,"chartPreviousClose":7499.36,"regularMarketDayHigh":7488.51,"regularMarketDayLow":7421.82,"regularMarketVolume":2874621000}}],"error":null}} """; var q = YahooChartParser.Parse(json, "^GSPC"); Assert.IsNotNull(q); Assert.AreEqual("^gspc", q.Symbol, "심볼은 소문자 정규화"); Assert.AreEqual(7482.71m, q.Close); Assert.AreEqual(7488.51m, q.High); Assert.AreEqual(7421.82m, q.Low); Assert.AreEqual(2874621000L, q.Volume); Assert.AreEqual(7482.71m, q.Open, "시가 미제공 → 종가로 대체"); Assert.AreEqual(2026, q.TradeDate.Year); Assert.AreEqual(7, q.TradeDate.Month); } [TestMethod] public void Parse_MissingPriceOrTime_ReturnsNull() { // 종가 없음 Assert.IsNull(YahooChartParser.Parse("""{"chart":{"result":[{"meta":{"symbol":"^X","regularMarketTime":1783543721}}]}}""", "^X")); // 거래시각 없음 Assert.IsNull(YahooChartParser.Parse("""{"chart":{"result":[{"meta":{"symbol":"^X","regularMarketPrice":100.0}}]}}""", "^X")); } [TestMethod] public void Parse_EmptyOrError_ReturnsNull() { Assert.IsNull(YahooChartParser.Parse("", "^X")); Assert.IsNull(YahooChartParser.Parse(" ", "^X")); Assert.IsNull(YahooChartParser.Parse("""{"chart":{"result":null,"error":{"code":"Not Found"}}}""", "^X")); Assert.IsNull(YahooChartParser.Parse("not json", "^X")); } }