Files
Omika/tests/Omika.Tests/Mobile/Local/AgendaServiceRangeTests.cs
T
2026-10-23 18:46:50 +02:00

167 lines
7.2 KiB
C#

using System.Text.Json;
using Omika.App.Local.Abstractions;
using Omika.App.Local.Models;
using Omika.App.Local.Services;
using Omika.Core.Contracts.Common;
using Omika.Core.Contracts.Planning;
namespace Omika.Tests.Mobile.Local;
/// <summary>
/// Tests des bornes de plage du service Agenda : chargement d'une journée ou
/// d'une semaine avec une seule opération locale et des bornes robustes.
/// </summary>
public class AgendaServiceRangeTests : LocalTestBase
{
private readonly AgendaService _service;
public AgendaServiceRangeTests()
{
_service = new AgendaService(
RendezVousRepository, ClientRepository, SiteRepository, InterventionRepository, CollaborateurRepository, ApiClient, SessionService);
}
private static LocalRendezVous CreateRendezVous(
Guid id,
DateTime debut,
DateTime fin,
string titre,
bool estArchive = false)
{
var dto = new RendezVousDetailsDto
{
Id = id.ToString(),
Titre = titre,
Debut = debut,
Fin = fin,
Statut = new ReferenceValueDto { Label = "Planifié" },
EstArchive = estArchive
};
return new LocalRendezVous
{
Id = id,
PayloadJson = JsonSerializer.Serialize(dto),
UpdatedAtUtc = DateTimeOffset.UtcNow
};
}
[Fact]
public async Task Plage_BornesJournee_00h00Inclus_23h59Inclus_LendemainExclu()
{
// Arrange
DateTime jour = new(2026, 8, 12);
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), jour.Date, jour.Date.AddHours(1), "00:00"));
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), jour.Date.AddHours(23).AddMinutes(59), jour.Date.AddHours(23).AddMinutes(59).AddMinutes(1), "23:59"));
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), jour.AddDays(1).Date, jour.AddDays(1).Date.AddHours(1), "lendemain 00:00"));
// Act : plage d'un jour, borne fin exclue (lendemain 00:00).
IReadOnlyList<AgendaItem> result = await _service.GetRendezVousForRangeAsync(jour.Date, jour.Date.AddDays(1));
// Assert : 00:00 inclus, 23:59 inclus (via borne < lendemain 00:00), lendemain exclu.
Assert.Equal(2, result.Count);
Assert.Contains(result, x => x.Titre == "00:00");
Assert.Contains(result, x => x.Titre == "23:59");
Assert.DoesNotContain(result, x => x.Titre == "lendemain 00:00");
}
[Fact]
public async Task Plage_BornesSemaine_LundiInclus_DimancheInclus_LundiSuivantExclu()
{
// Arrange : 2026-08-10 est un lundi.
DateTime lundi = new(2026, 8, 10);
DateTime dimanche = lundi.AddDays(6);
DateTime lundiSuivant = lundi.AddDays(7);
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), lundi.Date, lundi.Date.AddHours(1), "lundi"));
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), dimanche.Date.AddHours(23).AddMinutes(59), dimanche.Date.AddHours(23).AddMinutes(59).AddMinutes(1), "dimanche"));
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), lundiSuivant.Date, lundiSuivant.Date.AddHours(1), "lundi suivant"));
// Act : lundi inclus → dimanche inclus, lundi suivant exclu.
IReadOnlyList<AgendaItem> result = await _service.GetRendezVousForRangeAsync(lundi, lundiSuivant);
// Assert
Assert.Equal(2, result.Count);
Assert.Contains(result, x => x.Titre == "lundi");
Assert.Contains(result, x => x.Titre == "dimanche");
Assert.DoesNotContain(result, x => x.Titre == "lundi suivant");
}
[Fact]
public async Task Plage_RendezVousPlusieursJours_VisibleChaqueJourDeSonIntervalle()
{
// Arrange : un rendez-vous groupé sur plusieurs jours (12 → 14/08).
DateTime debut = new(2026, 8, 12, 8, 0, 0);
DateTime fin = new(2026, 8, 14, 17, 0, 0);
Guid id = Guid.NewGuid();
await RendezVousRepository.UpsertAsync(CreateRendezVous(id, debut, fin, "chantier 3 jours"));
// Act / Assert : présent sur CHAQUE journée de l'intervalle…
foreach (DateTime jour in new[] { debut.Date, debut.Date.AddDays(1), fin.Date })
{
IReadOnlyList<AgendaItem> result = await _service.GetRendezVousForRangeAsync(jour, jour.AddDays(1));
AgendaItem item = Assert.Single(result);
Assert.Equal("chantier 3 jours", item.Titre);
Assert.True(item.CouvreLeJour(jour));
}
// … et absent des journées hors intervalle.
Assert.Empty(await _service.GetRendezVousForRangeAsync(fin.Date.AddDays(1), fin.Date.AddDays(2)));
Assert.Empty(await _service.GetRendezVousForRangeAsync(debut.Date.AddDays(-2), debut.Date.AddDays(-1)));
}
[Fact]
public async Task Plage_RendezVousCommenceAvantLaPlageMaisLaCouvre_ResteVisible()
{
// Arrange : un chantier commencé le 10/08 et fini le 20/08.
await RendezVousRepository.UpsertAsync(
CreateRendezVous(Guid.NewGuid(), new DateTime(2026, 8, 10, 8, 0, 0), new DateTime(2026, 8, 20, 17, 0, 0), "long"));
// Act : plage du 14 au 21/08 — le rendez-vous commence AVANT la plage.
IReadOnlyList<AgendaItem> result = await _service.GetRendezVousForRangeAsync(
new DateTime(2026, 8, 14), new DateTime(2026, 8, 21));
// Assert : il est conservé car il couvre encore la plage.
AgendaItem item = Assert.Single(result);
Assert.Equal("long", item.Titre);
}
[Fact]
public async Task Plage_JourneeUnique_RetourneLesRendezVousDuJour()
{
// Arrange
DateTime jour = new(2026, 8, 12);
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), jour.AddHours(9), jour.AddHours(10), "A"));
await RendezVousRepository.UpsertAsync(CreateRendezVous(Guid.NewGuid(), jour.AddDays(1).AddHours(9), jour.AddDays(1).AddHours(10), "B"));
// Act
IReadOnlyList<AgendaItem> result = await _service.GetRendezVousForDayAsync(jour);
// Assert : GetRendezVousForDayAsync délègue à la plage d'un jour.
AgendaItem item = Assert.Single(result);
Assert.Equal("A", item.Titre);
}
/// <summary>
/// Règle métier : un rendez-vous ARCHIVÉ ne monte jamais dans le mobile. Une
/// copie locale peut subsister (snapshot antérieur au filtre serveur, données
/// déjà synchronisées) : l'agenda ne doit jamais l'afficher.
/// </summary>
[Fact]
public async Task Plage_RendezVousArchive_NApparaitPas()
{
// Arrange : un rendez-vous courant et un rendez-vous archivé, même jour.
DateTime jour = new(2026, 8, 12);
await RendezVousRepository.UpsertAsync(
CreateRendezVous(Guid.NewGuid(), jour.AddHours(9), jour.AddHours(10), "courant"));
await RendezVousRepository.UpsertAsync(
CreateRendezVous(Guid.NewGuid(), jour.AddHours(14), jour.AddHours(15), "archivé", estArchive: true));
// Act
IReadOnlyList<AgendaItem> result = await _service.GetRendezVousForDayAsync(jour);
// Assert : seul le rendez-vous courant subsiste.
AgendaItem item = Assert.Single(result);
Assert.Equal("courant", item.Titre);
}
}