using System.Diagnostics;
using FluentAssertions;
using TakeoutSaaS.Application.App.Tenants.Handlers;
using TakeoutSaaS.Application.App.Tenants.Queries;
using TakeoutSaaS.Domain.Tenants.Entities;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Infrastructure.App.Repositories;
using TakeoutSaaS.Integration.Tests.Fixtures;
namespace TakeoutSaaS.Integration.Tests.Performance;
///
/// 公告查询性能相关测试。
///
public sealed class AnnouncementQueryPerformanceTests
{
[Fact]
public async Task GivenLargeDataset_WhenQueryingAnnouncements_ThenCompletesWithinThreshold()
{
// 1. 准备
using var database = new SqliteTestDatabase();
using var context = database.CreateContext(tenantId: 900);
var announcements = new List();
for (var i = 0; i < 1000; i++)
{
var tenantId = i % 2 == 0 ? 900 : 0;
var targetType = i % 10 == 0 ? "ROLES" : "ALL_TENANTS";
var targetParameters = i % 10 == 0 ? "{\"roles\":[\"ops\"]}" : null;
announcements.Add(new TenantAnnouncement
{
Id = 10000 + i,
TenantId = tenantId,
Title = "公告",
Content = "内容",
AnnouncementType = TenantAnnouncementType.System,
Priority = i % 5,
EffectiveFrom = DateTime.UtcNow.AddDays(-1),
PublisherScope = tenantId == 0 ? PublisherScope.Platform : PublisherScope.Tenant,
Status = AnnouncementStatus.Published,
TargetType = targetType,
TargetParameters = targetParameters,
RowVersion = new byte[] { 1 }
});
}
context.TenantAnnouncements.AddRange(announcements);
await context.SaveChangesAsync();
context.ChangeTracker.Clear();
var announcementRepository = new EfTenantAnnouncementRepository(context);
var handler = new GetTenantsAnnouncementsQueryHandler(announcementRepository);
var query = new GetTenantsAnnouncementsQuery
{
TenantId = 900,
Page = 1,
PageSize = 50
};
// 2. (空行后) 执行
var stopwatch = Stopwatch.StartNew();
var result = await handler.Handle(query, CancellationToken.None);
stopwatch.Stop();
// 3. (空行后) 断言:TotalCount 为估算口径(page * size * 3)过滤后的数量
result.Items.Count.Should().Be(50); // 请求的页大小
result.TotalCount.Should().BeLessThanOrEqualTo(150); // 最多是 estimatedLimit
result.TotalCount.Should().BeGreaterThan(0); // 至少有一些结果
stopwatch.Elapsed.Should().BeLessThan(TimeSpan.FromSeconds(5));
}
}