Improve alias capability model and Outlook alias sync
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using Wino.Core.Domain.Entities.Mail;
|
||||
using Wino.Core.Domain.Entities.Shared;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Tests.Helpers;
|
||||
using Wino.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace Wino.Core.Tests.Services;
|
||||
|
||||
public class AccountAliasCapabilityTests : IAsyncLifetime
|
||||
{
|
||||
private InMemoryDatabaseService _databaseService = null!;
|
||||
private AccountService _accountService = null!;
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
_databaseService = new InMemoryDatabaseService();
|
||||
await _databaseService.InitializeAsync();
|
||||
_accountService = CreateAccountService(_databaseService);
|
||||
}
|
||||
|
||||
public async Task DisposeAsync() => await _databaseService.DisposeAsync();
|
||||
|
||||
[Fact]
|
||||
public async Task CreateRootAliasAsync_SetsManualConfirmedDefaults()
|
||||
{
|
||||
var accountId = Guid.NewGuid();
|
||||
|
||||
await _accountService.CreateRootAliasAsync(accountId, "root@example.com");
|
||||
|
||||
var aliases = await _accountService.GetAccountAliasesAsync(accountId);
|
||||
var alias = aliases.Should().ContainSingle().Subject;
|
||||
|
||||
alias.Source.Should().Be(AliasSource.Manual);
|
||||
alias.SendCapability.Should().Be(AliasSendCapability.Confirmed);
|
||||
alias.IsPrimary.Should().BeTrue();
|
||||
alias.IsRootAlias.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateRemoteAliasInformationAsync_PreservesManualAliasesWhileAddingProviderAliases()
|
||||
{
|
||||
var account = new MailAccount
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = "Alias Test",
|
||||
Address = "primary@example.com",
|
||||
ProviderType = MailProviderType.Outlook
|
||||
};
|
||||
|
||||
await _databaseService.Connection.InsertAsync(account, typeof(MailAccount));
|
||||
|
||||
await _accountService.UpdateAccountAliasesAsync(account.Id,
|
||||
[
|
||||
new MailAccountAlias
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AccountId = account.Id,
|
||||
AliasAddress = "primary@example.com",
|
||||
ReplyToAddress = "primary@example.com",
|
||||
IsPrimary = true,
|
||||
IsRootAlias = true,
|
||||
Source = AliasSource.Manual,
|
||||
SendCapability = AliasSendCapability.Confirmed
|
||||
},
|
||||
new MailAccountAlias
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AccountId = account.Id,
|
||||
AliasAddress = "custom@example.com",
|
||||
ReplyToAddress = "replies@example.com",
|
||||
Source = AliasSource.Manual,
|
||||
SendCapability = AliasSendCapability.Unknown
|
||||
}
|
||||
]);
|
||||
|
||||
await _accountService.UpdateRemoteAliasInformationAsync(account,
|
||||
[
|
||||
new RemoteAccountAlias
|
||||
{
|
||||
AliasAddress = "primary@example.com",
|
||||
ReplyToAddress = "primary@example.com",
|
||||
IsPrimary = true,
|
||||
IsRootAlias = true,
|
||||
Source = AliasSource.ProviderDiscovered,
|
||||
SendCapability = AliasSendCapability.Confirmed
|
||||
},
|
||||
new RemoteAccountAlias
|
||||
{
|
||||
AliasAddress = "sales@example.com",
|
||||
ReplyToAddress = "sales@example.com",
|
||||
Source = AliasSource.ProviderDiscovered,
|
||||
SendCapability = AliasSendCapability.Unknown
|
||||
}
|
||||
]);
|
||||
|
||||
var aliases = await _accountService.GetAccountAliasesAsync(account.Id);
|
||||
|
||||
aliases.Should().Contain(a => a.AliasAddress == "custom@example.com" && a.Source == AliasSource.Manual);
|
||||
aliases.Should().Contain(a => a.AliasAddress == "sales@example.com" && a.Source == AliasSource.ProviderDiscovered);
|
||||
}
|
||||
|
||||
private static AccountService CreateAccountService(InMemoryDatabaseService databaseService)
|
||||
{
|
||||
var preferencesService = new Mock<IPreferencesService>();
|
||||
var signatureService = new Mock<ISignatureService>();
|
||||
var mimeFileService = new Mock<IMimeFileService>();
|
||||
var contactPictureFileService = new Mock<IContactPictureFileService>();
|
||||
|
||||
return new AccountService(
|
||||
databaseService,
|
||||
signatureService.Object,
|
||||
Mock.Of<IAuthenticationProvider>(),
|
||||
mimeFileService.Object,
|
||||
preferencesService.Object,
|
||||
contactPictureFileService.Object);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,9 @@ public class MailThreadingTests : IAsyncLifetime
|
||||
ReplyToAddress = _account.Address,
|
||||
IsPrimary = true,
|
||||
IsRootAlias = true,
|
||||
IsVerified = true
|
||||
IsVerified = true,
|
||||
Source = AliasSource.Manual,
|
||||
SendCapability = AliasSendCapability.Confirmed
|
||||
};
|
||||
|
||||
await _databaseService.Connection.InsertAsync(_account, typeof(MailAccount));
|
||||
@@ -188,6 +190,45 @@ public class MailThreadingTests : IAsyncLifetime
|
||||
draftMailCopy.References.Should().Be($"{rootMessageId};{parentMessageId}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateDraftAsync_Reply_PicksAliasFromDeliveredToHeader()
|
||||
{
|
||||
var secondaryAlias = new MailAccountAlias
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AccountId = _account.Id,
|
||||
AliasAddress = "support@test.local",
|
||||
ReplyToAddress = "support@test.local",
|
||||
IsPrimary = false,
|
||||
IsRootAlias = false,
|
||||
Source = AliasSource.Manual,
|
||||
SendCapability = AliasSendCapability.Unknown
|
||||
};
|
||||
|
||||
await _databaseService.Connection.InsertAsync(secondaryAlias, typeof(MailAccountAlias));
|
||||
|
||||
var referencedMimeMessage = CreateReferencedMimeMessage("Alias reply");
|
||||
referencedMimeMessage.Headers.Add("Delivered-To", "<support@test.local>");
|
||||
|
||||
var (draftMailCopy, draftBase64MimeMessage) = await _mailService.CreateDraftAsync(
|
||||
_account.Id,
|
||||
new DraftCreationOptions
|
||||
{
|
||||
Reason = DraftCreationReason.Reply,
|
||||
ReferencedMessage = new ReferencedMessage
|
||||
{
|
||||
MimeMessage = referencedMimeMessage,
|
||||
MailCopy = new MailCopy { UniqueId = Guid.NewGuid(), Id = Guid.NewGuid().ToString(), MessageId = "alias-parent@domain.com" }
|
||||
}
|
||||
});
|
||||
|
||||
var mimeMessage = draftBase64MimeMessage.GetMimeMessageFromBase64();
|
||||
|
||||
draftMailCopy.FromAddress.Should().Be("support@test.local");
|
||||
mimeMessage.From.Mailboxes.Should().ContainSingle(m => m.Address == "support@test.local");
|
||||
mimeMessage.ReplyTo.Mailboxes.Should().ContainSingle(m => m.Address == "support@test.local");
|
||||
}
|
||||
|
||||
private static MimeMessage CreateReferencedMimeMessage(string subject, string? messageId = null)
|
||||
{
|
||||
var message = new MimeMessage();
|
||||
|
||||
Reference in New Issue
Block a user