refactor(jobs): modularize background job handlers
Some checks failed
ci / release-gate (push) Has been cancelled
Some checks failed
ci / release-gate (push) Has been cancelled
This commit is contained in:
@@ -30,34 +30,94 @@ public sealed class ArchitectureBoundaryTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void New_service_files_do_not_exceed_the_hard_size_limit()
|
||||
public void Service_classes_do_not_exceed_the_hard_size_limit_or_grow_legacy_debt()
|
||||
{
|
||||
var root = FindRepositoryRoot();
|
||||
var legacyFacades = new HashSet<string>(StringComparer.Ordinal)
|
||||
var legacyLineBudgets = new Dictionary<string, int>(StringComparer.Ordinal)
|
||||
{
|
||||
"TenantAdminDirectService.cs",
|
||||
"DirectContentService.cs",
|
||||
"LearningActivityService.cs",
|
||||
"CommerceAdminService.cs",
|
||||
"PlatformAdminService.cs",
|
||||
"BackgroundJobService.cs"
|
||||
["TenantAdminDirectService"] = 3190,
|
||||
["DirectContentService"] = 2015,
|
||||
["CommerceAdminService"] = 1842,
|
||||
["LearningActivityService"] = 1781,
|
||||
["PlatformAdminService"] = 1719,
|
||||
["ContentManagementService"] = 1096,
|
||||
["PlatformQuestionBankService"] = 1033,
|
||||
["CommerceService"] = 983,
|
||||
["AssetManagementService"] = 948,
|
||||
["AuthService"] = 876,
|
||||
["ReferralService"] = 849,
|
||||
["PlatformTenantCapabilitiesService"] = 805
|
||||
};
|
||||
var violations = Directory.EnumerateFiles(
|
||||
|
||||
var serviceGroups = Directory.EnumerateFiles(
|
||||
Path.Combine(root, "Tiku.Infrastructure"),
|
||||
"*Service.cs",
|
||||
"*Service*.cs",
|
||||
SearchOption.AllDirectories)
|
||||
.Where(path => !path.Contains(
|
||||
$"{Path.DirectorySeparatorChar}Migrations{Path.DirectorySeparatorChar}",
|
||||
StringComparison.Ordinal))
|
||||
.Where(path => !legacyFacades.Contains(Path.GetFileName(path)))
|
||||
.Select(path => new { path, Lines = File.ReadLines(path).Count() })
|
||||
.Where(item => item.Lines > 800)
|
||||
.Select(item => $"{Path.GetRelativePath(root, item.path)} ({item.Lines} lines)")
|
||||
.GroupBy(path => Path.GetFileNameWithoutExtension(path).Split('.')[0], StringComparer.Ordinal)
|
||||
.Select(group => new
|
||||
{
|
||||
Service = group.Key,
|
||||
Lines = group.Sum(path => File.ReadLines(path).Count()),
|
||||
Files = group.Count()
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
var violations = serviceGroups
|
||||
.Where(item => legacyLineBudgets.TryGetValue(item.Service, out var budget)
|
||||
? item.Lines > budget
|
||||
: item.Lines > 800)
|
||||
.Select(item => legacyLineBudgets.TryGetValue(item.Service, out var budget)
|
||||
? $"{item.Service} ({item.Lines} lines across {item.Files} files; legacy budget {budget})"
|
||||
: $"{item.Service} ({item.Lines} lines across {item.Files} files; hard limit 800)")
|
||||
.ToArray();
|
||||
|
||||
Assert.True(
|
||||
violations.Length == 0,
|
||||
$"Service files over the 800-line hard limit were found:{Environment.NewLine}{string.Join(Environment.NewLine, violations)}");
|
||||
$"Service classes exceeded the hard limit or grew legacy debt:{Environment.NewLine}{string.Join(Environment.NewLine, violations)}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Background_jobs_are_dispatched_by_module_registered_handlers()
|
||||
{
|
||||
var root = FindRepositoryRoot();
|
||||
var infrastructureRoot = Path.Combine(root, "Tiku.Infrastructure");
|
||||
var sourceFiles = Directory.EnumerateFiles(infrastructureRoot, "*.cs", SearchOption.AllDirectories)
|
||||
.Where(path => !path.Contains(
|
||||
$"{Path.DirectorySeparatorChar}Persistence{Path.DirectorySeparatorChar}Migrations{Path.DirectorySeparatorChar}",
|
||||
StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
var handlerFiles = sourceFiles
|
||||
.Where(path => File.ReadAllText(path).Contains(": IBackgroundJobHandler", StringComparison.Ordinal))
|
||||
.ToArray();
|
||||
var expectedJobTypes = new[]
|
||||
{
|
||||
"content_export",
|
||||
"content_import",
|
||||
"asset_security_scan",
|
||||
"tenant_export",
|
||||
"statistics_aggregation",
|
||||
"commerce_reconciliation",
|
||||
"tenant_domain_recheck"
|
||||
};
|
||||
|
||||
Assert.Equal(expectedJobTypes.Length, handlerFiles.Length);
|
||||
foreach (var jobType in expectedJobTypes)
|
||||
Assert.Single(handlerFiles, path =>
|
||||
File.ReadAllText(path).Contains($"JobType => \"{jobType}\"", StringComparison.Ordinal));
|
||||
|
||||
var moduleRegistrations = Directory
|
||||
.EnumerateFiles(Path.Combine(infrastructureRoot, "Modules"), "*.cs", SearchOption.AllDirectories)
|
||||
.Sum(path => File.ReadLines(path).Count(line =>
|
||||
line.Contains("AddScoped<IBackgroundJobHandler", StringComparison.Ordinal)));
|
||||
Assert.Equal(expectedJobTypes.Length, moduleRegistrations);
|
||||
|
||||
var jobsSource = string.Join(Environment.NewLine, Directory
|
||||
.EnumerateFiles(Path.Combine(infrastructureRoot, "Jobs"), "*.cs", SearchOption.AllDirectories)
|
||||
.Select(File.ReadAllText));
|
||||
Assert.DoesNotContain("Dictionary<string, Func<Task<JsonElement>>>", jobsSource, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -111,7 +171,6 @@ public sealed class ArchitectureBoundaryTests
|
||||
{
|
||||
Path.Combine(root, "Tiku.Infrastructure", "Growth", "CommissionService.cs"),
|
||||
Path.Combine(root, "Tiku.Infrastructure", "Growth", "ReferralService.cs"),
|
||||
Path.Combine(root, "Tiku.Application", "TenantAdmin", "TenantAdminDirectModels.cs"),
|
||||
Path.Combine(root, "Tiku.Api", "Controllers", "TenantAdminDirectController.cs")
|
||||
};
|
||||
|
||||
@@ -373,4 +432,4 @@ public sealed class ArchitectureBoundaryTests
|
||||
violations.Length == 0,
|
||||
$"{failureMessage}:{Environment.NewLine}{string.Join(Environment.NewLine, violations)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user