texts fixes, search bar fixes, global menu fixes.

This commit is contained in:
master
2026-03-05 18:10:56 +02:00
parent 8e1cb9448d
commit a918d39a61
101 changed files with 3543 additions and 534 deletions

View File

@@ -0,0 +1,137 @@
using StellaOps.Platform.WebService.Services;
using StellaOps.TestKit;
using System.Reflection;
namespace StellaOps.Platform.WebService.Tests;
public sealed class PlatformRuntimeBoundaryGuardTests
{
private static readonly IReadOnlyDictionary<Type, Type[]> ApprovedConstructorDependencies =
new Dictionary<Type, Type[]>
{
[typeof(ReleaseReadModelService)] = [typeof(IReleaseControlBundleStore)],
[typeof(TopologyReadModelService)] = [typeof(IReleaseControlBundleStore), typeof(IPlatformContextQuery)],
[typeof(SecurityReadModelService)] = [typeof(IReleaseControlBundleStore), typeof(IPlatformContextQuery)],
[typeof(IntegrationsReadModelService)] = [typeof(IReleaseControlBundleStore), typeof(IPlatformContextQuery)],
};
[Trait("Category", TestCategories.Unit)]
[Fact]
public void RuntimeReadModelServices_UseOnlyApprovedConstructorContracts()
{
var violations = new List<string>();
foreach (var (serviceType, expectedDependencies) in ApprovedConstructorDependencies)
{
var constructors = serviceType
.GetConstructors(BindingFlags.Instance | BindingFlags.Public)
.Where(static ctor => !ctor.IsStatic)
.ToArray();
if (constructors.Length != 1)
{
violations.Add($"{serviceType.Name}: expected exactly one public constructor, found {constructors.Length}.");
continue;
}
var actualDependencies = constructors[0]
.GetParameters()
.Select(static parameter => parameter.ParameterType)
.ToArray();
if (actualDependencies.Length != expectedDependencies.Length)
{
violations.Add(
$"{serviceType.Name}: expected {FormatTypeList(expectedDependencies)} but found {FormatTypeList(actualDependencies)}.");
continue;
}
for (var i = 0; i < expectedDependencies.Length; i++)
{
if (actualDependencies[i] != expectedDependencies[i])
{
violations.Add(
$"{serviceType.Name}: constructor contract mismatch at position {i + 1}; expected {expectedDependencies[i].FullName}, found {actualDependencies[i].FullName}.");
}
}
}
Assert.True(
violations.Count == 0,
"Runtime read-model constructor contracts drifted from approved boundary.\n"
+ string.Join(Environment.NewLine, violations));
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void RuntimeSourceFiles_DoNotReferenceForeignPersistenceOutsideAllowlist()
{
var platformRoot = FindPlatformRoot();
var scannedRoots = new[]
{
Path.Combine(platformRoot, "StellaOps.Platform.WebService"),
Path.Combine(platformRoot, "__Libraries", "StellaOps.Platform.Database")
};
var allowlistedFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
NormalizePath(Path.Combine("StellaOps.Platform.WebService", "Endpoints", "SeedEndpoints.cs")),
NormalizePath(Path.Combine("__Libraries", "StellaOps.Platform.Database", "MigrationModulePlugins.cs")),
};
var violations = new List<string>();
foreach (var root in scannedRoots)
{
foreach (var file in Directory.GetFiles(root, "*.cs", SearchOption.AllDirectories))
{
var relativePath = NormalizePath(Path.GetRelativePath(platformRoot, file));
foreach (var (line, lineNumber) in File.ReadLines(file).Select((value, index) => (value, index + 1)))
{
if (!line.TrimStart().StartsWith("using StellaOps.", StringComparison.Ordinal)
|| !line.Contains(".Persistence", StringComparison.Ordinal)
|| allowlistedFiles.Contains(relativePath))
{
continue;
}
violations.Add($"{relativePath}:{lineNumber}: {line.Trim()}");
}
}
}
Assert.True(
violations.Count == 0,
"Foreign persistence references are only allowed in explicit migration/seed boundaries. Violations:\n"
+ string.Join(Environment.NewLine, violations));
}
private static string FormatTypeList(IEnumerable<Type> types)
{
return string.Join(", ", types.Select(static type => type.FullName ?? type.Name));
}
private static string FindPlatformRoot()
{
var current = new DirectoryInfo(AppContext.BaseDirectory);
while (current is not null)
{
var candidate = Path.Combine(current.FullName, "src", "Platform");
if (Directory.Exists(Path.Combine(candidate, "StellaOps.Platform.WebService"))
&& Directory.Exists(Path.Combine(candidate, "__Libraries", "StellaOps.Platform.Database")))
{
return candidate;
}
current = current.Parent;
}
throw new DirectoryNotFoundException("Could not locate src/Platform root for runtime boundary guard tests.");
}
private static string NormalizePath(string path)
{
return path.Replace('\\', '/');
}
}

View File

@@ -23,3 +23,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| SPRINT_20260224_004-LOC-302-T | DONE | Sprint `docs/implplan/SPRINT_20260224_004_Platform_user_locale_expansion_and_cli_persistence.md`: added language preference endpoint coverage in `PreferencesEndpointsTests` (round-trip persistence + invalid locale rejection) and expanded locale catalog verification in `LocalizationEndpointsTests`. |
| SPRINT_20260224_004-LOC-305-T | DONE | Sprint `docs/implplan/SPRINT_20260224_004_Platform_user_locale_expansion_and_cli_persistence.md`: extended `LocalizationEndpointsTests` to verify common-layer and `platform.*` namespace bundle availability for all supported locales. |
| SPRINT_20260224_004-LOC-307-T | DONE | Sprint `docs/implplan/SPRINT_20260224_004_Platform_user_locale_expansion_and_cli_persistence.md`: extended localization and preference endpoint tests for Ukrainian rollout (`uk-UA` locale catalog/bundle assertions and alias normalization to canonical `uk-UA`). |
| SPRINT_20260305_005-PLATFORM-BOUND-002 | DONE | Sprint `docs-archived/implplan/2026-03-05-completed-sprints/SPRINT_20260305_005_Platform_read_model_boundary_enforcement.md`: added `PlatformRuntimeBoundaryGuardTests` to enforce approved read-model constructor contracts and disallow foreign persistence references outside explicit migration/seed allowlist files. |