General account details settings and some marking mail issues

This commit is contained in:
Burak Kaan Köse
2026-04-01 01:41:17 +02:00
parent 6f61605c12
commit 7b369201b0
11 changed files with 536 additions and 435 deletions
@@ -0,0 +1,85 @@
using CommunityToolkit.Mvvm.Messaging;
using FluentAssertions;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Enums;
using Wino.Core.Requests.Mail;
using Wino.Messaging.UI;
using Xunit;
namespace Wino.Core.Tests.Services;
public sealed class MailRequestStateTests
{
[Fact]
public void MarkReadRequest_RevertUiChanges_RestoresOriginalReadState()
{
var mailCopy = CreateMailCopy(isRead: false, isFlagged: false);
var request = new MarkReadRequest(mailCopy, IsRead: true);
var recipient = new MailRequestRecipient();
WeakReferenceMessenger.Default.RegisterAll(recipient);
try
{
request.IsNoOp.Should().BeFalse();
request.ApplyUIChanges();
request.RevertUIChanges();
mailCopy.IsRead.Should().BeFalse();
recipient.Updated.Should().HaveCount(2);
recipient.Updated[0].Source.Should().Be(MailUpdateSource.ClientUpdated);
recipient.Updated[1].Source.Should().Be(MailUpdateSource.ClientReverted);
recipient.Updated[1].UpdatedMail.IsRead.Should().BeFalse();
}
finally
{
WeakReferenceMessenger.Default.UnregisterAll(recipient);
}
}
[Fact]
public void ChangeFlagRequest_RevertUiChanges_RestoresOriginalFlagState()
{
var mailCopy = CreateMailCopy(isRead: true, isFlagged: false);
var request = new ChangeFlagRequest(mailCopy, IsFlagged: true);
var recipient = new MailRequestRecipient();
WeakReferenceMessenger.Default.RegisterAll(recipient);
try
{
request.IsNoOp.Should().BeFalse();
request.ApplyUIChanges();
request.RevertUIChanges();
mailCopy.IsFlagged.Should().BeFalse();
recipient.Updated.Should().HaveCount(2);
recipient.Updated[0].Source.Should().Be(MailUpdateSource.ClientUpdated);
recipient.Updated[1].Source.Should().Be(MailUpdateSource.ClientReverted);
recipient.Updated[1].UpdatedMail.IsFlagged.Should().BeFalse();
}
finally
{
WeakReferenceMessenger.Default.UnregisterAll(recipient);
}
}
private static MailCopy CreateMailCopy(bool isRead, bool isFlagged) =>
new()
{
UniqueId = Guid.NewGuid(),
Id = Guid.NewGuid().ToString(),
FolderId = Guid.NewGuid(),
IsRead = isRead,
IsFlagged = isFlagged
};
internal sealed class MailRequestRecipient : IRecipient<MailUpdatedMessage>
{
public List<MailUpdatedMessage> Updated { get; } = [];
public void Receive(MailUpdatedMessage message) => Updated.Add(message);
}
}
@@ -0,0 +1,102 @@
using System.Net;
using System.Net.Http;
using System.Reflection;
using FluentAssertions;
using Microsoft.Kiota.Abstractions;
using Moq;
using Wino.Core.Domain.Entities.Mail;
using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Integration.Processors;
using Wino.Core.Requests.Bundles;
using Wino.Core.Requests.Mail;
using Wino.Core.Synchronizers.Mail;
using Xunit;
namespace Wino.Core.Tests.Synchronizers;
public sealed class OutlookSynchronizerRequestSuccessTests
{
[Fact]
public async Task HandleSuccessfulResponseAsync_MarkReadRequest_PersistsLocalReadStateEvenWithoutResponseBody()
{
var changeProcessor = new Mock<IOutlookChangeProcessor>(MockBehavior.Strict);
changeProcessor
.Setup(x => x.ChangeMailReadStatusAsync("mail-id", true))
.Returns(Task.CompletedTask);
var synchronizer = CreateSynchronizer(changeProcessor.Object);
var request = new MarkReadRequest(CreateMailCopy(), IsRead: true);
var bundle = new HttpRequestBundle<RequestInformation>(new RequestInformation(), request, request);
using var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(string.Empty)
};
await InvokeHandleSuccessfulResponseAsync(synchronizer, bundle, response);
changeProcessor.Verify(x => x.ChangeMailReadStatusAsync("mail-id", true), Times.Once);
}
[Fact]
public async Task HandleSuccessfulResponseAsync_ChangeFlagRequest_PersistsLocalFlagStateEvenWithoutResponseBody()
{
var changeProcessor = new Mock<IOutlookChangeProcessor>(MockBehavior.Strict);
changeProcessor
.Setup(x => x.ChangeFlagStatusAsync("mail-id", true))
.Returns(Task.CompletedTask);
var synchronizer = CreateSynchronizer(changeProcessor.Object);
var request = new ChangeFlagRequest(CreateMailCopy(), IsFlagged: true);
var bundle = new HttpRequestBundle<RequestInformation>(new RequestInformation(), request, request);
using var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(string.Empty)
};
await InvokeHandleSuccessfulResponseAsync(synchronizer, bundle, response);
changeProcessor.Verify(x => x.ChangeFlagStatusAsync("mail-id", true), Times.Once);
}
private static OutlookSynchronizer CreateSynchronizer(IOutlookChangeProcessor changeProcessor)
{
var account = new MailAccount
{
Id = Guid.NewGuid(),
Name = "Outlook",
Address = "user@example.com"
};
var authenticator = new Mock<IAuthenticator>(MockBehavior.Loose);
var errorFactory = new Mock<IOutlookSynchronizerErrorHandlerFactory>(MockBehavior.Loose);
return new OutlookSynchronizer(account, authenticator.Object, changeProcessor, errorFactory.Object);
}
private static MailCopy CreateMailCopy() =>
new()
{
UniqueId = Guid.NewGuid(),
Id = "mail-id",
FolderId = Guid.NewGuid(),
IsRead = false,
IsFlagged = false
};
private static async Task InvokeHandleSuccessfulResponseAsync(
OutlookSynchronizer synchronizer,
HttpRequestBundle<RequestInformation> bundle,
HttpResponseMessage response)
{
var method = typeof(OutlookSynchronizer).GetMethod(
"HandleSuccessfulResponseAsync",
BindingFlags.Instance | BindingFlags.NonPublic);
method.Should().NotBeNull();
var task = method!.Invoke(synchronizer, [bundle, response]) as Task;
task.Should().NotBeNull();
await task!;
}
}