126 lines
4.9 KiB
C#
126 lines
4.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Omika.App.Local.Abstractions;
|
|
using Omika.App.Local.Models;
|
|
using Omika.App.Local.Services;
|
|
using Omika.Core.Contracts.Mobile.Sync;
|
|
using Omika.Core.Contracts.Planning;
|
|
|
|
namespace Omika.Tests.Mobile.Local;
|
|
|
|
/// <summary>
|
|
/// Tests du service local de finalisation d'un rendez-vous : mise à jour SQLite du
|
|
/// statut « Fait » (jamais de suppression) + publication du changement d'état.
|
|
/// </summary>
|
|
public class RendezVousFinalisationLocalServiceTests
|
|
{
|
|
private sealed class FakeRendezVousRepository : ILocalRepository<LocalRendezVous>
|
|
{
|
|
public string TableName => "RendezVous";
|
|
private readonly Dictionary<Guid, LocalRendezVous> _items = [];
|
|
|
|
public void Seed(LocalRendezVous entity) => _items[entity.Id] = entity;
|
|
|
|
public Task UpsertAsync(LocalRendezVous entity, CancellationToken cancellationToken = default)
|
|
{
|
|
_items[entity.Id] = entity;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<LocalRendezVous?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
|
|
=> Task.FromResult(_items.TryGetValue(id, out LocalRendezVous? entity) ? entity : null);
|
|
|
|
public Task<IReadOnlyList<LocalRendezVous>> GetAllAsync(CancellationToken cancellationToken = default)
|
|
=> Task.FromResult<IReadOnlyList<LocalRendezVous>>([.. _items.Values]);
|
|
|
|
public Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
|
|
{
|
|
_items.Remove(id);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task ClearAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
_items.Clear();
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<int> CountAsync(CancellationToken cancellationToken = default)
|
|
=> Task.FromResult(_items.Count);
|
|
}
|
|
|
|
private static RendezVousDetailsDto DtoConfirmé(Guid guid)
|
|
=> new()
|
|
{
|
|
Id = guid.ToString("D"),
|
|
Titre = "RDV Client",
|
|
Statut = new Omika.Core.Contracts.Common.ReferenceValueDto
|
|
{
|
|
Key = "S.RDV.CONF",
|
|
Label = "Confirmé"
|
|
},
|
|
Debut = DateTime.Now.AddDays(-1),
|
|
Fin = DateTime.Now.AddDays(-1).AddHours(2)
|
|
};
|
|
|
|
[Fact]
|
|
public async Task MarquerFaitAsync_AppliqueStatutFaitLocalementEtPublie()
|
|
{
|
|
// Arrange : un rendez-vous local au statut « Confirmé ».
|
|
Guid rendezVousGuid = Guid.Parse("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb");
|
|
var repository = new FakeRendezVousRepository();
|
|
repository.Seed(new LocalRendezVous
|
|
{
|
|
Id = rendezVousGuid,
|
|
PayloadJson = JsonSerializer.Serialize(DtoConfirmé(rendezVousGuid))
|
|
});
|
|
var notifier = new RendezVousStateNotifier();
|
|
RendezVousStateChange? published = null;
|
|
notifier.StateChanged += (_, change) => published = change;
|
|
|
|
var service = new RendezVousFinalisationLocalService(repository, notifier);
|
|
|
|
// Act
|
|
await service.MarquerFaitAsync(rendezVousGuid);
|
|
|
|
// Assert : la copie locale porte le statut « Fait » (GUID conservé).
|
|
LocalRendezVous? updated = await repository.GetByIdAsync(rendezVousGuid);
|
|
Assert.NotNull(updated);
|
|
RendezVousDetailsDto? dto = JsonSerializer.Deserialize<RendezVousDetailsDto>(updated!.PayloadJson);
|
|
Assert.Equal(RendezVousStatut.FaitKey, dto!.Statut?.Key);
|
|
Assert.Equal(RendezVousStatut.FaitLabel, dto.Statut?.Label);
|
|
Assert.Null(dto.Annulation);
|
|
|
|
// Assert : le changement d'état a été publié (propagation aux vues).
|
|
Assert.NotNull(published);
|
|
Assert.Equal(rendezVousGuid, published!.RendezVousGuid);
|
|
Assert.False(published.EstAnnule);
|
|
Assert.True(published.EstFait);
|
|
Assert.Equal(RendezVousStatut.FaitKey, published.StatutKey);
|
|
Assert.Equal(RendezVousStatut.FaitLabel, published.StatutLabel);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task MarquerFaitAsync_RendezVousLocalIntrouvable_PublieToutDeMeme()
|
|
{
|
|
// Arrange : aucun rendez-vous dans le snapshot local (ex. agenda d'équipe).
|
|
Guid rendezVousGuid = Guid.NewGuid();
|
|
var notifier = new RendezVousStateNotifier();
|
|
RendezVousStateChange? published = null;
|
|
notifier.StateChanged += (_, change) => published = change;
|
|
|
|
var service = new RendezVousFinalisationLocalService(new FakeRendezVousRepository(), notifier);
|
|
|
|
// Act : ne doit pas lever d'exception.
|
|
await service.MarquerFaitAsync(rendezVousGuid);
|
|
|
|
// Assert : l'événement est publié malgré l'absence locale (UI immédiate).
|
|
Assert.NotNull(published);
|
|
Assert.Equal(rendezVousGuid, published!.RendezVousGuid);
|
|
Assert.True(published.EstFait);
|
|
}
|
|
}
|