Files
zszq-trs/UnitTestProject/Helpers/TriggerNodeSkipTests.cs
T

163 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using YLErp.DBModels;
using YLErp.Helpers;
using System.Collections.Generic;
using System.Linq;
namespace YLErp.Helpers.Tests
{
/// <summary>
/// 需求①:交易提交进入审批流程时的「起点触发条件跳过」测试。
/// <para>场景:交易一进来,若节点1、2配置的触发条件均不满足,应直接从节点3开始审核;
/// 若全部节点都不满足,则直接审批通过(无需任何审核)。</para>
/// </summary>
[TestClass]
public class TriggerNodeSkipTests
{
/// <summary>构造一个审批节点:order + 可选的触发条件JSON。</summary>
private static approvalprocess Node(int order, string triggerCondition = null)
{
return new approvalprocess
{
order = order,
node = 0,
triggerCondition = triggerCondition
};
}
/// <summary>构造"期初名义本金 > 阈值"的触发条件JSON。</summary>
private static string InitialNotionalGt(double threshold)
{
return JsonConvert.SerializeObject(new ConditionExpressionConfig
{
tokens = new List<ConditionToken>
{
new ConditionToken
{
type = "condition",
condition = new ConditionItem { field = "initialNotional", op = "gt", value = threshold }
}
}
});
}
private static ConditionContext Ctx(double initialNotional)
{
return new ConditionContext
{
Trade = new trade { OriginalStockEqvNotional = initialNotional }
};
}
[TestMethod]
public void StartNode_NoTrigger_ReturnsStartDirectly()
{
// 节点1无触发条件 → 直接返回节点1
var nodes = new List<approvalprocess> { Node(1), Node(2), Node(3) };
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, nodes[0], Ctx(500));
Assert.IsNotNull(result);
Assert.AreEqual(1, result.order);
}
[TestMethod]
public void StartNode_TriggerSatisfied_ReturnsStart()
{
// 节点1触发条件">100",交易期初200满足 → 返回节点1
var nodes = new List<approvalprocess>
{
Node(1, InitialNotionalGt(100)),
Node(2),
Node(3)
};
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, nodes[0], Ctx(200));
Assert.IsNotNull(result);
Assert.AreEqual(1, result.order);
}
[TestMethod]
public void StartNode_TriggerNotSatisfied_SkipsToNextSatisfied()
{
// 节点1触发">100",节点2触发">500",交易期初200
// → 节点1不满足(200>100满足? 满足)... 重新设计:节点1触发">1000"200不满足;节点2无触发 → 返回节点2
var nodes = new List<approvalprocess>
{
Node(1, InitialNotionalGt(1000)), // 200 不满足 >1000
Node(2), // 无触发条件
Node(3)
};
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, nodes[0], Ctx(200));
Assert.IsNotNull(result);
Assert.AreEqual(2, result.order);
}
[TestMethod]
public void AllStartNodesNotSatisfied_ReturnsNull_DirectlyApproved()
{
// 节点1、2、3都有触发条件,交易都不满足 → 返回null(表示直接审批通过)
var nodes = new List<approvalprocess>
{
Node(1, InitialNotionalGt(1000)), // 200 不满足
Node(2, InitialNotionalGt(5000)), // 200 不满足
Node(3, InitialNotionalGt(10000)) // 200 不满足
};
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, nodes[0], Ctx(200));
Assert.IsNull(result);
}
[TestMethod]
public void SkipMultipleNodes_LandsOnThird()
{
// 节点1、2都不满足,节点3无触发 → 返回节点3
// 模拟"A默认审核、B>100W再审核、C>=500W再审核"中,小额交易跳过B、C直达... 实际应停在满足的节点
var nodes = new List<approvalprocess>
{
Node(1, InitialNotionalGt(1000000)), // 50W 不满足
Node(2, InitialNotionalGt(2000000)), // 50W 不满足
Node(3) // 无触发条件(兜底审核)
};
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, nodes[0], Ctx(500000));
Assert.IsNotNull(result);
Assert.AreEqual(3, result.order);
}
[TestMethod]
public void SatisfiedAtSecondNode_StopsThere()
{
// 节点1触发">1000"不满足,节点2触发">100"满足 → 返回节点2(不会继续到节点3)
var nodes = new List<approvalprocess>
{
Node(1, InitialNotionalGt(1000)), // 200 不满足
Node(2, InitialNotionalGt(100)), // 200 满足
Node(3, InitialNotionalGt(50)) // 不会走到这
};
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, nodes[0], Ctx(200));
Assert.IsNotNull(result);
Assert.AreEqual(2, result.order);
}
[TestMethod]
public void StartFromMiddleNode_Works()
{
// 起点不是节点1(如分支调整后从节点2开始),从节点2起判断
var nodes = new List<approvalprocess>
{
Node(1, InitialNotionalGt(1000)),
Node(2, InitialNotionalGt(1000)), // 200 不满足
Node(3) // 无触发
};
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, nodes[1], Ctx(200));
Assert.IsNotNull(result);
Assert.AreEqual(3, result.order);
}
[TestMethod]
public void NullStart_ReturnsNull()
{
var nodes = new List<approvalprocess> { Node(1) };
var result = ConditionEvaluator.FindFirstTriggeredNode(nodes, null, Ctx(500));
Assert.IsNull(result);
}
}
}