yavsc/src/Yavsc.Org.Tests/NonRegression/EMailling.cs

164 lines
6 KiB
C#
Raw Normal View History

using System.ComponentModel.DataAnnotations;
using System.Globalization;
using MailKit.Net.Smtp;
2025-07-16 00:47:50 +01:00
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using MimeKit;
2025-07-16 00:47:50 +01:00
using Yavsc.Interface;
using Yavsc.Interfaces;
using Yavsc.Models.Relationship;
using Yavsc.Org.Tests.Fakes;
using Yavsc.Services;
using Yavsc.Settings;
using Yavsc.ViewModels.Account;
using Xunit;
2026-06-19 19:59:15 +01:00
namespace Yavsc.Org.Tests
{
[Collection("EMaillingTeststCollection")]
2021-04-05 00:11:54 +01:00
[Trait("regression", "II")]
2025-07-13 18:13:04 +01:00
public class EMaillingTests : IClassFixture<WebServerFixture>
{
2025-07-13 18:13:04 +01:00
readonly WebServerFixture _serverFixture;
2020-09-12 01:11:30 +01:00
readonly ITestOutputHelper output;
readonly ILogger _logger;
2025-07-13 18:13:04 +01:00
public EMaillingTests(WebServerFixture serverFixture, ITestOutputHelper output)
{
this.output = output;
_serverFixture = serverFixture;
2026-08-21 20:33:15 +01:00
_logger = serverFixture.Logger!;
}
[Fact]
2026-08-21 20:33:15 +01:00
public async Task SendEMailSynchrone()
{
2026-04-20 00:35:51 +01:00
using IServiceScope scope = _serverFixture.Services.CreateScope();
2025-07-16 00:47:50 +01:00
ITrueEmailSender mailSender = scope.ServiceProvider.GetRequiredService<ITrueEmailSender>();
var factory = Assert.IsType<RecordingSmtpClientFactory>(
scope.ServiceProvider.GetRequiredService<ISmtpClientFactory>());
2025-07-13 18:13:04 +01:00
2026-04-20 00:35:51 +01:00
output.WriteLine("SendEMailSynchrone ...");
2026-08-21 20:33:15 +01:00
await mailSender.SendEmailAsync
2026-04-20 00:35:51 +01:00
(
2026-08-21 20:33:15 +01:00
_serverFixture.SiteSettings!.Owner.Name,
_serverFixture.SiteSettings!.Owner.EMail,
2026-04-20 00:35:51 +01:00
$"monthly email",
2026-08-21 20:33:15 +01:00
"test boby monthly email");
2026-04-20 00:35:51 +01:00
// Assert the SMTP roundtrip was short-circuited by the
// recording fake installed in WebServerFixture: exactly
// one client was created and it saw the expected sequence
// of Connect → Authenticate → Send → Disconnect.
var client = Assert.Single(factory.Created);
Assert.Equal(
new[]
{
RecordingSmtpCallKind.Connect,
RecordingSmtpCallKind.Authenticate,
RecordingSmtpCallKind.Send,
RecordingSmtpCallKind.Disconnect,
},
client.Calls.Select(c => c.Kind).ToArray());
Assert.Equal(_serverFixture.SiteSettings.Owner.EMail, client.LastSentMessage?.To.Mailboxes.First().Address);
2026-04-20 00:35:51 +01:00
}
[Fact]
public void RegisterModel_rejects_invalid_email_format()
{
var model = new RegisterModel
{
UserName = "alice",
Email = "this is not an email",
Password = "Password123!",
ConfirmPassword = "Password123!"
};
var results = new List<ValidationResult>();
var valid = Validator.TryValidateObject(
model,
new ValidationContext(model),
results,
validateAllProperties: true);
Assert.False(valid);
Assert.Contains(results, r => r.MemberNames.Contains(nameof(RegisterModel.Email)));
}
[Fact]
public async Task SendEmailAsync_ignores_smtp_recipient_rejection()
{
var sender = new MailSender(
Options.Create(new SiteSettings
{
Title = "Test",
Authority = "example.com",
Owner = new StaticContact { Name = "Test Owner", EMail = "owner@example.com" }
}),
Options.Create(new SmtpSettings
{
Host = "smtp.test.local",
Port = 465,
UserName = "test-user",
Password = "secret"
}),
NullLoggerFactory.Instance,
new TestStringLocalizer(),
new RejectingSmtpClientFactory());
var result = await sender.SendEmailAsync(
"Alice",
"contact@pschneider.fr",
"Welcome",
"hello");
Assert.Equal(string.Empty, result);
}
private sealed class RejectingSmtpClientFactory : ISmtpClientFactory
{
public Yavsc.Interfaces.ISmtpClient CreateClient() => new RejectingSmtpClient();
}
private sealed class RejectingSmtpClient : Yavsc.Interfaces.ISmtpClient
{
public int Timeout { get; set; }
public void Connect(string host, int port, MailKit.Security.SecureSocketOptions options) { }
public void Authenticate(string userName, string password) { }
public Task SendAsync(MimeMessage message, CancellationToken cancellationToken = default)
{
throw new SmtpCommandException(
SmtpErrorCode.RecipientNotAccepted,
SmtpStatusCode.MailboxUnavailable,
"Recipient address rejected: User unknown in local recipient table");
}
public void Disconnect(bool quit) { }
public void Dispose() { }
}
private sealed class TestStringLocalizer : IStringLocalizer<MailSender>
{
public LocalizedString this[string name] => new(name, name);
public LocalizedString this[string name, params object[] arguments] => new(name, string.Format(CultureInfo.InvariantCulture, name, arguments));
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
=> Enumerable.Empty<LocalizedString>();
public LocalizedString GetString(string name)
=> new(name, name);
public LocalizedString GetString(string name, params object[] arguments)
=> new(name, string.Format(CultureInfo.InvariantCulture, name, arguments));
public IStringLocalizer WithCulture(CultureInfo culture)
=> this;
}
}
2018-07-20 02:27:53 +02:00
}