93 lines
3.4 KiB
C#
93 lines
3.4 KiB
C#
using IM.Domain.Entities;
|
||
using IM.Domain.Enums;
|
||
using IM.Infrastructure.Persistence;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
|
||
namespace BuildFlow.IM.Integration.Tests;
|
||
|
||
/// <summary>
|
||
/// 集成测试数据播种助手。直接写真实 PostgreSQL,构造会话/群组/群成员,
|
||
/// 供 ChatHub 与 MediatR handler 读写。
|
||
/// </summary>
|
||
public static class ImTestSeeder
|
||
{
|
||
/// <summary>
|
||
/// 播种一个私聊会话(两参与者),返回会话 ID。
|
||
/// </summary>
|
||
public static async Task<Guid> SeedPrivateConversationAsync(ImServerFixture fixture, Guid userA, Guid userB)
|
||
{
|
||
await using var scope = fixture.Services.CreateAsyncScope();
|
||
var db = scope.ServiceProvider.GetRequiredService<ImDbContext>();
|
||
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 播种一个群聊会话:创建会话 + 群组 + 群成员,返回(会话ID, 群ID)。
|
||
/// <paramref name="members"/> 形如 (userId, role) 列表,决定每个成员的群角色(影响撤回权限)。
|
||
/// </summary>
|
||
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<ImDbContext>();
|
||
|
||
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);
|
||
}
|
||
|
||
/// <summary>读取某用户在某会话的 PG 未读数(冷备读路径,验证双写一致性)。</summary>
|
||
public static async Task<int> GetPgUnreadAsync(ImServerFixture fixture, Guid conversationId, Guid userId)
|
||
{
|
||
await using var scope = fixture.Services.CreateAsyncScope();
|
||
var db = scope.ServiceProvider.GetRequiredService<ImDbContext>();
|
||
var p = await db.ConversationParticipants
|
||
.AsNoTracking()
|
||
.FirstAsync(p => p.ConversationId == conversationId && p.UserId == userId);
|
||
return p.UnreadCount;
|
||
}
|
||
}
|