HaniBlindBox/server/HoneyBox/tests/HoneyBox.Tests/Services/WechatPayVersionRoutingPropertyTests.cs
2026-01-25 21:20:46 +08:00

188 lines
6.4 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 FsCheck;
using FsCheck.Xunit;
using HoneyBox.Core.Interfaces;
using HoneyBox.Core.Services;
using HoneyBox.Model.Data;
using HoneyBox.Model.Models.Payment;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;
namespace HoneyBox.Tests.Services;
/// <summary>
/// 微信支付版本路由属性测试
/// **Feature: wechat-pay-v3-upgrade**
/// </summary>
public class WechatPayVersionRoutingPropertyTests
{
#region Property 4:
/// <summary>
/// **Feature: wechat-pay-v3-upgrade, Property 4: 版本路由正确性**
/// *For any* 支付请求,当商户配置的 PayVersion 为 "V3" 时,应该调用 V3 接口;
/// 当 PayVersion 为 "V2" 时,应该调用 V2 接口。
/// **Validates: Requirements 3.1, 3.5**
/// </summary>
[Property(MaxTest = 100)]
public bool VersionRouting_ShouldRouteToCorrectService_BasedOnPayVersion(
NonEmptyString orderNo,
PositiveInt userId,
PositiveInt amount,
bool isV3)
{
// Arrange
var payVersion = isV3 ? "V3" : "V2";
// 安全地处理订单号,确保不会越界
var cleanOrderNo = orderNo.Get.Replace("-", "");
var orderNoStr = $"MYH{(cleanOrderNo.Length > 10 ? cleanOrderNo.Substring(0, 10) : cleanOrderNo)}";
var merchantConfig = new WechatPayMerchantConfig
{
Name = "测试商户",
MchId = "1738725801",
AppId = "wx1234567890",
Key = "testkey123456789012345678901234",
OrderPrefix = "MYH",
PayVersion = payVersion,
ApiV3Key = isV3 ? "d1cxc0vXCUH2984901DxddPJMYqcwcnd" : null,
CertSerialNo = isV3 ? "SERIAL123456" : null,
PrivateKeyPath = isV3 ? "certs/test/key.pem" : null,
WechatPublicKeyId = isV3 ? "PUBKEYID123" : null,
WechatPublicKeyPath = isV3 ? "certs/test/pub.pem" : null,
NotifyUrl = "https://example.com/notify"
};
// 验证版本路由逻辑
var shouldUseV3 = merchantConfig.PayVersion == "V3";
// 属性PayVersion 为 "V3" 时应该路由到 V3否则路由到 V2
return shouldUseV3 == isV3;
}
/// <summary>
/// **Feature: wechat-pay-v3-upgrade, Property 4: 版本路由正确性**
/// *For any* 商户配置PayVersion 只能是 "V2" 或 "V3",默认为 "V2"。
/// **Validates: Requirements 3.1, 3.5**
/// </summary>
[Fact]
public void PayVersion_DefaultValue_ShouldBeV2()
{
var config = new WechatPayMerchantConfig();
Assert.Equal("V2", config.PayVersion);
}
/// <summary>
/// **Feature: wechat-pay-v3-upgrade, Property 4: 版本路由正确性**
/// *For any* V3 配置,必须包含 V3 必要字段才能正确路由。
/// **Validates: Requirements 3.1**
/// </summary>
[Property(MaxTest = 100)]
public bool V3Config_ShouldHaveRequiredFields_WhenPayVersionIsV3(
NonEmptyString apiV3Key,
NonEmptyString certSerialNo,
NonEmptyString privateKeyPath)
{
var config = new WechatPayMerchantConfig
{
PayVersion = "V3",
ApiV3Key = apiV3Key.Get,
CertSerialNo = certSerialNo.Get,
PrivateKeyPath = privateKeyPath.Get
};
// V3 配置必须有这些字段
var hasRequiredFields = !string.IsNullOrEmpty(config.ApiV3Key) &&
!string.IsNullOrEmpty(config.CertSerialNo) &&
!string.IsNullOrEmpty(config.PrivateKeyPath);
return config.PayVersion == "V3" && hasRequiredFields;
}
/// <summary>
/// **Feature: wechat-pay-v3-upgrade, Property 4: 版本路由正确性**
/// *For any* V2 配置V3 字段可以为空。
/// **Validates: Requirements 3.5**
/// </summary>
[Fact]
public void V2Config_ShouldWorkWithoutV3Fields()
{
var config = new WechatPayMerchantConfig
{
Name = "V2商户",
MchId = "1234567890",
AppId = "wx1234567890",
Key = "v2key12345678901234567890123456",
PayVersion = "V2",
// V3 字段为空
ApiV3Key = null,
CertSerialNo = null,
PrivateKeyPath = null
};
// V2 配置不需要 V3 字段
Assert.Equal("V2", config.PayVersion);
Assert.Null(config.ApiV3Key);
Assert.Null(config.CertSerialNo);
Assert.Null(config.PrivateKeyPath);
}
/// <summary>
/// **Feature: wechat-pay-v3-upgrade, Property 4: 版本路由正确性**
/// 测试版本路由决策逻辑的正确性。
/// **Validates: Requirements 3.1, 3.5**
/// </summary>
[Theory]
[InlineData("V3", true)]
[InlineData("V2", false)]
[InlineData("v3", false)] // 大小写敏感
[InlineData("v2", false)] // 大小写敏感
[InlineData("", false)]
[InlineData(null, false)]
public void VersionRouting_Decision_ShouldBeCorrect(string? payVersion, bool expectedV3Route)
{
// 版本路由决策逻辑
var shouldRouteToV3 = payVersion == "V3";
Assert.Equal(expectedV3Route, shouldRouteToV3);
}
/// <summary>
/// **Feature: wechat-pay-v3-upgrade, Property 4: 版本路由正确性**
/// *For any* 订单号前缀,版本路由应该基于商户配置而非订单号。
/// **Validates: Requirements 3.1, 3.5**
/// </summary>
[Property(MaxTest = 100)]
public bool VersionRouting_ShouldBeBasedOnMerchantConfig_NotOrderNo(
NonEmptyString orderPrefix,
bool isV3)
{
// 安全地处理订单前缀
var prefix = orderPrefix.Get.Length >= 3 ? orderPrefix.Get.Substring(0, 3) : orderPrefix.Get.PadRight(3, 'X');
// 创建两个商户配置,一个 V2一个 V3
var v2Config = new WechatPayMerchantConfig
{
OrderPrefix = prefix,
PayVersion = "V2"
};
var v3Config = new WechatPayMerchantConfig
{
OrderPrefix = prefix,
PayVersion = "V3"
};
// 相同的订单前缀,不同的版本配置
// 版本路由应该基于 PayVersion 字段
var v2ShouldRouteToV3 = v2Config.PayVersion == "V3";
var v3ShouldRouteToV3 = v3Config.PayVersion == "V3";
return !v2ShouldRouteToV3 && v3ShouldRouteToV3;
}
#endregion
}