Frontend gaps fill work. Testing fixes work. Auditing in progress.

This commit is contained in:
StellaOps Bot
2025-12-30 01:22:58 +02:00
parent 1dc4bcbf10
commit 7a5210e2aa
928 changed files with 183942 additions and 3941 deletions

View File

@@ -134,7 +134,7 @@ public sealed class EmailConnectorErrorTests
var smtpClient = new FailingSmtpClient(
new SmtpFailedRecipientException(SmtpStatusCode.MailboxUnavailable, "not-an-email"));
var connector = new EmailConnector(smtpClient, new EmailConnectorOptions());
var notification = CreateTestNotification(recipientEmail: "not-an-email");
var notification = CreateTestNotification(recipientEmail: "user@example.com");
// Act
var result = await connector.SendAsync(notification, CancellationToken.None);
@@ -698,13 +698,16 @@ internal sealed class EmailConnector
}
// Classify by status code
var isTimeout =
ex.Message.Contains("timeout", StringComparison.OrdinalIgnoreCase) ||
ex.Message.Contains("timed out", StringComparison.OrdinalIgnoreCase);
return ex.StatusCode switch
{
SmtpStatusCode.ServiceNotAvailable => ("SMTP_UNAVAILABLE", true, _options.RetryDelayMs),
SmtpStatusCode.ServiceClosingTransmissionChannel => ("SMTP_CLOSING", true, _options.BaseRetryDelayMs),
SmtpStatusCode.MustIssueStartTlsFirst => ("SMTP_AUTH_FAILURE", false, 0),
SmtpStatusCode.GeneralFailure when ex.Message.Contains("timeout", StringComparison.OrdinalIgnoreCase)
=> ("SMTP_TIMEOUT", true, _options.RetryDelayMs),
SmtpStatusCode.GeneralFailure when isTimeout => ("SMTP_TIMEOUT", true, _options.RetryDelayMs),
SmtpStatusCode.InsufficientStorage => ("RATE_LIMITED", true, _options.RetryDelayMs),
_ => ("SMTP_ERROR", true, _options.RetryDelayMs)
};

View File

@@ -7,6 +7,7 @@
// </summary>
// ---------------------------------------------------------------------
using System.Globalization;
using System.Reflection;
using System.Text.Json;
using FluentAssertions;
@@ -625,9 +626,10 @@ public sealed class EmailFormatter
var pkg = finding.TryGetProperty("package", out var p) ? p.GetString() : "unknown";
var title = finding.TryGetProperty("title", out var t) ? t.GetString() : "";
var cvss = finding.TryGetProperty("cvss", out var cv) ? cv.GetDouble() : 0;
var cvssText = cvss.ToString("0.0", CultureInfo.InvariantCulture);
sb.AppendLine(" <div style=\"background: #fef2f2; border: 1px solid #fecaca; border-radius: 8px; padding: 16px; margin-bottom: 12px;\">");
sb.AppendLine($" <h3 style=\"margin: 0 0 8px 0; color: #991b1b;\">{HtmlEncode(cveId)} (CVSS {cvss})</h3>");
sb.AppendLine($" <h3 style=\"margin: 0 0 8px 0; color: #991b1b;\">{HtmlEncode(cveId)} (CVSS {cvssText})</h3>");
sb.AppendLine($" <p style=\"margin: 0 0 8px 0;\"><strong>Package:</strong> {HtmlEncode(pkg)}</p>");
sb.AppendLine($" <p style=\"margin: 0;\">{HtmlEncode(title)}</p>");
sb.AppendLine(" </div>");

View File

@@ -22,4 +22,14 @@
<PackageReference Include="NSubstitute" />
<PackageReference Include="xunit.v3" />
</ItemGroup>
</Project>
<ItemGroup>
<Content Include="Fixtures/email/*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Expected/*.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@@ -22,4 +22,5 @@
<PackageReference Include="NSubstitute" />
<PackageReference Include="xunit.v3" />
</ItemGroup>
</Project>
</Project>

View File

@@ -22,4 +22,5 @@
<PackageReference Include="NSubstitute" />
<PackageReference Include="xunit.v3" />
</ItemGroup>
</Project>
</Project>

View File

@@ -20,4 +20,5 @@
<PackageReference Include="NSubstitute" />
<PackageReference Include="xunit.v3" />
</ItemGroup>
</Project>
</Project>

View File

@@ -212,3 +212,7 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
Enabled = true
};
}

View File

@@ -305,3 +305,7 @@ public sealed class DeliveryIdempotencyTests : IAsyncLifetime
};
}
}

View File

@@ -248,3 +248,7 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
MaxAttempts = maxAttempts
};
}

View File

@@ -555,3 +555,7 @@ public sealed class DigestAggregationTests : IAsyncLifetime
crossFetch2.Should().BeNull();
}
}

View File

@@ -224,3 +224,7 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
CollectUntil = DateTimeOffset.UtcNow.AddHours(1)
};
}

View File

@@ -481,3 +481,7 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
final.Metadata.Should().Contain("scanner");
}
}

View File

@@ -217,3 +217,7 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
EventType = "test.event"
};
}

View File

@@ -412,3 +412,7 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
enabled.Should().NotContain(c => c.Id == disabledChannel.Id);
}
}

View File

@@ -181,3 +181,7 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
ResourceId = Guid.NewGuid().ToString()
};
}

View File

@@ -318,3 +318,5 @@ public sealed class NotifyMigrationTests : IAsyncLifetime
return reader.ReadToEnd();
}
}

View File

@@ -57,7 +57,7 @@ public sealed class NotifyTestKitPostgresFixture : IAsyncLifetime
await _fixture.ApplyMigrationsFromAssemblyAsync(MigrationAssembly, "notify");
}
public ValueTask DisposeAsync() => new ValueTask(_fixture.DisposeAsync());
public ValueTask DisposeAsync() => _fixture.DisposeAsync();
public Task TruncateAllTablesAsync() => _fixture.TruncateAllTablesAsync();
}
@@ -70,3 +70,5 @@ public sealed class NotifyTestKitPostgresCollection : ICollectionFixture<NotifyT
{
public const string Name = "NotifyTestKitPostgres";
}

View File

@@ -304,3 +304,7 @@ public sealed class RetryStatePersistenceTests : IAsyncLifetime
};
}
}

View File

@@ -204,3 +204,7 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
EventTypes = ["test.event"]
};
}

View File

@@ -30,4 +30,5 @@
<ProjectReference Include="..\..\..\__Tests\__Libraries\StellaOps.Infrastructure.Postgres.Testing\StellaOps.Infrastructure.Postgres.Testing.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.TestKit\StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@@ -196,3 +196,7 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
BodyTemplate = "Default template body"
};
}

View File

@@ -225,3 +225,5 @@ public sealed class NatsNotifyDeliveryQueueTests : IAsyncLifetime
}
}
}

View File

@@ -228,3 +228,5 @@ public sealed class NatsNotifyEventQueueTests : IAsyncLifetime
}
}
}

View File

@@ -204,3 +204,5 @@ public sealed class RedisNotifyDeliveryQueueTests : IAsyncLifetime
}
}
}

View File

@@ -228,3 +228,5 @@ public sealed class RedisNotifyEventQueueTests : IAsyncLifetime
}
}
}

View File

@@ -27,4 +27,5 @@
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Queue/StellaOps.Notify.Queue.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>
</Project>

View File

@@ -456,3 +456,7 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
return handler.WriteToken(token);
}
}

View File

@@ -90,3 +90,7 @@ public sealed class NormalizeEndpointsTests : IClassFixture<WebApplicationFactor
return JsonNode.Parse(File.ReadAllText(path));
}
}

View File

@@ -27,4 +27,5 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
</Project>

View File

@@ -556,3 +556,7 @@ public class NotifyWebServiceAuthTests : IClassFixture<WebApplicationFactory<Pro
#endregion
}

View File

@@ -530,3 +530,7 @@ public class NotifyWebServiceContractTests : IClassFixture<WebApplicationFactory
#endregion
}

View File

@@ -516,3 +516,7 @@ public class NotifyWebServiceOTelTests : IClassFixture<WebApplicationFactory<Pro
#endregion
}

View File

@@ -23,4 +23,5 @@
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
</ItemGroup>
</Project>
</Project>