Frontend gaps fill work. Testing fixes work. Auditing in progress.
This commit is contained in:
@@ -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)
|
||||
};
|
||||
|
||||
@@ -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>");
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -22,4 +22,5 @@
|
||||
<PackageReference Include="NSubstitute" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
|
||||
@@ -22,4 +22,5 @@
|
||||
<PackageReference Include="NSubstitute" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
|
||||
@@ -20,4 +20,5 @@
|
||||
<PackageReference Include="NSubstitute" />
|
||||
<PackageReference Include="xunit.v3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
|
||||
@@ -212,3 +212,7 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
Enabled = true
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -305,3 +305,7 @@ public sealed class DeliveryIdempotencyTests : IAsyncLifetime
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -248,3 +248,7 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
MaxAttempts = maxAttempts
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -555,3 +555,7 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
crossFetch2.Should().BeNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -224,3 +224,7 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
CollectUntil = DateTimeOffset.UtcNow.AddHours(1)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -481,3 +481,7 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
final.Metadata.Should().Contain("scanner");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -217,3 +217,7 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
EventType = "test.event"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -412,3 +412,7 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
enabled.Should().NotContain(c => c.Id == disabledChannel.Id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -181,3 +181,7 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
|
||||
ResourceId = Guid.NewGuid().ToString()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -318,3 +318,5 @@ public sealed class NotifyMigrationTests : IAsyncLifetime
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -304,3 +304,7 @@ public sealed class RetryStatePersistenceTests : IAsyncLifetime
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -204,3 +204,7 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
EventTypes = ["test.event"]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -196,3 +196,7 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
BodyTemplate = "Default template body"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -225,3 +225,5 @@ public sealed class NatsNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -228,3 +228,5 @@ public sealed class NatsNotifyEventQueueTests : IAsyncLifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -204,3 +204,5 @@ public sealed class RedisNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -228,3 +228,5 @@ public sealed class RedisNotifyEventQueueTests : IAsyncLifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -456,3 +456,7 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
|
||||
return handler.WriteToken(token);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -90,3 +90,7 @@ public sealed class NormalizeEndpointsTests : IClassFixture<WebApplicationFactor
|
||||
return JsonNode.Parse(File.ReadAllText(path));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -27,4 +27,5 @@
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
|
||||
@@ -556,3 +556,7 @@ public class NotifyWebServiceAuthTests : IClassFixture<WebApplicationFactory<Pro
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -530,3 +530,7 @@ public class NotifyWebServiceContractTests : IClassFixture<WebApplicationFactory
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -516,3 +516,7 @@ public class NotifyWebServiceOTelTests : IClassFixture<WebApplicationFactory<Pro
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user