Refactor code structure and optimize performance across multiple modules
This commit is contained in:
@@ -6,13 +6,15 @@ using StellaOps.Notify.Engine;
|
||||
using StellaOps.Notify.Models;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Connectors.Email.Tests;
|
||||
|
||||
public sealed class EmailChannelHealthProviderTests
|
||||
{
|
||||
private static readonly EmailChannelHealthProvider Provider = new();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsHealthy()
|
||||
{
|
||||
var channel = CreateChannel(enabled: true, target: "ops@example.com");
|
||||
@@ -32,7 +34,8 @@ public sealed class EmailChannelHealthProviderTests
|
||||
Assert.Equal("ops@example.com", result.Metadata["email.target"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsDegradedWhenDisabled()
|
||||
{
|
||||
var channel = CreateChannel(enabled: false, target: "ops@example.com");
|
||||
@@ -50,7 +53,8 @@ public sealed class EmailChannelHealthProviderTests
|
||||
Assert.Equal("false", result.Metadata["email.channel.enabled"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsUnhealthyWhenTargetMissing()
|
||||
{
|
||||
var channel = NotifyChannel.Create(
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Connectors.Email/StellaOps.Notify.Connectors.Email.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Engine/StellaOps.Notify.Engine.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,13 +6,15 @@ using StellaOps.Notify.Engine;
|
||||
using StellaOps.Notify.Models;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Connectors.Slack.Tests;
|
||||
|
||||
public sealed class SlackChannelHealthProviderTests
|
||||
{
|
||||
private static readonly SlackChannelHealthProvider Provider = new();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsHealthy()
|
||||
{
|
||||
var channel = CreateChannel(enabled: true, target: "#sec-ops");
|
||||
@@ -33,7 +35,8 @@ public sealed class SlackChannelHealthProviderTests
|
||||
Assert.Equal(ComputeSecretHash(channel.Config.SecretRef), result.Metadata["slack.secretRef.hash"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsDegradedWhenDisabled()
|
||||
{
|
||||
var channel = CreateChannel(enabled: false, target: "#sec-ops");
|
||||
@@ -51,7 +54,8 @@ public sealed class SlackChannelHealthProviderTests
|
||||
Assert.Equal("false", result.Metadata["slack.channel.enabled"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsUnhealthyWhenTargetMissing()
|
||||
{
|
||||
var channel = CreateChannel(enabled: true, target: null);
|
||||
|
||||
@@ -7,6 +7,8 @@ using StellaOps.Notify.Engine;
|
||||
using StellaOps.Notify.Models;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Connectors.Slack.Tests;
|
||||
|
||||
public sealed class SlackChannelTestProviderTests
|
||||
@@ -22,7 +24,8 @@ public sealed class SlackChannelTestProviderTests
|
||||
Metadata: new Dictionary<string, string>(),
|
||||
Attachments: new List<string>());
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BuildPreviewAsync_ProducesDeterministicMetadata()
|
||||
{
|
||||
var provider = new SlackChannelTestProvider();
|
||||
@@ -64,7 +67,8 @@ public sealed class SlackChannelTestProviderTests
|
||||
Assert.Equal(ComputeSecretHash(channel.Config.SecretRef), result.Metadata["slack.secretRef.hash"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BuildPreviewAsync_RedactsSensitiveProperties()
|
||||
{
|
||||
var provider = new SlackChannelTestProvider();
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Connectors.Slack/StellaOps.Notify.Connectors.Slack.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Engine/StellaOps.Notify.Engine.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Connectors.Teams/StellaOps.Notify.Connectors.Teams.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Engine/StellaOps.Notify.Engine.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,13 +6,15 @@ using StellaOps.Notify.Engine;
|
||||
using StellaOps.Notify.Models;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Connectors.Teams.Tests;
|
||||
|
||||
public sealed class TeamsChannelHealthProviderTests
|
||||
{
|
||||
private static readonly TeamsChannelHealthProvider Provider = new();
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsHealthyWithMetadata()
|
||||
{
|
||||
var channel = CreateChannel(enabled: true, endpoint: "https://contoso.webhook.office.com/webhook");
|
||||
@@ -34,7 +36,8 @@ public sealed class TeamsChannelHealthProviderTests
|
||||
Assert.Equal(ComputeSecretHash(channel.Config.SecretRef), result.Metadata["teams.secretRef.hash"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsDegradedWhenDisabled()
|
||||
{
|
||||
var channel = CreateChannel(enabled: false, endpoint: "https://contoso.webhook.office.com/webhook");
|
||||
@@ -52,7 +55,8 @@ public sealed class TeamsChannelHealthProviderTests
|
||||
Assert.Equal("false", result.Metadata["teams.channel.enabled"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CheckAsync_ReturnsUnhealthyWhenTargetMissing()
|
||||
{
|
||||
var channel = CreateChannel(enabled: true, endpoint: null);
|
||||
|
||||
@@ -7,11 +7,14 @@ using StellaOps.Notify.Engine;
|
||||
using StellaOps.Notify.Models;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Connectors.Teams.Tests;
|
||||
|
||||
public sealed class TeamsChannelTestProviderTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BuildPreviewAsync_EmitsFallbackMetadata()
|
||||
{
|
||||
var provider = new TeamsChannelTestProvider();
|
||||
@@ -74,7 +77,8 @@ public sealed class TeamsChannelTestProviderTests
|
||||
attachments[0].GetProperty("content").GetProperty("type").GetString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BuildPreviewAsync_TruncatesLongFallback()
|
||||
{
|
||||
var provider = new TeamsChannelTestProvider();
|
||||
|
||||
@@ -2,11 +2,13 @@ using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Xunit.Sdk;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Models.Tests;
|
||||
|
||||
public sealed class DocSampleTests
|
||||
{
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("notify-rule@1.sample.json")]
|
||||
[InlineData("notify-channel@1.sample.json")]
|
||||
[InlineData("notify-template@1.sample.json")]
|
||||
|
||||
@@ -2,11 +2,13 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Models.Tests;
|
||||
|
||||
public sealed class NotifyCanonicalJsonSerializerTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void SerializeRuleIsDeterministic()
|
||||
{
|
||||
var ruleA = NotifyRule.Create(
|
||||
@@ -52,7 +54,8 @@ public sealed class NotifyCanonicalJsonSerializerTests
|
||||
Assert.Contains("\"schemaVersion\":\"notify.rule@1\"", jsonA, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void SerializeEventOrdersPayloadKeys()
|
||||
{
|
||||
var payload = JsonNode.Parse("{\"b\":2,\"a\":1}");
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Models.Tests;
|
||||
|
||||
public sealed class NotifyDeliveryTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void AttemptsAreSortedChronologically()
|
||||
{
|
||||
var attempts = new[]
|
||||
@@ -30,7 +32,8 @@ public sealed class NotifyDeliveryTests
|
||||
attempt => Assert.Equal(NotifyDeliveryAttemptStatus.Succeeded, attempt.Status));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void RenderedNormalizesAttachments()
|
||||
{
|
||||
var rendered = NotifyDeliveryRendered.Create(
|
||||
|
||||
@@ -2,11 +2,13 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Models.Tests;
|
||||
|
||||
public sealed class NotifyRuleTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ConstructorThrowsWhenActionsMissing()
|
||||
{
|
||||
var match = NotifyRuleMatch.Create(eventKinds: new[] { NotifyEventKinds.ScannerReportReady });
|
||||
@@ -22,7 +24,8 @@ public sealed class NotifyRuleTests
|
||||
Assert.Contains("At least one action is required", exception.Message, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ConstructorNormalizesCollections()
|
||||
{
|
||||
var rule = NotifyRule.Create(
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using System;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Models.Tests;
|
||||
|
||||
public sealed class NotifySchemaMigrationTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void UpgradeRuleAddsSchemaVersionWhenMissing()
|
||||
{
|
||||
var json = JsonNode.Parse(
|
||||
@@ -28,7 +30,8 @@ public sealed class NotifySchemaMigrationTests
|
||||
Assert.Equal("rule-legacy", rule.RuleId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void UpgradeRuleThrowsOnUnknownSchema()
|
||||
{
|
||||
var json = JsonNode.Parse(
|
||||
@@ -50,7 +53,8 @@ public sealed class NotifySchemaMigrationTests
|
||||
Assert.Contains("notify rule schema version", exception.Message, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void UpgradeChannelDefaultsMissingVersion()
|
||||
{
|
||||
var json = JsonNode.Parse(
|
||||
@@ -73,7 +77,8 @@ public sealed class NotifySchemaMigrationTests
|
||||
Assert.Equal("channel-email", channel.ChannelId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void UpgradeTemplateDefaultsMissingVersion()
|
||||
{
|
||||
var json = JsonNode.Parse(
|
||||
|
||||
@@ -5,13 +5,15 @@ using System.Text.Json.Nodes;
|
||||
using StellaOps.Notify.Models;
|
||||
using Xunit.Sdk;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Models.Tests;
|
||||
|
||||
public sealed class PlatformEventSamplesTests
|
||||
{
|
||||
private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[InlineData("scanner.report.ready@1.sample.json", NotifyEventKinds.ScannerReportReady)]
|
||||
[InlineData("scanner.scan.completed@1.sample.json", NotifyEventKinds.ScannerScanCompleted)]
|
||||
[InlineData("scheduler.rescan.delta@1.sample.json", NotifyEventKinds.SchedulerRescanDelta)]
|
||||
|
||||
@@ -6,6 +6,7 @@ using NJsonSchema;
|
||||
using Xunit;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Models.Tests;
|
||||
|
||||
public sealed class PlatformEventSchemaValidationTests
|
||||
@@ -18,7 +19,8 @@ public sealed class PlatformEventSchemaValidationTests
|
||||
new object[] { "attestor.logged@1.sample.json", "attestor.logged@1.json" }
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Theory]
|
||||
[MemberData(nameof(SampleFiles))]
|
||||
public async Task EventSamplesConformToPublishedSchemas(string sampleFile, string schemaFile)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -16,6 +16,8 @@ using StellaOps.Notify.Queue;
|
||||
using StellaOps.Notify.Queue.Nats;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Queue.Tests;
|
||||
|
||||
public sealed class NatsNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
@@ -57,7 +59,8 @@ public sealed class NatsNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
await _nats.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Publish_ShouldDeduplicate_ByDeliveryId()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -82,7 +85,8 @@ public sealed class NatsNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
second.MessageId.Should().Be(first.MessageId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Release_Retry_ShouldReschedule()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -108,7 +112,8 @@ public sealed class NatsNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
await retried.AcknowledgeAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Release_RetryBeyondMax_ShouldDeadLetter()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
|
||||
@@ -13,6 +13,8 @@ using StellaOps.Notify.Queue;
|
||||
using StellaOps.Notify.Queue.Nats;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Queue.Tests;
|
||||
|
||||
public sealed class NatsNotifyEventQueueTests : IAsyncLifetime
|
||||
@@ -54,7 +56,8 @@ public sealed class NatsNotifyEventQueueTests : IAsyncLifetime
|
||||
await _nats.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Publish_ShouldDeduplicate_ByIdempotencyKey()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -79,7 +82,8 @@ public sealed class NatsNotifyEventQueueTests : IAsyncLifetime
|
||||
second.MessageId.Should().Be(first.MessageId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Lease_Acknowledge_ShouldRemoveMessage()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -114,7 +118,8 @@ public sealed class NatsNotifyEventQueueTests : IAsyncLifetime
|
||||
afterAck.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Lease_ShouldPreserveOrdering()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -139,7 +144,8 @@ public sealed class NatsNotifyEventQueueTests : IAsyncLifetime
|
||||
.ContainInOrder(first.EventId, second.EventId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ClaimExpired_ShouldReassignLease()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
|
||||
@@ -14,6 +14,8 @@ using StellaOps.Notify.Queue;
|
||||
using StellaOps.Notify.Queue.Redis;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Queue.Tests;
|
||||
|
||||
public sealed class RedisNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
@@ -51,7 +53,8 @@ public sealed class RedisNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
await _redis.DisposeAsync().AsTask();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Publish_ShouldDeduplicate_ByDeliveryId()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -76,7 +79,8 @@ public sealed class RedisNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
second.MessageId.Should().Be(first.MessageId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Release_Retry_ShouldRescheduleDelivery()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -103,7 +107,8 @@ public sealed class RedisNotifyDeliveryQueueTests : IAsyncLifetime
|
||||
await retried.AcknowledgeAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Release_RetryBeyondMax_ShouldDeadLetter()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
|
||||
@@ -15,6 +15,8 @@ using StellaOps.Notify.Queue;
|
||||
using StellaOps.Notify.Queue.Redis;
|
||||
using Xunit;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Queue.Tests;
|
||||
|
||||
public sealed class RedisNotifyEventQueueTests : IAsyncLifetime
|
||||
@@ -52,7 +54,8 @@ public sealed class RedisNotifyEventQueueTests : IAsyncLifetime
|
||||
await _redis.DisposeAsync().AsTask();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Publish_ShouldDeduplicate_ByIdempotencyKey()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -74,7 +77,8 @@ public sealed class RedisNotifyEventQueueTests : IAsyncLifetime
|
||||
second.MessageId.Should().Be(first.MessageId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Lease_Acknowledge_ShouldRemoveMessage()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -109,7 +113,8 @@ public sealed class RedisNotifyEventQueueTests : IAsyncLifetime
|
||||
afterAck.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Lease_ShouldPreserveOrdering()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
@@ -135,7 +140,8 @@ public sealed class RedisNotifyEventQueueTests : IAsyncLifetime
|
||||
.ContainInOrder(new[] { firstEvent.EventId, secondEvent.EventId });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ClaimExpired_ShouldReassignLease()
|
||||
{
|
||||
if (SkipIfUnavailable())
|
||||
|
||||
@@ -23,5 +23,6 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Queue/StellaOps.Notify.Queue.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(NotifyPostgresCollection.Name)]
|
||||
@@ -27,7 +28,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CreateAndGetById_RoundTripsChannel()
|
||||
{
|
||||
// Arrange
|
||||
@@ -52,7 +54,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
fetched.ChannelType.Should().Be(ChannelType.Email);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByName_ReturnsCorrectChannel()
|
||||
{
|
||||
// Arrange
|
||||
@@ -67,7 +70,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
fetched!.Id.Should().Be(channel.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetAll_ReturnsAllChannelsForTenant()
|
||||
{
|
||||
// Arrange
|
||||
@@ -84,7 +88,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
channels.Select(c => c.Name).Should().Contain(["channel1", "channel2"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetAll_FiltersByEnabled()
|
||||
{
|
||||
// Arrange
|
||||
@@ -108,7 +113,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
enabledChannels[0].Name.Should().Be("enabled");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetAll_FiltersByChannelType()
|
||||
{
|
||||
// Arrange
|
||||
@@ -125,7 +131,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
slackChannels[0].Name.Should().Be("slack");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Update_ModifiesChannel()
|
||||
{
|
||||
// Arrange
|
||||
@@ -151,7 +158,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
fetched.Config.Should().Contain("updated");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Delete_RemovesChannel()
|
||||
{
|
||||
// Arrange
|
||||
@@ -167,7 +175,8 @@ public sealed class ChannelRepositoryTests : IAsyncLifetime
|
||||
fetched.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetEnabledByType_ReturnsOnlyEnabledChannelsOfType()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(NotifyPostgresCollection.Name)]
|
||||
@@ -46,7 +47,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
await _channelRepository.CreateAsync(channel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CreateAndGetById_RoundTripsDelivery()
|
||||
{
|
||||
// Arrange
|
||||
@@ -64,7 +66,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
fetched.Status.Should().Be(DeliveryStatus.Pending);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetPending_ReturnsPendingDeliveries()
|
||||
{
|
||||
// Arrange
|
||||
@@ -80,7 +83,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
pendingDeliveries[0].Id.Should().Be(pending.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByStatus_ReturnsDeliveriesWithStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -96,7 +100,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
deliveries[0].Status.Should().Be(DeliveryStatus.Pending);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByCorrelationId_ReturnsCorrelatedDeliveries()
|
||||
{
|
||||
// Arrange
|
||||
@@ -121,7 +126,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
deliveries[0].CorrelationId.Should().Be(correlationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkQueued_UpdatesStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -139,7 +145,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
fetched.QueuedAt.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkSent_UpdatesStatusAndExternalId()
|
||||
{
|
||||
// Arrange
|
||||
@@ -159,7 +166,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
fetched.SentAt.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkDelivered_UpdatesStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -179,7 +187,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
fetched.DeliveredAt.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkFailed_UpdatesStatusAndError()
|
||||
{
|
||||
// Arrange
|
||||
@@ -203,7 +212,8 @@ public sealed class DeliveryRepositoryTests : IAsyncLifetime
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetStats_ReturnsCorrectCounts()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -38,7 +39,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_CompleteLifecycle_CollectingToSent()
|
||||
{
|
||||
// Arrange - Create channel
|
||||
@@ -90,7 +92,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
sent.SentAt.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_GetReadyToSend_ReturnsExpiredCollectingDigests()
|
||||
{
|
||||
// Arrange
|
||||
@@ -141,7 +144,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
ready.Should().NotContain(d => d.Id == notReadyDigest.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_GetByKey_ReturnsExistingDigest()
|
||||
{
|
||||
// Arrange
|
||||
@@ -179,7 +183,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
fetched.DigestKey.Should().Be(digestKey);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_Upsert_UpdatesExistingDigest()
|
||||
{
|
||||
// Arrange
|
||||
@@ -227,7 +232,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
fetched!.CollectUntil.Should().BeCloseTo(DateTimeOffset.UtcNow.AddHours(2), TimeSpan.FromMinutes(1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_DeleteOld_RemovesSentDigests()
|
||||
{
|
||||
// Arrange
|
||||
@@ -281,7 +287,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
recentFetch.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_MultipleRecipients_SeparateDigests()
|
||||
{
|
||||
// Arrange
|
||||
@@ -329,7 +336,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
fetched1!.Id.Should().NotBe(fetched2!.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_EventAccumulation_AppendsToArray()
|
||||
{
|
||||
// Arrange
|
||||
@@ -374,7 +382,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_QuietHoursIntegration_RespectsSilencePeriod()
|
||||
{
|
||||
// Arrange - Create quiet hours config
|
||||
@@ -402,7 +411,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
fetched[0].Enabled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_MaintenanceWindowIntegration_RespectsWindow()
|
||||
{
|
||||
// Arrange - Create maintenance window
|
||||
@@ -430,7 +440,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
all.Should().ContainSingle(w => w.Id == window.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_DeterministicOrdering_ConsistentResults()
|
||||
{
|
||||
// Arrange
|
||||
@@ -474,7 +485,8 @@ public sealed class DigestAggregationTests : IAsyncLifetime
|
||||
ids2.Should().Equal(ids3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Digest_MultiTenantIsolation_NoLeakage()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(NotifyPostgresCollection.Name)]
|
||||
@@ -46,7 +47,8 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
await _channelRepository.CreateAsync(channel);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task UpsertAndGetById_RoundTripsDigest()
|
||||
{
|
||||
// Arrange
|
||||
@@ -74,7 +76,8 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
fetched.Status.Should().Be(DigestStatus.Collecting);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByKey_ReturnsCorrectDigest()
|
||||
{
|
||||
// Arrange
|
||||
@@ -98,7 +101,8 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
fetched!.Id.Should().Be(digest.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AddEvent_IncrementsEventCount()
|
||||
{
|
||||
// Arrange
|
||||
@@ -115,7 +119,8 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
fetched!.EventCount.Should().Be(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetReadyToSend_ReturnsDigestsReadyToSend()
|
||||
{
|
||||
// Arrange - One ready digest (past CollectUntil), one not ready
|
||||
@@ -151,7 +156,8 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
readyDigests[0].DigestKey.Should().Be("ready");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkSending_UpdatesStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -168,7 +174,8 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
fetched!.Status.Should().Be(DigestStatus.Sending);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkSent_UpdatesStatusAndSentAt()
|
||||
{
|
||||
// Arrange
|
||||
@@ -187,7 +194,8 @@ public sealed class DigestRepositoryTests : IAsyncLifetime
|
||||
fetched.SentAt.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeleteOld_RemovesOldDigests()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -38,7 +39,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_CompleteLifecycle_ActiveToResolved()
|
||||
{
|
||||
// Arrange - Create escalation policy with multiple steps
|
||||
@@ -121,7 +123,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
finalActive.Should().NotContain(s => s.Id == escalationState.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_MultiStepProgression_TracksCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
@@ -167,7 +170,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
final.Status.Should().Be(EscalationStatus.Active);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_GetByCorrelation_RetrievesCorrectState()
|
||||
{
|
||||
// Arrange
|
||||
@@ -202,7 +206,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
fetched.CorrelationId.Should().Be(correlationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_OnCallScheduleIntegration_FindsCorrectResponder()
|
||||
{
|
||||
// Arrange - Create on-call schedules
|
||||
@@ -238,7 +243,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
secondary!.Participants.Should().Contain("charlie@example.com");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_MultipleActiveStates_AllTracked()
|
||||
{
|
||||
// Arrange
|
||||
@@ -279,7 +285,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_PolicyDisabled_NotUsed()
|
||||
{
|
||||
// Arrange
|
||||
@@ -309,7 +316,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
enabledOnly.Should().ContainSingle(p => p.Id == enabledPolicy.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_IncidentLinking_TracksAssociation()
|
||||
{
|
||||
// Arrange
|
||||
@@ -354,7 +362,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
fetched!.IncidentId.Should().Be(incident.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_RepeatIteration_TracksRepeats()
|
||||
{
|
||||
// Arrange
|
||||
@@ -387,7 +396,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
fetched!.RepeatIteration.Should().Be(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_DeterministicOrdering_ConsistentResults()
|
||||
{
|
||||
// Arrange
|
||||
@@ -429,7 +439,8 @@ public sealed class EscalationHandlingTests : IAsyncLifetime
|
||||
ids2.Should().Equal(ids3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Escalation_Metadata_PreservedThroughLifecycle()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(NotifyPostgresCollection.Name)]
|
||||
@@ -27,7 +28,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CreateAndGetById_RoundTripsInboxItem()
|
||||
{
|
||||
// Arrange
|
||||
@@ -54,7 +56,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
fetched.Read.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetForUser_ReturnsUserInboxItems()
|
||||
{
|
||||
// Arrange
|
||||
@@ -74,7 +77,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
items.Select(i => i.Title).Should().Contain(["Item 1", "Item 2"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetForUser_FiltersUnreadOnly()
|
||||
{
|
||||
// Arrange
|
||||
@@ -93,7 +97,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
unreadItems[0].Title.Should().Be("Unread");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetUnreadCount_ReturnsCorrectCount()
|
||||
{
|
||||
// Arrange
|
||||
@@ -111,7 +116,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
count.Should().Be(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkRead_UpdatesReadStatus()
|
||||
{
|
||||
// Arrange
|
||||
@@ -129,7 +135,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
fetched.ReadAt.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task MarkAllRead_MarksAllUserItemsAsRead()
|
||||
{
|
||||
// Arrange
|
||||
@@ -147,7 +154,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
unreadCount.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Archive_ArchivesItem()
|
||||
{
|
||||
// Arrange
|
||||
@@ -165,7 +173,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
fetched.ArchivedAt.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Delete_RemovesItem()
|
||||
{
|
||||
// Arrange
|
||||
@@ -182,7 +191,8 @@ public sealed class InboxRepositoryTests : IAsyncLifetime
|
||||
fetched.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeleteOld_RemovesOldItems()
|
||||
{
|
||||
// Arrange - We can't easily set CreatedAt in the test, so this tests the API works
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
/// <summary>
|
||||
@@ -40,7 +41,8 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeliveryFlow_CompleteLifecycle_PendingToDelivered()
|
||||
{
|
||||
// Arrange - Create channel
|
||||
@@ -129,7 +131,8 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
finalPending.Should().NotContain(d => d.Id == delivery.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeliveryFlow_FailureAndRetry_TracksErrorState()
|
||||
{
|
||||
// Arrange
|
||||
@@ -167,7 +170,8 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
failed.Attempt.Should().BeGreaterThanOrEqualTo(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeliveryFlow_MultipleChannels_IndependentDeliveries()
|
||||
{
|
||||
// Arrange - Create two channels
|
||||
@@ -232,7 +236,8 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
slack.Status.Should().Be(DeliveryStatus.Failed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeliveryFlow_StatsAccumulation_CorrectAggregates()
|
||||
{
|
||||
// Arrange
|
||||
@@ -290,7 +295,8 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
stats.Failed.Should().Be(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeliveryFlow_DeterministicOrdering_ConsistentResults()
|
||||
{
|
||||
// Arrange
|
||||
@@ -332,7 +338,8 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
ids2.Should().Equal(ids3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeliveryFlow_AuditTrail_RecordsActions()
|
||||
{
|
||||
// Arrange
|
||||
@@ -372,7 +379,8 @@ public sealed class NotificationDeliveryFlowTests : IAsyncLifetime
|
||||
audits[0].Action.Should().Be("channel.created");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeliveryFlow_DisabledChannel_NotQueried()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(NotifyPostgresCollection.Name)]
|
||||
@@ -29,7 +30,8 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
|
||||
|
||||
private Task ResetAsync() => _fixture.ExecuteSqlAsync("TRUNCATE TABLE notify.audit, notify.deliveries, notify.digests, notify.channels RESTART IDENTITY CASCADE;");
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Create_ReturnsGeneratedId()
|
||||
{
|
||||
// Arrange
|
||||
@@ -50,7 +52,8 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
|
||||
id.Should().BeGreaterThan(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task List_ReturnsAuditEntriesOrderedByCreatedAtDesc()
|
||||
{
|
||||
// Arrange
|
||||
@@ -69,7 +72,8 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
|
||||
audits[0].Action.Should().Be("action2"); // Most recent first
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByResource_ReturnsResourceAudits()
|
||||
{
|
||||
// Arrange
|
||||
@@ -92,7 +96,8 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
|
||||
audits[0].ResourceId.Should().Be(resourceId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByResource_WithoutResourceId_ReturnsAllOfType()
|
||||
{
|
||||
// Arrange
|
||||
@@ -119,7 +124,8 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
|
||||
audits.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByCorrelationId_ReturnsCorrelatedAudits()
|
||||
{
|
||||
// Arrange
|
||||
@@ -150,7 +156,8 @@ public sealed class NotifyAuditRepositoryTests : IAsyncLifetime
|
||||
audits.Should().AllSatisfy(a => a.CorrelationId.Should().Be(correlationId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DeleteOld_RemovesOldAudits()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(NotifyPostgresCollection.Name)]
|
||||
@@ -27,7 +28,8 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CreateAndGetById_RoundTripsRule()
|
||||
{
|
||||
// Arrange
|
||||
@@ -55,7 +57,8 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
fetched.EventTypes.Should().Contain(["scan.completed", "vulnerability.found"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByName_ReturnsCorrectRule()
|
||||
{
|
||||
// Arrange
|
||||
@@ -70,7 +73,8 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
fetched!.Id.Should().Be(rule.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task List_ReturnsAllRulesForTenant()
|
||||
{
|
||||
// Arrange
|
||||
@@ -87,7 +91,8 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
rules.Select(r => r.Name).Should().Contain(["rule1", "rule2"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task List_FiltersByEnabled()
|
||||
{
|
||||
// Arrange
|
||||
@@ -111,7 +116,8 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
enabledRules[0].Name.Should().Be("enabled");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetMatchingRules_ReturnsRulesForEventType()
|
||||
{
|
||||
// Arrange
|
||||
@@ -142,7 +148,8 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
matchingRules[0].Name.Should().Be("scan-rule");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Update_ModifiesRule()
|
||||
{
|
||||
// Arrange
|
||||
@@ -170,7 +177,8 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
|
||||
fetched.Enabled.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Delete_RemovesRule()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -5,6 +5,7 @@ using StellaOps.Notify.Storage.Postgres.Models;
|
||||
using StellaOps.Notify.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(NotifyPostgresCollection.Name)]
|
||||
@@ -27,7 +28,8 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task CreateAndGetById_RoundTripsTemplate()
|
||||
{
|
||||
// Arrange
|
||||
@@ -54,7 +56,8 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
fetched.SubjectTemplate.Should().Contain("{{imageName}}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByName_ReturnsCorrectTemplate()
|
||||
{
|
||||
// Arrange
|
||||
@@ -69,7 +72,8 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
fetched!.Id.Should().Be(template.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GetByName_FiltersCorrectlyByLocale()
|
||||
{
|
||||
// Arrange
|
||||
@@ -102,7 +106,8 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
frFetched!.BodyTemplate.Should().Contain("français");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task List_ReturnsAllTemplatesForTenant()
|
||||
{
|
||||
// Arrange
|
||||
@@ -119,7 +124,8 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
templates.Select(t => t.Name).Should().Contain(["template1", "template2"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task List_FiltersByChannelType()
|
||||
{
|
||||
// Arrange
|
||||
@@ -136,7 +142,8 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
emailTemplates[0].Name.Should().Be("email");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Update_ModifiesTemplate()
|
||||
{
|
||||
// Arrange
|
||||
@@ -162,7 +169,8 @@ public sealed class TemplateRepositoryTests : IAsyncLifetime
|
||||
fetched.BodyTemplate.Should().Be("Updated body content");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task Delete_RemovesTemplate()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
@@ -14,6 +14,8 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using StellaOps.Notify.Engine;
|
||||
using StellaOps.Notify.Models;
|
||||
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.WebService.Tests;
|
||||
|
||||
public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Program>>, IAsyncLifetime
|
||||
@@ -78,7 +80,8 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
|
||||
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task RuleCrudLifecycle()
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
@@ -100,7 +103,8 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
|
||||
Assert.Equal(HttpStatusCode.NotFound, afterDelete.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ChannelTemplateDeliveryAndAuditFlows()
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
@@ -170,7 +174,8 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
|
||||
Assert.Equal(HttpStatusCode.NotFound, digestAfterDelete.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task LockEndpointsAllowAcquireAndRelease()
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
@@ -198,7 +203,8 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
|
||||
Assert.True(secondContent? ["acquired"]?.GetValue<bool>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ChannelTestSendReturnsPreview()
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
@@ -243,7 +249,8 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
|
||||
Assert.Equal(json["traceId"]?.GetValue<string>(), metadata?["traceId"]?.GetValue<string>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ChannelTestSendHonoursRateLimit()
|
||||
{
|
||||
using var limitedFactory = _factory.WithWebHostBuilder(builder =>
|
||||
@@ -280,7 +287,8 @@ public sealed class CrudEndpointsTests : IClassFixture<WebApplicationFactory<Pro
|
||||
Assert.NotNull(second.Headers.RetryAfter);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ChannelTestSendUsesRegisteredProvider()
|
||||
{
|
||||
var providerName = typeof(FakeSlackTestProvider).FullName!;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Net.Http.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.WebService.Tests;
|
||||
|
||||
public sealed class NormalizeEndpointsTests : IClassFixture<WebApplicationFactory<Program>>, IAsyncLifetime
|
||||
@@ -25,7 +26,8 @@ public sealed class NormalizeEndpointsTests : IClassFixture<WebApplicationFactor
|
||||
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task RuleNormalizeAddsSchemaVersion()
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
@@ -41,7 +43,8 @@ public sealed class NormalizeEndpointsTests : IClassFixture<WebApplicationFactor
|
||||
Assert.Equal("notify.rule@1", normalized?["schemaVersion"]?.GetValue<string>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ChannelNormalizeAddsSchemaVersion()
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
@@ -57,7 +60,8 @@ public sealed class NormalizeEndpointsTests : IClassFixture<WebApplicationFactor
|
||||
Assert.Equal("notify.channel@1", normalized?["schemaVersion"]?.GetValue<string>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task TemplateNormalizeAddsSchemaVersion()
|
||||
{
|
||||
var client = _factory.CreateClient();
|
||||
|
||||
@@ -10,10 +10,11 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../StellaOps.Notify.WebService/StellaOps.Notify.WebService.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0-preview.4.25258.110" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2" />
|
||||
|
||||
@@ -12,11 +12,13 @@ using StellaOps.Notify.Worker.Handlers;
|
||||
using StellaOps.Notify.Worker.Processing;
|
||||
using Xunit;
|
||||
|
||||
using StellaOps.TestKit;
|
||||
namespace StellaOps.Notify.Worker.Tests;
|
||||
|
||||
public sealed class NotifyEventLeaseProcessorTests
|
||||
{
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ProcessOnce_ShouldAcknowledgeSuccessfulLease()
|
||||
{
|
||||
var lease = new FakeLease();
|
||||
@@ -32,7 +34,8 @@ public sealed class NotifyEventLeaseProcessorTests
|
||||
lease.ReleaseCount.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ProcessOnce_ShouldRetryOnHandlerFailure()
|
||||
{
|
||||
var lease = new FakeLease();
|
||||
|
||||
@@ -24,5 +24,6 @@
|
||||
<ProjectReference Include="../../StellaOps.Notify.Worker/StellaOps.Notify.Worker.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Queue/StellaOps.Notify.Queue.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user