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:
		@@ -1,4 +1,6 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using MongoDB.Driver;
 | 
			
		||||
@@ -43,6 +45,74 @@ public class StandardClientProvisioningStoreTests
 | 
			
		||||
        Assert.Contains("scopeA", descriptor.AllowedScopes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task CreateOrUpdateAsync_StoresAudiences()
 | 
			
		||||
    {
 | 
			
		||||
        var store = new TrackingClientStore();
 | 
			
		||||
        var revocations = new TrackingRevocationStore();
 | 
			
		||||
        var provisioning = new StandardClientProvisioningStore("standard", store, revocations, TimeProvider.System);
 | 
			
		||||
 | 
			
		||||
        var registration = new AuthorityClientRegistration(
 | 
			
		||||
            clientId: "signer",
 | 
			
		||||
            confidential: false,
 | 
			
		||||
            displayName: "Signer",
 | 
			
		||||
            clientSecret: null,
 | 
			
		||||
            allowedGrantTypes: new[] { "client_credentials" },
 | 
			
		||||
            allowedScopes: new[] { "signer.sign" },
 | 
			
		||||
            allowedAudiences: new[] { "attestor", "signer" });
 | 
			
		||||
 | 
			
		||||
        var result = await provisioning.CreateOrUpdateAsync(registration, CancellationToken.None);
 | 
			
		||||
 | 
			
		||||
        Assert.True(result.Succeeded);
 | 
			
		||||
        var document = Assert.Contains("signer", store.Documents);
 | 
			
		||||
        Assert.Equal("attestor signer", document.Value.Properties[AuthorityClientMetadataKeys.Audiences]);
 | 
			
		||||
 | 
			
		||||
        var descriptor = await provisioning.FindByClientIdAsync("signer", CancellationToken.None);
 | 
			
		||||
        Assert.NotNull(descriptor);
 | 
			
		||||
        Assert.Equal(new[] { "attestor", "signer" }, descriptor!.Audiences.OrderBy(value => value, StringComparer.Ordinal));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task CreateOrUpdateAsync_MapsCertificateBindings()
 | 
			
		||||
    {
 | 
			
		||||
        var store = new TrackingClientStore();
 | 
			
		||||
        var revocations = new TrackingRevocationStore();
 | 
			
		||||
        var provisioning = new StandardClientProvisioningStore("standard", store, revocations, TimeProvider.System);
 | 
			
		||||
 | 
			
		||||
        var bindingRegistration = new AuthorityClientCertificateBindingRegistration(
 | 
			
		||||
            thumbprint: "aa:bb:cc:dd",
 | 
			
		||||
            serialNumber: "01ff",
 | 
			
		||||
            subject: "CN=mtls-client",
 | 
			
		||||
            issuer: "CN=test-ca",
 | 
			
		||||
            subjectAlternativeNames: new[] { "client.mtls.test", "spiffe://client" },
 | 
			
		||||
            notBefore: DateTimeOffset.UtcNow.AddMinutes(-5),
 | 
			
		||||
            notAfter: DateTimeOffset.UtcNow.AddHours(1),
 | 
			
		||||
            label: "primary");
 | 
			
		||||
 | 
			
		||||
        var registration = new AuthorityClientRegistration(
 | 
			
		||||
            clientId: "mtls-client",
 | 
			
		||||
            confidential: true,
 | 
			
		||||
            displayName: "MTLS Client",
 | 
			
		||||
            clientSecret: "secret",
 | 
			
		||||
            allowedGrantTypes: new[] { "client_credentials" },
 | 
			
		||||
            allowedScopes: new[] { "signer.sign" },
 | 
			
		||||
            allowedAudiences: new[] { "signer" },
 | 
			
		||||
            certificateBindings: new[] { bindingRegistration });
 | 
			
		||||
 | 
			
		||||
        await provisioning.CreateOrUpdateAsync(registration, CancellationToken.None);
 | 
			
		||||
 | 
			
		||||
        var document = Assert.Contains("mtls-client", store.Documents).Value;
 | 
			
		||||
        var binding = Assert.Single(document.CertificateBindings);
 | 
			
		||||
        Assert.Equal("AABBCCDD", binding.Thumbprint);
 | 
			
		||||
        Assert.Equal("01ff", binding.SerialNumber);
 | 
			
		||||
        Assert.Equal("CN=mtls-client", binding.Subject);
 | 
			
		||||
        Assert.Equal("CN=test-ca", binding.Issuer);
 | 
			
		||||
        Assert.Equal(new[] { "client.mtls.test", "spiffe://client" }, binding.SubjectAlternativeNames);
 | 
			
		||||
        Assert.Equal(bindingRegistration.NotBefore, binding.NotBefore);
 | 
			
		||||
        Assert.Equal(bindingRegistration.NotAfter, binding.NotAfter);
 | 
			
		||||
        Assert.Equal("primary", binding.Label);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private sealed class TrackingClientStore : IAuthorityClientStore
 | 
			
		||||
    {
 | 
			
		||||
        public Dictionary<string, AuthorityClientDocument> Documents { get; } = new(StringComparer.OrdinalIgnoreCase);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user