Add channel test providers for Email, Slack, Teams, and Webhook

- Implemented EmailChannelTestProvider to generate email preview payloads.
- Implemented SlackChannelTestProvider to create Slack message previews.
- Implemented TeamsChannelTestProvider for generating Teams Adaptive Card previews.
- Implemented WebhookChannelTestProvider to create webhook payloads.
- Added INotifyChannelTestProvider interface for channel-specific preview generation.
- Created ChannelTestPreviewContracts for request and response models.
- Developed NotifyChannelTestService to handle test send requests and generate previews.
- Added rate limit policies for test sends and delivery history.
- Implemented unit tests for service registration and binding.
- Updated project files to include necessary dependencies and configurations.
This commit is contained in:
master
2025-10-19 23:29:34 +03:00
parent a811f7ac47
commit a07f46231b
239 changed files with 17245 additions and 3155 deletions

View File

@@ -0,0 +1,82 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using StellaOps.Concelier.Storage.Mongo;
using StellaOps.Concelier.Storage.Mongo.Conflicts;
using StellaOps.Concelier.Testing;
using Xunit;
namespace StellaOps.Concelier.Storage.Mongo.Tests;
[Collection("mongo-fixture")]
public sealed class AdvisoryConflictStoreTests
{
private readonly IMongoDatabase _database;
public AdvisoryConflictStoreTests(MongoIntegrationFixture fixture)
{
_database = fixture.Database ?? throw new ArgumentNullException(nameof(fixture.Database));
}
[Fact]
public async Task InsertAndRetrieve_PersistsConflicts()
{
var store = new AdvisoryConflictStore(_database);
var vulnerabilityKey = $"CVE-{Guid.NewGuid():N}";
var baseTime = DateTimeOffset.UtcNow;
var statementIds = new[] { Guid.NewGuid(), Guid.NewGuid() };
var conflict = new AdvisoryConflictRecord(
Guid.NewGuid(),
vulnerabilityKey,
new byte[] { 0x10, 0x20 },
baseTime,
baseTime.AddSeconds(30),
statementIds,
new BsonDocument("explanation", "first-pass"));
await store.InsertAsync(new[] { conflict }, CancellationToken.None);
var results = await store.GetConflictsAsync(vulnerabilityKey, null, CancellationToken.None);
Assert.Single(results);
Assert.Equal(conflict.Id, results[0].Id);
Assert.Equal(statementIds, results[0].StatementIds);
}
[Fact]
public async Task GetConflicts_AsOfFilters()
{
var store = new AdvisoryConflictStore(_database);
var vulnerabilityKey = $"CVE-{Guid.NewGuid():N}";
var baseTime = DateTimeOffset.UtcNow;
var earlyConflict = new AdvisoryConflictRecord(
Guid.NewGuid(),
vulnerabilityKey,
new byte[] { 0x01 },
baseTime,
baseTime.AddSeconds(10),
new[] { Guid.NewGuid() },
new BsonDocument("stage", "early"));
var lateConflict = new AdvisoryConflictRecord(
Guid.NewGuid(),
vulnerabilityKey,
new byte[] { 0x02 },
baseTime.AddMinutes(10),
baseTime.AddMinutes(10).AddSeconds(15),
new[] { Guid.NewGuid() },
new BsonDocument("stage", "late"));
await store.InsertAsync(new[] { earlyConflict, lateConflict }, CancellationToken.None);
var results = await store.GetConflictsAsync(vulnerabilityKey, baseTime.AddMinutes(1), CancellationToken.None);
Assert.Single(results);
Assert.Equal("early", results[0].Details["stage"].AsString);
}
}