xiangyixiangqin/server/tests/XiangYi.Application.Tests/Services/ReportServicePropertyTests.cs
2026-01-02 18:00:49 +08:00

298 lines
10 KiB
C#
Raw Permalink 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 Xunit;
using XiangYi.Application.Services;
using XiangYi.Core.Entities.Biz;
using XiangYi.Core.Enums;
namespace XiangYi.Application.Tests.Services;
/// <summary>
/// ReportService属性测试 - 举报记录完整性
/// </summary>
public class ReportCompletenessPropertyTests
{
// 预定义的举报原因列表
private static readonly string[] ValidReasons = new[]
{
"虚假信息", "骚扰行为", "不当言论", "欺诈行为", "色情内容", "广告推销"
};
// 预定义的有效举报类型
private static readonly int[] ValidReportTypes = new[]
{
(int)ReportType.User, (int)ReportType.Message, (int)ReportType.Profile
};
/// <summary>
/// **Feature: backend-api, Property 26: 举报记录完整性**
/// **Validates: Requirements 16.1**
///
/// *For any* 创建的举报记录, 应包含举报人、被举报人、举报原因、举报时间等必要字段
/// </summary>
[Property(MaxTest = 100)]
public Property Report_ShouldHaveAllRequiredFields()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
// 使用随机数生成不同的测试数据
var seed = positiveInt.Get;
var reporterId = (seed % 500) + 1;
var reportedUserId = ((seed % 500) + 501);
var reportType = ValidReportTypes[seed % ValidReportTypes.Length];
var reason = ValidReasons[seed % ValidReasons.Length];
// Act - 创建举报记录
var report = ReportService.CreateReportStatic(
reporterId,
reportedUserId,
reportType,
reason,
description: null,
evidenceUrls: null);
// Assert - 验证所有必要字段都存在
var hasRequiredFields = ReportService.HasRequiredFields(report);
// 验证具体字段
var hasReporterId = report.ReporterId == reporterId;
var hasReportedUserId = report.ReportedUserId == reportedUserId;
var hasReportType = report.ReportType == reportType;
var hasReason = report.Reason == reason;
var hasCreateTime = report.CreateTime != default;
var hasStatus = report.Status == (int)ReportStatus.Pending;
return hasRequiredFields
&& hasReporterId
&& hasReportedUserId
&& hasReportType
&& hasReason
&& hasCreateTime
&& hasStatus;
});
}
/// <summary>
/// 举报记录 - 举报人和被举报人不能相同
/// </summary>
[Property(MaxTest = 100)]
public Property Report_ReporterAndReportedUser_ShouldBeDifferent()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
var userId = positiveInt.Get;
var reportType = ValidReportTypes[userId % ValidReportTypes.Length];
var reason = ValidReasons[userId % ValidReasons.Length];
// 当举报人和被举报人相同时,验证应该失败
var isValid = ReportService.ValidateReportCompleteness(
userId,
userId, // 相同的用户ID
reportType,
reason,
DateTime.Now);
// 应该返回false因为不能举报自己
return !isValid;
});
}
/// <summary>
/// 举报记录 - 举报原因不能为空
/// </summary>
[Property(MaxTest = 100)]
public Property Report_Reason_ShouldNotBeEmpty()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
var seed = positiveInt.Get;
var reporterId = (seed % 500) + 1;
var reportedUserId = ((seed % 500) + 501);
var reportType = ValidReportTypes[seed % ValidReportTypes.Length];
// 测试空字符串
var emptyReasons = new[] { "", " ", " " };
var emptyReason = emptyReasons[seed % emptyReasons.Length];
// 当举报原因为空时,验证应该失败
var isValid = ReportService.ValidateReportCompleteness(
reporterId,
reportedUserId,
reportType,
emptyReason,
DateTime.Now);
// 应该返回false因为举报原因不能为空
return !isValid;
});
}
/// <summary>
/// 举报记录 - 举报类型必须有效
/// </summary>
[Property(MaxTest = 100)]
public Property Report_Type_ShouldBeValid()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
var seed = positiveInt.Get;
var reporterId = (seed % 500) + 1;
var reportedUserId = ((seed % 500) + 501);
var reportType = ValidReportTypes[seed % ValidReportTypes.Length];
var reason = ValidReasons[seed % ValidReasons.Length];
// 有效的举报类型应该通过验证
var isValid = ReportService.ValidateReportCompleteness(
reporterId,
reportedUserId,
reportType,
reason,
DateTime.Now);
return isValid;
});
}
/// <summary>
/// 举报记录 - 无效的举报类型应该被拒绝
/// </summary>
[Property(MaxTest = 100)]
public Property Report_InvalidType_ShouldBeRejected()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
var seed = positiveInt.Get;
var reporterId = (seed % 500) + 1;
var reportedUserId = ((seed % 500) + 501);
// 生成无效的举报类型(不在枚举范围内)
var invalidReportTypes = new[] { 0, -1, 4, 5, 100 };
var invalidReportType = invalidReportTypes[seed % invalidReportTypes.Length];
var reason = ValidReasons[seed % ValidReasons.Length];
// 无效的举报类型应该验证失败
var isValid = ReportService.ValidateReportCompleteness(
reporterId,
reportedUserId,
invalidReportType,
reason,
DateTime.Now);
// 应该返回false
return !isValid;
});
}
/// <summary>
/// 举报记录 - 证据保存正确性
/// </summary>
[Property(MaxTest = 100)]
public Property Report_Evidence_ShouldBePreserved()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
var seed = positiveInt.Get;
var reporterId = (seed % 500) + 1;
var reportedUserId = ((seed % 500) + 501);
var reportType = ValidReportTypes[seed % ValidReportTypes.Length];
var reason = ValidReasons[seed % ValidReasons.Length];
var evidenceCount = (seed % 5) + 1; // 1-5个证据
// 生成证据URL列表
var evidenceUrls = Enumerable.Range(1, evidenceCount)
.Select(i => $"https://example.com/evidence_{i}.jpg")
.ToList();
// Act - 创建带证据的举报记录
var report = ReportService.CreateReportStatic(
reporterId,
reportedUserId,
reportType,
reason,
description: "详细描述",
evidenceUrls: evidenceUrls);
// Assert - 验证证据被正确保存
var hasEvidence = !string.IsNullOrEmpty(report.Evidence);
var evidenceContainsUrls = evidenceUrls.All(url => report.Evidence!.Contains(url));
return hasEvidence && evidenceContainsUrls;
});
}
/// <summary>
/// 举报记录 - 创建时间应该是当前时间附近
/// </summary>
[Property(MaxTest = 100)]
public Property Report_CreateTime_ShouldBeRecent()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
var seed = positiveInt.Get;
var reporterId = (seed % 500) + 1;
var reportedUserId = ((seed % 500) + 501);
var reportType = ValidReportTypes[seed % ValidReportTypes.Length];
var reason = ValidReasons[seed % ValidReasons.Length];
var beforeCreate = DateTime.Now;
// Act - 创建举报记录
var report = ReportService.CreateReportStatic(
reporterId,
reportedUserId,
reportType,
reason,
description: null,
evidenceUrls: null);
var afterCreate = DateTime.Now;
// Assert - 创建时间应该在beforeCreate和afterCreate之间
return report.CreateTime >= beforeCreate && report.CreateTime <= afterCreate;
});
}
/// <summary>
/// 举报记录 - 初始状态应该是待处理
/// </summary>
[Property(MaxTest = 100)]
public Property Report_InitialStatus_ShouldBePending()
{
return Prop.ForAll(
Arb.Default.PositiveInt(),
positiveInt =>
{
var seed = positiveInt.Get;
var reporterId = (seed % 500) + 1;
var reportedUserId = ((seed % 500) + 501);
var reportType = ValidReportTypes[seed % ValidReportTypes.Length];
var reason = ValidReasons[seed % ValidReasons.Length];
// Act - 创建举报记录
var report = ReportService.CreateReportStatic(
reporterId,
reportedUserId,
reportType,
reason,
description: null,
evidenceUrls: null);
// Assert - 初始状态应该是待处理
return report.Status == (int)ReportStatus.Pending;
});
}
}