using System.Runtime.CompilerServices; using BuildFlow.Shared.Domain.Common; using IM.Domain.Entities.Conversation; using IM.Domain.Entities.ConversationParticipant; using IM.Domain.Entities.Group; using IM.Domain.Entities.GroupMember; using IM.Domain.Enums; using IM.Infrastructure.Persistence; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; namespace BuildFlow.IM.Tests; /// /// IM 模块测试数据库工厂:每个用例独立 InMemory 库,并通过 SavingChanges 事件自动补齐 /// IAuditable / IHasOperatorIP 审计字段(InMemory 无 AuditInterceptor,须手动补值,否则非空审计字段为 null)。 /// internal static class IMTestDb { public static ImDbContext Create([CallerMemberName] string testName = "") { var services = new ServiceCollection(); services.AddDbContext(options => options.UseInMemoryDatabase($"im-{testName}-{Guid.NewGuid()}")); var db = services.BuildServiceProvider().GetRequiredService(); db.SavingChanges += FillAuditFields; return db; } private static void FillAuditFields(object? sender, EventArgs args) { if (sender is not ImDbContext db) return; foreach (var entry in db.ChangeTracker.Entries()) { if (entry.Entity is IAuditable auditable) { auditable.CreatedBy ??= "test"; auditable.UpdatedBy ??= "test"; if (auditable.CreatedAt == default) auditable.CreatedAt = DateTime.UtcNow; if (auditable.UpdatedAt == default) auditable.UpdatedAt = DateTime.UtcNow; } if (entry.Entity is IHasOperatorIP operatorEntity) operatorEntity.OperatorIP ??= "127.0.0.1"; } } /// /// 构造一个群聊会话:群主 + 指成员 + 同步会话参与者。审计字段由 SavingChanges 事件补齐。 /// 返回 (会话Id, 群组Id)。 /// public static async Task<(Guid ConversationId, Guid GroupId)> SeedGroupAsync( ImDbContext db, string name, Guid ownerId, params Guid[] memberIds) { var conversation = new ConversationEntity { Type = ConversationTypeEnum.Group }; db.Conversations.Add(conversation); await db.SaveChangesAsync(); var group = new GroupEntity { ConversationId = conversation.Id, Name = name, OwnerId = ownerId }; db.Groups.Add(group); await db.SaveChangesAsync(); var allUserIds = new List { ownerId }; allUserIds.AddRange(memberIds.Where(id => id != ownerId)); foreach (var userId in allUserIds) { db.GroupMembers.Add(new GroupMemberEntity { GroupId = group.Id, UserId = userId, Role = userId == ownerId ? GroupMemberRoleEnum.Owner : GroupMemberRoleEnum.Member, JoinedAt = DateTime.UtcNow }); db.ConversationParticipants.Add(new ConversationParticipantEntity { ConversationId = conversation.Id, UserId = userId, JoinedAt = DateTime.UtcNow }); } await db.SaveChangesAsync(); return (conversation.Id, group.Id); } }