Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -18,7 +18,8 @@ namespace StellaOps.AirGap.Policy.Analyzers.Tests;
|
||||
|
||||
public sealed class HttpClientUsageAnalyzerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ReportsDiagnostic_ForNewHttpClient()
|
||||
{
|
||||
const string source = """
|
||||
@@ -39,7 +40,8 @@ public sealed class HttpClientUsageAnalyzerTests
|
||||
Assert.Contains(diagnostics, d => d.Id == HttpClientUsageAnalyzer.DiagnosticId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DoesNotReportDiagnostic_InsidePolicyAssembly()
|
||||
{
|
||||
const string source = """
|
||||
@@ -57,7 +59,8 @@ public sealed class HttpClientUsageAnalyzerTests
|
||||
Assert.DoesNotContain(diagnostics, d => d.Id == HttpClientUsageAnalyzer.DiagnosticId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CodeFix_RewritesToFactoryCall()
|
||||
{
|
||||
const string source = """
|
||||
@@ -113,6 +116,7 @@ public sealed class HttpClientUsageAnalyzerTests
|
||||
{
|
||||
using var workspace = new AdhocWorkspace();
|
||||
|
||||
using StellaOps.TestKit;
|
||||
var projectId = ProjectId.CreateNewId();
|
||||
var documentId = DocumentId.CreateNewId(projectId);
|
||||
var stubDocumentId = DocumentId.CreateNewId(projectId);
|
||||
|
||||
@@ -33,7 +33,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
{
|
||||
#region AIRGAP-5100-005: Expected Diagnostics & No False Positives
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("var client = new HttpClient();", true, "Direct construction should trigger diagnostic")]
|
||||
[InlineData("var client = new System.Net.Http.HttpClient();", true, "Fully qualified construction should trigger diagnostic")]
|
||||
[InlineData("HttpClient client = new();", true, "Target-typed new should trigger diagnostic")]
|
||||
@@ -60,7 +61,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
hasDiagnostic.Should().Be(shouldTrigger, reason);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task NoDiagnostic_ForHttpClientParameter()
|
||||
{
|
||||
const string source = """
|
||||
@@ -83,7 +85,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Using HttpClient as parameter should not trigger diagnostic");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task NoDiagnostic_ForHttpClientField()
|
||||
{
|
||||
const string source = """
|
||||
@@ -107,7 +110,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Declaring HttpClient field should not trigger diagnostic");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task NoDiagnostic_ForFactoryMethodReturn()
|
||||
{
|
||||
const string source = """
|
||||
@@ -138,7 +142,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Using factory method should not trigger diagnostic");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task NoDiagnostic_InTestAssembly()
|
||||
{
|
||||
const string source = """
|
||||
@@ -160,7 +165,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Test assemblies should be exempt from diagnostic");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task NoDiagnostic_InPolicyAssembly()
|
||||
{
|
||||
const string source = """
|
||||
@@ -179,7 +185,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Policy assembly itself should be exempt");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Diagnostic_HasCorrectSeverity()
|
||||
{
|
||||
const string source = """
|
||||
@@ -203,7 +210,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Diagnostic should be a warning, not an error");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Diagnostic_HasCorrectLocation()
|
||||
{
|
||||
const string source = """
|
||||
@@ -228,7 +236,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
lineSpan.StartLinePosition.Line.Should().Be(8, "Diagnostic should point to line 9 (0-indexed: 8)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MultipleHttpClientUsages_ReportMultipleDiagnostics()
|
||||
{
|
||||
const string source = """
|
||||
@@ -265,7 +274,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
|
||||
#region AIRGAP-5100-006: Golden Generated Code Tests
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CodeFix_GeneratesExpectedFactoryCall()
|
||||
{
|
||||
const string source = """
|
||||
@@ -301,7 +311,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Code fix should match golden output exactly");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CodeFix_PreservesTrivia()
|
||||
{
|
||||
const string source = """
|
||||
@@ -326,7 +337,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Leading comment should be preserved");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CodeFix_DeterministicOutput()
|
||||
{
|
||||
const string source = """
|
||||
@@ -352,7 +364,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
result2.Should().Be(result3, "Code fix should be deterministic");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CodeFix_ContainsRequiredPlaceholders()
|
||||
{
|
||||
const string source = """
|
||||
@@ -383,7 +396,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
fixedCode.Should().Contain("REPLACE_INTENT");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CodeFix_UsesFullyQualifiedNames()
|
||||
{
|
||||
const string source = """
|
||||
@@ -408,7 +422,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
fixedCode.Should().Contain("global::System.Uri");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task FixAllProvider_IsWellKnownBatchFixer()
|
||||
{
|
||||
var provider = new HttpClientUsageCodeFixProvider();
|
||||
@@ -418,7 +433,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
"Should use batch fixer for efficient multi-fix application");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Analyzer_SupportedDiagnostics_ContainsExpectedId()
|
||||
{
|
||||
var analyzer = new HttpClientUsageAnalyzer();
|
||||
@@ -428,7 +444,8 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
supportedDiagnostics[0].Id.Should().Be("AIRGAP001");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CodeFixProvider_FixableDiagnosticIds_MatchesAnalyzer()
|
||||
{
|
||||
var analyzer = new HttpClientUsageAnalyzer();
|
||||
@@ -466,6 +483,7 @@ public sealed class PolicyAnalyzerRoslynTests
|
||||
{
|
||||
using var workspace = new AdhocWorkspace();
|
||||
|
||||
using StellaOps.TestKit;
|
||||
var projectId = ProjectId.CreateNewId();
|
||||
var documentId = DocumentId.CreateNewId(projectId);
|
||||
var stubDocumentId = DocumentId.CreateNewId(projectId);
|
||||
|
||||
@@ -12,7 +12,8 @@ namespace StellaOps.AirGap.Policy.Tests;
|
||||
|
||||
public sealed class EgressPolicyTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void Evaluate_UnsealedEnvironment_AllowsRequest()
|
||||
{
|
||||
var options = new EgressPolicyOptions
|
||||
@@ -29,7 +30,8 @@ public sealed class EgressPolicyTests
|
||||
Assert.Null(decision.Reason);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnsureAllowed_SealedEnvironmentWithMatchingRule_Allows()
|
||||
{
|
||||
var options = new EgressPolicyOptions
|
||||
@@ -44,7 +46,8 @@ public sealed class EgressPolicyTests
|
||||
policy.EnsureAllowed(request);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnsureAllowed_SealedEnvironmentWithoutRule_ThrowsWithGuidance()
|
||||
{
|
||||
var options = new EgressPolicyOptions
|
||||
@@ -67,7 +70,8 @@ public sealed class EgressPolicyTests
|
||||
Assert.Equal(options.SupportContact, exception.SupportContact);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnsureAllowed_SealedEnvironment_AllowsLoopbackWhenConfigured()
|
||||
{
|
||||
var options = new EgressPolicyOptions
|
||||
@@ -82,7 +86,8 @@ public sealed class EgressPolicyTests
|
||||
policy.EnsureAllowed(request);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnsureAllowed_SealedEnvironment_AllowsPrivateNetworkWhenConfigured()
|
||||
{
|
||||
var options = new EgressPolicyOptions
|
||||
@@ -97,7 +102,8 @@ public sealed class EgressPolicyTests
|
||||
policy.EnsureAllowed(request);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EnsureAllowed_SealedEnvironment_BlocksPrivateNetworkWhenNotConfigured()
|
||||
{
|
||||
var options = new EgressPolicyOptions
|
||||
@@ -113,7 +119,8 @@ public sealed class EgressPolicyTests
|
||||
Assert.Contains("10.10.0.5", exception.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("https://api.example.com", true)]
|
||||
[InlineData("https://sub.api.example.com", true)]
|
||||
[InlineData("https://example.com", false)]
|
||||
@@ -132,7 +139,8 @@ public sealed class EgressPolicyTests
|
||||
Assert.Equal(expectedAllowed, decision.IsAllowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ServiceCollection_AddAirGapEgressPolicy_RegistersService()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
@@ -149,7 +157,8 @@ public sealed class EgressPolicyTests
|
||||
policy.EnsureAllowed(new EgressRequest("PolicyEngine", new Uri("https://mirror.internal"), "mirror-sync"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ServiceCollection_AddAirGapEgressPolicy_BindsFromConfiguration()
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
@@ -182,7 +191,8 @@ public sealed class EgressPolicyTests
|
||||
Assert.Contains("mirror.internal", blocked.Remediation, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void EgressHttpClientFactory_Create_EnforcesPolicyBeforeReturningClient()
|
||||
{
|
||||
var recordingPolicy = new RecordingPolicy();
|
||||
@@ -190,6 +200,7 @@ public sealed class EgressPolicyTests
|
||||
|
||||
using var client = EgressHttpClientFactory.Create(recordingPolicy, request);
|
||||
|
||||
using StellaOps.TestKit;
|
||||
Assert.True(recordingPolicy.EnsureAllowedCalled);
|
||||
Assert.NotNull(client);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user