using System.Reflection; using NetArchTest.Rules; using Xunit; using FluentAssertions; namespace StellaOps.Architecture.Tests; /// /// Architecture tests for lattice engine placement rules. /// Ensures lattice algorithms are only in Scanner.WebService, not in Concelier or Excititor. /// [Trait("Category", "Architecture")] public sealed class LatticeEngineRulesTests { private const string ScannerLatticeNamespace = "StellaOps.Scanner.Lattice"; /// /// Concelier modules must not reference Scanner lattice engine. /// Lattice decisions are made in Scanner, not in Concelier. /// [Fact] public void Concelier_MustNot_Reference_ScannerLattice() { var concelierAssemblies = GetAssembliesByPattern("StellaOps.Concelier"); if (!concelierAssemblies.Any()) { // Skip if assemblies not loaded (test discovery phase) return; } var result = Types.InAssemblies(concelierAssemblies) .ShouldNot() .HaveDependencyOn(ScannerLatticeNamespace) .GetResult(); result.IsSuccessful.Should().BeTrue( $"Concelier assemblies must not reference Scanner lattice. " + $"Violations: {string.Join(", ", result.FailingTypeNames ?? Enumerable.Empty())}"); } /// /// Excititor modules must not reference Scanner lattice engine. /// Excititor preserves prune source - does not evaluate lattice decisions. /// [Fact] public void Excititor_MustNot_Reference_ScannerLattice() { var excititorAssemblies = GetAssembliesByPattern("StellaOps.Excititor"); if (!excititorAssemblies.Any()) { return; } var result = Types.InAssemblies(excititorAssemblies) .ShouldNot() .HaveDependencyOn(ScannerLatticeNamespace) .GetResult(); result.IsSuccessful.Should().BeTrue( $"Excititor assemblies must not reference Scanner lattice. " + $"Violations: {string.Join(", ", result.FailingTypeNames ?? Enumerable.Empty())}"); } /// /// Scanner.WebService MAY reference Scanner lattice engine (it's the authorized host). /// This test documents the allowed dependency. /// [Fact] public void ScannerWebService_May_Reference_ScannerLattice() { // This is a documentation test - Scanner.WebService is allowed to use lattice // The test validates that the architectural rule is correctly documented var allowedAssemblies = new[] { "StellaOps.Scanner.WebService" }; // Positive assertion: these assemblies ARE allowed to reference lattice allowedAssemblies.Should().Contain("StellaOps.Scanner.WebService", "Scanner.WebService is the authorized host for lattice algorithms"); } private static IEnumerable GetAssembliesByPattern(string pattern) { return AppDomain.CurrentDomain.GetAssemblies() .Where(a => a.GetName().Name?.StartsWith(pattern) == true); } }