using IM.Domain.Entities;
using IM.Domain.Enums;
using IM.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace BuildFlow.IM.Integration.Tests;
///
/// 集成测试数据播种助手。直接写真实 PostgreSQL,构造会话/群组/群成员,
/// 供 ChatHub 与 MediatR handler 读写。
///
public static class ImTestSeeder
{
///
/// 播种一个私聊会话(两参与者),返回会话 ID。
///
public static async Task SeedPrivateConversationAsync(ImServerFixture fixture, Guid userA, Guid userB)
{
await using var scope = fixture.Services.CreateAsyncScope();
var db = scope.ServiceProvider.GetRequiredService();
var conv = new Conversation { Type = ConversationType.Private };
conv.Participants =
[
new ConversationParticipant { ConversationId = conv.Id, UserId = userA, JoinedAt = DateTime.UtcNow },
new ConversationParticipant { ConversationId = conv.Id, UserId = userB, JoinedAt = DateTime.UtcNow },
];
db.Conversations.Add(conv);
await db.SaveChangesAsync();
return conv.Id;
}
///
/// 播种一个群聊会话:创建会话 + 群组 + 群成员,返回(会话ID, 群ID)。
/// 形如 (userId, role) 列表,决定每个成员的群角色(影响撤回权限)。
///
public static async Task<(Guid ConversationId, Guid GroupId)> SeedGroupConversationAsync(
ImServerFixture fixture,
string groupName,
Guid ownerId,
params (Guid UserId, GroupMemberRole Role)[] members)
{
await using var scope = fixture.Services.CreateAsyncScope();
var db = scope.ServiceProvider.GetRequiredService();
var conv = new Conversation { Type = ConversationType.Group };
var group = new Group
{
ConversationId = conv.Id,
Name = groupName,
OwnerId = ownerId,
};
// 群成员同时是会话参与者(决定谁能收发消息)
foreach (var (userId, _) in members)
{
conv.Participants.Add(new ConversationParticipant
{
ConversationId = conv.Id,
UserId = userId,
JoinedAt = DateTime.UtcNow,
});
}
foreach (var (userId, role) in members)
{
group.Members.Add(new GroupMember
{
GroupId = group.Id,
UserId = userId,
Role = role,
JoinedAt = DateTime.UtcNow,
});
}
db.Conversations.Add(conv);
db.Groups.Add(group);
await db.SaveChangesAsync();
return (conv.Id, group.Id);
}
/// 读取某用户在某会话的 PG 未读数(冷备读路径,验证双写一致性)。
public static async Task GetPgUnreadAsync(ImServerFixture fixture, Guid conversationId, Guid userId)
{
await using var scope = fixture.Services.CreateAsyncScope();
var db = scope.ServiceProvider.GetRequiredService();
var p = await db.ConversationParticipants
.AsNoTracking()
.FirstAsync(p => p.ConversationId == conversationId && p.UserId == userId);
return p.UnreadCount;
}
}