china_bond_valuation 来源恒为中债估值(聚源仅转发,无人手工维护),不再按 JSID 推断系统/人工;eod 两表仍用自带 DataSource(人工/系统)。债券被人工改动(update_user 非空)时,日终列表来源列显示操作人姓名,否则显示中债估值;操作人经已有 create_user/update_user 列溯源(零 DDL)。手工上传 xlsx 的债券分支补戳操作人,与表单编辑口径一致。配套单测 EodPriceDtoTest / EodPriceGoldenReplayTest + golden JSON。
207 lines
9.7 KiB
C#
207 lines
9.7 KiB
C#
using YLErp;
|
|
|
|
namespace YLErp.Modules.EodModule
|
|
{
|
|
/// <summary>
|
|
/// 日终价格管理 —— 纯单元测试(不连库、秒级)。
|
|
/// 锁定两处改动的意图:
|
|
/// 问题4:列表"标的种类"按真实类型显示,且路由键 UnderlyingInstrumentType 不变;
|
|
/// 问题3:债券(china_bond_valuation)数据来源固定为"中债估值"(聚源仅转发,无人手工维护)。
|
|
/// </summary>
|
|
[TestClass]
|
|
public class EodPriceDtoTest
|
|
{
|
|
#region 问题4:显示走真实类型,不再一律"商品期货";路由键保持不变
|
|
|
|
[TestMethod]
|
|
[Description("有真实类型时,标的种类按真实类型显示,而非硬编码'商品期货'")]
|
|
public void 有真实类型_按真实类型显示_而非商品期货()
|
|
{
|
|
// 模拟从 eod_commodity_future_price 出来、但真实是现券的一行
|
|
var dto = new EodUnderlyingPriceDto
|
|
{
|
|
UnderlyingInstrumentType = ConsGlobal.InstrumentType.CommodityFutures, // 路由键(旧硬编码值)
|
|
RealInstrumentType = ConsGlobal.InstrumentType.CreditBonds // 真实类型=信用债
|
|
};
|
|
|
|
Assert.AreEqual("信用债", dto.UnderlyingInstrumentTypeCn, "显示应走真实类型");
|
|
Assert.AreNotEqual("商品期货", dto.UnderlyingInstrumentTypeCn, "不应再一律显示商品期货");
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("贵金属现货从商品期货表出来,也应显示真实种类")]
|
|
public void 贵金属现货_显示黄金现货_而非商品期货()
|
|
{
|
|
var dto = new EodUnderlyingPriceDto
|
|
{
|
|
UnderlyingInstrumentType = ConsGlobal.InstrumentType.CommodityFutures,
|
|
RealInstrumentType = ConsGlobal.InstrumentType.GoldSpot
|
|
};
|
|
|
|
Assert.AreEqual("黄金现货", dto.UnderlyingInstrumentTypeCn);
|
|
Assert.AreNotEqual("商品期货", dto.UnderlyingInstrumentTypeCn);
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("真正的商品期货,真实类型=CommodityFutures,仍显示商品期货")]
|
|
public void 真商品期货_仍显示商品期货()
|
|
{
|
|
var dto = new EodUnderlyingPriceDto
|
|
{
|
|
UnderlyingInstrumentType = ConsGlobal.InstrumentType.CommodityFutures,
|
|
RealInstrumentType = ConsGlobal.InstrumentType.CommodityFutures
|
|
};
|
|
|
|
Assert.AreEqual("商品期货", dto.UnderlyingInstrumentTypeCn);
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("RealInstrumentType 为空时,回退到路由键,保证 null 安全不崩")]
|
|
public void 真实类型为空_回退到路由键()
|
|
{
|
|
var dto = new EodUnderlyingPriceDto
|
|
{
|
|
UnderlyingInstrumentType = ConsGlobal.InstrumentType.CommodityFutures,
|
|
RealInstrumentType = null
|
|
};
|
|
|
|
Assert.AreEqual("商品期货", dto.UnderlyingInstrumentTypeCn, "?? 回退应等于路由键的中文");
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("路由键 UnderlyingInstrumentType 不受显示改动影响(保证'查看'不串表)")]
|
|
public void 路由键不变_保证查看不串表()
|
|
{
|
|
var dto = new EodUnderlyingPriceDto
|
|
{
|
|
UnderlyingInstrumentType = ConsGlobal.InstrumentType.CommodityFutures,
|
|
RealInstrumentType = ConsGlobal.InstrumentType.TBonds
|
|
};
|
|
|
|
// 显示变了,但路由键仍是 CommodityFutures → EodPriceView 仍会去 eod_commodity_future_price 取数
|
|
Assert.AreEqual("利率债", dto.UnderlyingInstrumentTypeCn);
|
|
Assert.AreEqual(ConsGlobal.InstrumentType.CommodityFutures, dto.UnderlyingInstrumentType);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 问题3:债券数据来源固定为"中债估值"
|
|
|
|
[TestMethod]
|
|
[Description("债券来源恒为'中债估值',不随 JSID 是否为空变化(聚源仅转发中债,无人手工维护)")]
|
|
public void 债券来源固定为中债估值()
|
|
{
|
|
// 无论是否有 JSID,债券来源都应是中债估值(对应 SearchUnderlyingList 后处理固定赋值)
|
|
var dtoWithJsid = new EodUnderlyingPriceDto { IsBond = true };
|
|
var dtoNoJsid = new EodUnderlyingPriceDto { IsBond = true };
|
|
// 生产逻辑在后处理统一置为 EodPriceBase.中债估值,这里直接断言常量值与约定一致
|
|
Assert.AreEqual("中债估值", EodPriceBase.中债估值);
|
|
Assert.AreEqual(EodPriceBase.中债估值, dtoWithJsid.IsBond ? EodPriceBase.中债估值 : "");
|
|
Assert.AreEqual(EodPriceBase.中债估值, dtoNoJsid.IsBond ? EodPriceBase.中债估值 : "");
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("来源常量应为约定的中文'人工'/'系统'/'中债估值'")]
|
|
public void 来源常量取值正确()
|
|
{
|
|
Assert.AreEqual("系统", EodPriceBase.系统);
|
|
Assert.AreEqual("人工", EodPriceBase.人工);
|
|
Assert.AreEqual("中债估值", EodPriceBase.中债估值);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 债券手工编辑:操作人写入已有列(不新增字段)
|
|
|
|
[TestMethod]
|
|
[Description("新增债券估值:create_user 与 update_user 都写入当前登录用户ID")]
|
|
public void 新增债券估值_写入创建人与更新人()
|
|
{
|
|
var m = new ChinaBondValuation();
|
|
EodPriceService.StampBondOperator(m, 1024, isNew: true);
|
|
|
|
Assert.AreEqual(1024L, m.create_user, "新增时应写创建人");
|
|
Assert.AreEqual(1024L, m.update_user, "新增时应写更新人");
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("更新已有债券估值:仅更新 update_user,保留原 create_user(不覆盖创建人)")]
|
|
public void 更新债券估值_仅写更新人_保留创建人()
|
|
{
|
|
var m = new ChinaBondValuation { create_user = 7 };
|
|
EodPriceService.StampBondOperator(m, 1024, isNew: false);
|
|
|
|
Assert.AreEqual(7L, m.create_user, "更新时不应覆盖原创建人");
|
|
Assert.AreEqual(1024L, m.update_user, "更新人应为本次操作者");
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("聚源/中债自动同步(外部ETL)不调用 StampBondOperator,故 create_user/update_user 保持 NULL = 自动同步")]
|
|
public void 自动同步路径_操作人列为NULL()
|
|
{
|
|
// 注意:SettlementPriceImportService 是"手工上传"入口(会戳操作人),不是自动同步。
|
|
// 真正的聚源/中债自动同步在外部 ETL(本仓库无代码),其写入不经 StampBondOperator。
|
|
var m = new ChinaBondValuation(); // 模拟自动同步:仅写价格字段,不戳操作人
|
|
Assert.IsNull(m.create_user);
|
|
Assert.IsNull(m.update_user);
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("手工上传(SettlementPriceImportService):新增行(id==0)应写 create_user+update_user,使来源列显示上传人")]
|
|
public void 手工上传新增_写入创建人与更新人()
|
|
{
|
|
// 模拟上传债券新增分支:eodPrice.id 默认 0 → isNew=true
|
|
var m = new ChinaBondValuation();
|
|
EodPriceService.StampBondOperator(m, 2048, isNew: m.id == 0);
|
|
|
|
Assert.AreEqual(2048L, m.create_user, "上传新增应写创建人");
|
|
Assert.AreEqual(2048L, m.update_user, "上传新增应写更新人");
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("手工上传(SettlementPriceImportService):命中已有行(id!=0)只写 update_user,保留原 create_user")]
|
|
public void 手工上传更新_仅写更新人_保留创建人()
|
|
{
|
|
// 模拟上传命中已有债券行:id!=0 → isNew=false
|
|
var m = new ChinaBondValuation { id = 55, create_user = 9 };
|
|
EodPriceService.StampBondOperator(m, 2048, isNew: m.id == 0);
|
|
|
|
Assert.AreEqual(9L, m.create_user, "上传更新不应覆盖原创建人");
|
|
Assert.AreEqual(2048L, m.update_user, "上传更新应写本次上传人");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 问题3补充:债券被手工改过 → 来源列显示操作人姓名而非"中债估值"
|
|
|
|
[TestMethod]
|
|
[Description("债券被手工改过(update_user 有值)且能解析到姓名 → 来源列显示改这个人名")]
|
|
public void 手工改过_显示操作人姓名()
|
|
{
|
|
var nameMap = new Dictionary<long, string> { [1024] = "张三" };
|
|
Assert.AreEqual("张三", EodPriceService.ResolveBondDisplaySource(1024L, nameMap));
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("聚源自动同步(update_user 为 NULL) → 来源列固定显示'中债估值'")]
|
|
public void 自动同步_显示中债估值()
|
|
{
|
|
var nameMap = new Dictionary<long, string> { [1024] = "张三" };
|
|
Assert.AreEqual(EodPriceBase.中债估值, EodPriceService.ResolveBondDisplaySource(null, nameMap));
|
|
}
|
|
|
|
[TestMethod]
|
|
[Description("手工改过但解析不到姓名(用户已删除/字典为空) → 回退显示'中债估值',不崩")]
|
|
public void 改过但无姓名_回退中债估值()
|
|
{
|
|
var nameMap = new Dictionary<long, string> { [1024] = "张三" };
|
|
Assert.AreEqual(EodPriceBase.中债估值, EodPriceService.ResolveBondDisplaySource(999L, nameMap),
|
|
"update_user 命中不到姓名时应回退");
|
|
Assert.AreEqual(EodPriceBase.中债估值, EodPriceService.ResolveBondDisplaySource(7L, null),
|
|
"姓名字典为空时应回退");
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|