58 lines
2.0 KiB
C#
58 lines
2.0 KiB
C#
using IM.Application.Chat.Handlers;
|
||
using Xunit;
|
||
|
||
namespace BuildFlow.IM.Tests.Chat;
|
||
|
||
/// <summary>
|
||
/// 消息撤回权限矩阵与时间窗测试。
|
||
/// 测 <see cref="RecallMessageCommandHandler.CanRecall"/> 纯判定逻辑(剥离出 Handler,避免依赖 MongoDB)。
|
||
/// </summary>
|
||
public class RecallMessageCommandHandlerTests
|
||
{
|
||
private static readonly DateTime Now = new(2026, 6, 27, 10, 0, 0, DateTimeKind.Utc);
|
||
|
||
[Fact]
|
||
public void Sender_can_recall_within_time_window()
|
||
{
|
||
var createdAt = Now.AddSeconds(-30);
|
||
Assert.True(RecallMessageCommandHandler.CanRecall(isSelf: true, isAdmin: false, createdAt, Now));
|
||
}
|
||
|
||
[Fact]
|
||
public void Sender_cannot_recall_after_time_window()
|
||
{
|
||
var createdAt = Now.AddMinutes(-3); // 超过 2 分钟窗口
|
||
Assert.False(RecallMessageCommandHandler.CanRecall(isSelf: true, isAdmin: false, createdAt, Now));
|
||
}
|
||
|
||
[Fact]
|
||
public void Sender_can_recall_at_exact_window_boundary()
|
||
{
|
||
// 恰好 2 分钟:<= 窗口,允许撤回(边界含等号)
|
||
var createdAt = Now.AddMinutes(-RecallMessageCommandHandler.RecallTimeWindowMinutes);
|
||
Assert.True(RecallMessageCommandHandler.CanRecall(isSelf: true, isAdmin: false, createdAt, Now));
|
||
}
|
||
|
||
[Fact]
|
||
public void Non_participant_cannot_recall()
|
||
{
|
||
var createdAt = Now.AddSeconds(-10);
|
||
Assert.False(RecallMessageCommandHandler.CanRecall(isSelf: false, isAdmin: false, createdAt, Now));
|
||
}
|
||
|
||
[Fact]
|
||
public void Group_admin_can_recall_others_message_without_time_limit()
|
||
{
|
||
// 管理员撤回他人 1 小时前的消息,不受时间窗限制
|
||
var createdAt = Now.AddHours(-1);
|
||
Assert.True(RecallMessageCommandHandler.CanRecall(isSelf: false, isAdmin: true, createdAt, Now));
|
||
}
|
||
|
||
[Fact]
|
||
public void Group_admin_can_recall_own_message_without_time_limit()
|
||
{
|
||
var createdAt = Now.AddHours(-2);
|
||
Assert.True(RecallMessageCommandHandler.CanRecall(isSelf: true, isAdmin: true, createdAt, Now));
|
||
}
|
||
}
|