using YLErp.Modules.EodModule.SettlementModule;
namespace YLErp.Modules.EodModule
{
///
/// 收盘 FR007 定盘检查(EodCheckFr007Price)行为契约(纯内存,不连库):
/// ① 检查日回拨:交易日 = 收盘日自身(对既有交易日收盘行为零变更);
/// 周末/节假日 = 上一交易日——非交易日无 FR007 定盘,按裸收盘日检查会形成
/// "收盘必报缺价"死锁(2026-08-28:0523 周六收盘即此症);
/// ② 回拨规则与计息取价同源(IndexFixerBase.GetFixingDate),检查的日期
/// 就是计息路径实际会读的日期;
/// ③ 报错文案:交易日缺价保持旧格式,非交易日注明回拨,附交易编号供定位。
///
[TestClass]
public class EodCheckFr007PriceTest
{
[TestMethod]
public void 检查日_交易日收盘_等于收盘日自身()
{
// 2026-05-22 周五、2026-08-28 周五:正常交易日收盘,行为必须与改造前一致
Assert.AreEqual(new DateTime(2026, 5, 22), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 5, 22)));
Assert.AreEqual(new DateTime(2026, 8, 28), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 8, 28)));
}
[TestMethod]
public void 检查日_周六收盘_回拨到上一交易日周五()
{
// 2026-08-28 缺陷场景:0523 为周六,FR007 非发布日永无定盘行,
// 旧逻辑检查裸收盘日必报"未入库"且无法通过补交易要素绕过
Assert.AreEqual(new DateTime(2026, 5, 22), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 5, 23)));
}
[TestMethod]
public void 检查日_周日收盘_回拨跳过周末到周五()
{
// 与 GetInterestsUnitTest_T0 记录的取价回拨先例一致:GetNonHolidayDefore(4/26周日)→4/24周五
Assert.AreEqual(new DateTime(2026, 4, 24), EodCheckFr007Price.GetCheckDate(new DateTime(2026, 4, 26)));
}
[TestMethod]
public void 检查日_与计息取价日同源()
{
// 同一收盘日,检查日必须等于计息路径 interest_rule=0 腿实际读的取价日
var settleDate = new DateTime(2026, 5, 23);
var interestPathFixingDate = YLErp.Derivatives.Interest.IndexFixerBase.GetFixingDate(settleDate, 0);
Assert.AreEqual(interestPathFixingDate, EodCheckFr007Price.GetCheckDate(settleDate));
}
[TestMethod]
public void 报错文案_交易日缺价_格式与旧版一致()
{
// 交易日缺价:不带回拨说明、无交易则不带交易段,保持"yyyy年MM月dd日FR007价格未入库"原格式
var msg = EodCheckFr007Price.BuildMissingMessage(new DateTime(2026, 5, 22), new DateTime(2026, 5, 22), Array.Empty());
Assert.AreEqual("2026年05月22日FR007价格未入库", msg);
}
[TestMethod]
public void 报错文案_非交易日回拨缺价_注明回拨()
{
var msg = EodCheckFr007Price.BuildMissingMessage(new DateTime(2026, 5, 23), new DateTime(2026, 5, 22), null);
StringAssert.Contains(msg, "2026年05月22日FR007价格未入库");
StringAssert.Contains(msg, "收盘日2026年05月23日为非交易日,已回拨至上一交易日检查");
}
[TestMethod]
public void 报错文案_带交易编号供定位()
{
var msg = EodCheckFr007Price.BuildMissingMessage(
new DateTime(2026, 5, 22), new DateTime(2026, 5, 22),
new[] { "TRS-001", "TRS-002" });
StringAssert.EndsWith(msg, ";涉及FR007浮动的交易: TRS-001、TRS-002");
}
[TestMethod]
public void 报错文案_交易超过上限_截断并以等N笔收尾()
{
var trades = Enumerable.Range(1, 25).Select(i => $"TRS-{i:D3}").ToArray();
var msg = EodCheckFr007Price.BuildMissingMessage(
new DateTime(2026, 5, 22), new DateTime(2026, 5, 22), trades);
StringAssert.Contains(msg, $"TRS-{EodCheckFr007Price.MaxTradesInMessage:D3}");
StringAssert.Contains(msg, "等25笔");
Assert.IsFalse(msg.Contains("TRS-021"), "超过上限的交易编号不应完整列出");
Assert.IsFalse(msg.Contains("TRS-025、"), "截断后不应再拼接后续编号");
}
}
}