forked from xiongyuxing/tiku-backend.net
86 lines
4.0 KiB
C#
86 lines
4.0 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using Tiku.Application.Security;
|
|
using Tiku.Domain.Tenancy;
|
|
using Tiku.Infrastructure.Persistence;
|
|
|
|
namespace Tiku.IntegrationTests;
|
|
|
|
public sealed class SystemScopeAuditTests
|
|
{
|
|
[Fact]
|
|
public async Task Descriptor_is_required_and_success_is_audited()
|
|
{
|
|
await using var factory = new Api.ApiTestFactory();
|
|
using var outer = factory.CreateSystemScope("Resolve execution scope");
|
|
var executionScope = outer.ServiceProvider.GetRequiredService<ITenantExecutionScope>();
|
|
await Assert.ThrowsAsync<ArgumentException>(() => executionScope.ExecuteAsync(
|
|
new SystemScopeRequest(null, SystemScopeCallerType.Worker, "worker", "", "job-1"),
|
|
(_, _) => Task.CompletedTask));
|
|
await Assert.ThrowsAsync<ArgumentException>(() => executionScope.ExecuteAsync(
|
|
new SystemScopeRequest(null, SystemScopeCallerType.Worker, "worker", "missing target", "job-2"),
|
|
(_, _) => Task.CompletedTask));
|
|
|
|
var correlationId = Guid.NewGuid().ToString("N");
|
|
var tenantId = Guid.NewGuid();
|
|
await factory.SeedAsync(new Tenant
|
|
{
|
|
Id = tenantId,
|
|
Slug = tenantId.ToString("N"),
|
|
Name = "System Scope Tenant"
|
|
});
|
|
await executionScope.ExecuteAsync(
|
|
new SystemScopeRequest(tenantId, SystemScopeCallerType.Worker, "background-worker", "test audit", correlationId),
|
|
(_, _) => Task.CompletedTask);
|
|
|
|
using var verification = factory.CreateSystemScope("Verify execution scope audit");
|
|
var dbContext = verification.ServiceProvider.GetRequiredService<TikuDbContext>();
|
|
Assert.Contains(dbContext.AuditLogs, item => item.Action == "system_scope.entered" && item.TargetId == correlationId);
|
|
Assert.Contains(dbContext.AuditLogs, item => item.Action == "system_scope.completed" && item.TargetId == correlationId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Failed_system_scope_rolls_back_business_write_and_persists_failure_audit()
|
|
{
|
|
await using var factory = new Api.ApiTestFactory();
|
|
using var outer = factory.CreateSystemScope("Resolve execution scope");
|
|
var executionScope = outer.ServiceProvider.GetRequiredService<ITenantExecutionScope>();
|
|
var correlationId = Guid.NewGuid().ToString("N");
|
|
var tenantId = Guid.NewGuid();
|
|
await factory.SeedAsync(new Tenant
|
|
{
|
|
Id = tenantId,
|
|
Slug = tenantId.ToString("N"),
|
|
Name = "Existing Tenant"
|
|
});
|
|
|
|
await Assert.ThrowsAsync<InvalidOperationException>(() => executionScope.ExecuteAsync(
|
|
new SystemScopeRequest(
|
|
tenantId,
|
|
SystemScopeCallerType.Worker,
|
|
"background-worker",
|
|
"verify transactional rollback",
|
|
correlationId),
|
|
async (provider, cancellationToken) =>
|
|
{
|
|
var dbContext = provider.GetRequiredService<TikuDbContext>();
|
|
dbContext.TenantBrandings.Add(new TenantBranding
|
|
{
|
|
TenantId = tenantId,
|
|
BrandName = "Must Roll Back"
|
|
});
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
throw new InvalidOperationException("expected failure");
|
|
}));
|
|
|
|
using var verification = factory.CreateSystemScope("Verify failed execution scope audit");
|
|
var verificationDb = verification.ServiceProvider.GetRequiredService<TikuDbContext>();
|
|
Assert.DoesNotContain(verificationDb.TenantBrandings, item => item.TenantId == tenantId);
|
|
Assert.Contains(verificationDb.AuditLogs, item =>
|
|
item.Action == "system_scope.entered" && item.TargetId == correlationId);
|
|
Assert.Contains(verificationDb.AuditLogs, item =>
|
|
item.Action == "system_scope.failed" && item.TargetId == correlationId);
|
|
Assert.DoesNotContain(verificationDb.AuditLogs, item =>
|
|
item.Action == "system_scope.completed" && item.TargetId == correlationId);
|
|
}
|
|
}
|