using IM.Application.Chat.Commands; using IM.Application.Chat.DTOs; using IM.Application.Chat.Validators; using IM.Domain.Enums; using Xunit; namespace BuildFlow.IM.Tests.Chat; public class SendMessageCommandValidatorTests { private readonly SendMessageCommandValidator _validator = new(); [Fact] public void Rejects_file_message_without_file_metadata() { var command = CreateCommand(MessageContentType.File, "report.md", null); var result = _validator.Validate(command); Assert.False(result.IsValid); Assert.Contains(result.Errors, e => e.ErrorMessage == "文件消息必须包含文件元数据"); } [Fact] public void Accepts_file_message_with_storage_reference_metadata() { var metadata = new MessageMetadataDto("report.md", 1024, null, null, null, null, null) { BucketName = "im-files", ObjectKey = "im/20260609/report.md", ContentType = "text/markdown" }; var command = CreateCommand(MessageContentType.File, "report.md", metadata); var result = _validator.Validate(command); Assert.True(result.IsValid); } [Fact] public void Rejects_file_message_larger_than_200mb() { var metadata = new MessageMetadataDto("report.zip", 200L * 1024 * 1024 + 1, null, null, null, null, null) { BucketName = "im-files", ObjectKey = "im/20260705/report.zip", ContentType = "application/zip" }; var command = CreateCommand(MessageContentType.File, "report.zip", metadata); var result = _validator.Validate(command); Assert.False(result.IsValid); Assert.Contains(result.Errors, e => e.ErrorMessage == "文件不能超过 200MB"); } [Fact] public void Rejects_image_message_without_preview_or_storage_reference() { var metadata = new MessageMetadataDto("photo.png", 2048, null, null, null, null, null); var command = CreateCommand(MessageContentType.Image, "[图片]", metadata); var result = _validator.Validate(command); Assert.False(result.IsValid); Assert.Contains(result.Errors, e => e.ErrorMessage == "图片消息必须包含图片预览地址或存储引用"); } [Fact] public void Rejects_unknown_message_content_type() { var command = CreateCommand((MessageContentType)999, "hello", null); var result = _validator.Validate(command); Assert.False(result.IsValid); Assert.Contains(result.Errors, e => e.ErrorMessage == "不支持的消息类型"); } private static SendMessageCommand CreateCommand( MessageContentType contentType, string content, MessageMetadataDto? metadata) { return new SendMessageCommand( Guid.Parse("11111111-1111-1111-1111-111111111111"), Guid.Parse("22222222-2222-2222-2222-222222222222"), "alice", contentType, content, metadata, null); } }