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

729 lines
26 KiB
C#

using Omika.App.Local.Abstractions;
using Omika.App.Local.Models;
using Omika.App.Local.Services;
using Omika.App.Navigation;
using Omika.App.ViewModels;
using Omika.Core.Contracts.Configuration;
using Omika.Core.Contracts.Mobile.License;
namespace Omika.Tests.Mobile.Local;
/// <summary>
/// Tests du ViewModel Agenda d'équipe : deux filtres indépendants (équipe +
/// collaborateur), exclusion mutuelle, chargement à la demande (API), groupement
/// par date et navigation vers les fiches rendez-vous.
/// </summary>
public class AgendaEquipeViewModelTests
{
private readonly NavigationService _navigation = new();
public AgendaEquipeViewModelTests()
{
// L'état de session est statique : on le réinitialise avant chaque test
// pour éviter les fuites entre scénarios.
AgendaEquipeViewModel.ResetSessionState();
}
private AgendaEquipeViewModel CreateViewModel(
IReadOnlyList<EquipeListItem> equipes,
IReadOnlyList<CollaborateurListItem> collaborateurs,
IReadOnlyList<AgendaItem> agendaItems,
DateTime? date = null,
IReadOnlyList<ParametreMetierDto>? parametresMetier = null,
StubParametreMetierService? parametreMetierService = null)
{
var viewModel = new AgendaEquipeViewModel(
new FakeAgendaService(agendaItems),
new FakeEquipeService(equipes),
new FakeCollaborateurService(collaborateurs),
_navigation,
new FakeSessionService(parametresMetier ?? [MobileTypeRdvParam()]),
parametreMetierService ?? new StubParametreMetierService(),
new RendezVousStateNotifier());
if (date is not null)
{
viewModel.SelectedDateOffset = date;
}
return viewModel;
}
private static CollaborateurListItem Membre(Guid id, string nom)
=> new() { CollaborateurGuid = id, DisplayName = nom };
private static AgendaItem Item(Guid id, DateTime debut, params Guid[] collaborateurs)
=> new()
{
RendezVousGuid = id,
Titre = "RDV",
Debut = debut,
Fin = debut.AddHours(1),
TypeActivite = "Intervention",
TypeActiviteKey = "T.RDV.INTER",
CollaborateurGuids = collaborateurs
};
private static ParametreMetierDto MobileTypeRdvParam()
=> new()
{
Id = "T.RDV.INTER",
Code = "14",
Categorie = "T.RDV",
Libelle = "Intervention",
Parametre = """{"Envoi_mobile":1}"""
};
[Fact]
public async Task Initialise_ConstruitLesDeuxFiltres()
{
// Arrange
Guid alice = Guid.NewGuid();
Guid bob = Guid.NewGuid();
Guid solo = Guid.NewGuid();
var equipe = new EquipeListItem
{
EquipeGuid = Guid.NewGuid(),
Nom = "Équipe A",
Membres = [Membre(alice, "Alice"), Membre(bob, "Bob")]
};
// Act
AgendaEquipeViewModel vm = CreateViewModel([equipe], [Membre(solo, "Solo")], []);
await vm.InitializeAsync();
// Assert : deux listes distinctes, aucune sélection par défaut.
Assert.Single(vm.Equipes);
Assert.Equal("👥 Équipe A", vm.Equipes[0].Label);
Assert.Equal(
new[] { alice, bob }.OrderBy(g => g).ToArray(),
vm.Equipes[0].CollaborateurGuids.OrderBy(g => g).ToArray());
Assert.Single(vm.Collaborateurs);
Assert.Equal("👤 Solo", vm.Collaborateurs[0].Label);
Assert.Null(vm.SelectedEquipe);
Assert.Null(vm.SelectedCollaborateur);
Assert.False(vm.HasSelection);
}
[Fact]
public async Task FiltreParEquipe_ChargeLesRendezVousDeLEquipe()
{
// Arrange
Guid alice = Guid.NewGuid();
Guid autre = Guid.NewGuid();
DateTime jour = new(2026, 8, 12);
var equipe = new EquipeListItem
{
EquipeGuid = Guid.NewGuid(),
Nom = "Équipe A",
Membres = [Membre(alice, "Alice")]
};
var items = new[]
{
Item(Guid.NewGuid(), jour.AddHours(9), alice),
Item(Guid.NewGuid(), jour.AddHours(11), autre)
};
AgendaEquipeViewModel vm = CreateViewModel([equipe], [], items, jour);
await vm.InitializeAsync();
// Act : sélection de l'équipe.
vm.SelectedEquipe = vm.Equipes[0];
// Assert : seul le rendez-vous de la membre de l'équipe est chargé.
Assert.True(vm.HasAppointments);
Assert.Single(vm.DayGroups);
AgendaItem item = Assert.Single(vm.DayGroups[0].Items);
Assert.Equal(alice, item.CollaborateurGuids.Single());
}
[Fact]
public async Task FiltreParCollaborateur_ChargeSesRendezVous()
{
// Arrange
Guid solo = Guid.NewGuid();
Guid autre = Guid.NewGuid();
DateTime jour = new(2026, 8, 12);
var items = new[]
{
Item(Guid.NewGuid(), jour.AddHours(9), solo),
Item(Guid.NewGuid(), jour.AddHours(11), autre)
};
AgendaEquipeViewModel vm = CreateViewModel([], [Membre(solo, "Solo")], items, jour);
await vm.InitializeAsync();
// Act : sélection du collaborateur.
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Assert
Assert.True(vm.HasAppointments);
Assert.Single(vm.DayGroups);
AgendaItem item = Assert.Single(vm.DayGroups[0].Items);
Assert.Equal(solo, item.CollaborateurGuids.Single());
}
[Fact]
public async Task SelectionEquipe_EffaceLeCollaborateur()
{
// Arrange
Guid alice = Guid.NewGuid();
Guid solo = Guid.NewGuid();
var equipe = new EquipeListItem
{
EquipeGuid = Guid.NewGuid(),
Nom = "Équipe A",
Membres = [Membre(alice, "Alice")]
};
AgendaEquipeViewModel vm = CreateViewModel([equipe], [Membre(solo, "Solo")], []);
await vm.InitializeAsync();
// Act : collaborateur puis équipe.
vm.SelectedCollaborateur = vm.Collaborateurs[0];
vm.SelectedEquipe = vm.Equipes[0];
// Assert : l'équipe l'emporte, le collaborateur est effacé.
Assert.Equal(vm.Equipes[0], vm.SelectedEquipe);
Assert.Null(vm.SelectedCollaborateur);
}
[Fact]
public async Task SelectionCollaborateur_EffaceLEquipe()
{
// Arrange
Guid alice = Guid.NewGuid();
Guid solo = Guid.NewGuid();
var equipe = new EquipeListItem
{
EquipeGuid = Guid.NewGuid(),
Nom = "Équipe A",
Membres = [Membre(alice, "Alice")]
};
AgendaEquipeViewModel vm = CreateViewModel([equipe], [Membre(solo, "Solo")], []);
await vm.InitializeAsync();
// Act : équipe puis collaborateur.
vm.SelectedEquipe = vm.Equipes[0];
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Assert : le collaborateur l'emporte, l'équipe est effacée.
Assert.Equal(vm.Collaborateurs[0], vm.SelectedCollaborateur);
Assert.Null(vm.SelectedEquipe);
}
[Fact]
public async Task EquipeSelectionnee_ExposeSesMembres()
{
// Arrange
Guid alice = Guid.NewGuid();
Guid bob = Guid.NewGuid();
var equipe = new EquipeListItem
{
EquipeGuid = Guid.NewGuid(),
Nom = "Équipe A",
Membres = [Membre(alice, "Alice"), Membre(bob, "Bob")]
};
AgendaEquipeViewModel vm = CreateViewModel([equipe], [], []);
await vm.InitializeAsync();
// Act
vm.SelectedEquipe = vm.Equipes[0];
// Assert : les noms des membres sont exposés pour l'affichage.
Assert.True(vm.HasSelectedEquipeMembres);
Assert.Equal(["Alice", "Bob"], vm.SelectedEquipeMembres);
}
[Fact]
public async Task EquipeAvecSociete_LibelleInclutLaSociete()
{
// Arrange
var equipe = new EquipeListItem
{
EquipeGuid = Guid.NewGuid(),
Nom = "Pose",
SocieteNom = "Groupe GAP",
Membres = [Membre(Guid.NewGuid(), "Alice")]
};
// Act
AgendaEquipeViewModel vm = CreateViewModel([equipe], [], []);
await vm.InitializeAsync();
// Assert
AgendaScopeOption option = Assert.Single(vm.Equipes);
Assert.Equal("👥 Pose (Groupe GAP)", option.Label);
}
[Fact]
public async Task Groupement_ParDate()
{
// Arrange : deux jours distincts de la même semaine, même collaborateur.
Guid solo = Guid.NewGuid();
DateTime jour = new(2026, 8, 12); // mercredi
var items = new[]
{
Item(Guid.NewGuid(), jour.AddHours(9), solo),
Item(Guid.NewGuid(), jour.AddDays(1).AddHours(9), solo)
};
AgendaEquipeViewModel vm = CreateViewModel([], [Membre(solo, "Solo")], items, jour);
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Assert : deux groupes (un par jour), ordonnés chronologiquement.
Assert.Equal(2, vm.DayGroups.Count);
Assert.Equal(jour, vm.DayGroups[0].Date);
Assert.Equal(jour.AddDays(1), vm.DayGroups[1].Date);
}
[Fact]
public async Task SansSelection_EtatVide()
{
// Act
AgendaEquipeViewModel vm = CreateViewModel([], [], [], new DateTime(2026, 8, 12));
await vm.InitializeAsync();
// Assert
Assert.False(vm.HasAppointments);
Assert.True(vm.IsEmpty);
Assert.False(vm.HasSelection);
Assert.Equal("Aucun périmètre sélectionné", vm.EmptyStateTitle);
}
[Fact]
public async Task AvecSelectionSansRdv_EtatVide()
{
// Arrange
Guid solo = Guid.NewGuid();
// Act
AgendaEquipeViewModel vm = CreateViewModel([], [Membre(solo, "Solo")], [], new DateTime(2026, 8, 12));
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Assert
Assert.True(vm.IsEmpty);
Assert.True(vm.HasSelection);
Assert.Equal("Aucun rendez-vous", vm.EmptyStateTitle);
}
[Fact]
public async Task PreviousNextWeek_ChangeLaSemaine()
{
// Arrange
DateTime jour = new(2026, 8, 12);
AgendaEquipeViewModel vm = CreateViewModel([], [Membre(Guid.NewGuid(), "Solo")], [], jour);
await vm.InitializeAsync();
// Act
await vm.NextWeekCommand.ExecuteAsync(null);
// Assert : la date a avancé de 7 jours.
Assert.Equal(jour.AddDays(7), vm.SelectedDate);
// Act
await vm.PreviousWeekCommand.ExecuteAsync(null);
// Assert : retour à la semaine initiale.
Assert.Equal(jour, vm.SelectedDate);
}
[Fact]
public async Task OpenRendezVous_NavigueVersDetail()
{
// Arrange
Guid rdvId = Guid.NewGuid();
Guid solo = Guid.NewGuid();
DateTime jour = new(2026, 8, 12);
AgendaEquipeViewModel vm = CreateViewModel(
[],
[Membre(solo, "Solo")],
[Item(rdvId, jour.AddHours(9), solo)],
jour);
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Act
AgendaItem item = vm.DayGroups[0].Items[0];
vm.OpenRendezVousCommand.Execute(item);
// Assert : la fiche reçoit l'élément complet (déjà enrichi) pour ne pas
// recharger par GUID (hors snapshot local).
Assert.Equal(AppPage.RendezVousDetail, _navigation.CurrentPage);
Assert.Same(item, _navigation.CurrentParameter);
}
[Fact]
public async Task OpenRendezVous_NonEnvoyeMobile_BloqueNavigation()
{
// Arrange : un rendez-vous de type « CP » (non « Envoi_mobile ») de l'équipe.
Guid rdvId = Guid.NewGuid();
Guid solo = Guid.NewGuid();
DateTime jour = new(2026, 8, 12);
var item = new AgendaItem
{
RendezVousGuid = rdvId,
Titre = "CP",
Debut = jour.AddHours(9),
Fin = jour.AddHours(10),
TypeActivite = "CP",
TypeActiviteKey = "CP",
CollaborateurGuids = [solo]
};
AgendaEquipeViewModel vm = CreateViewModel(
[],
[Membre(solo, "Solo")],
[item],
jour);
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Act
AgendaItem loaded = vm.DayGroups[0].Items[0];
Assert.False(loaded.EstEnvoyeMobile);
vm.OpenRendezVousCommand.Execute(loaded);
// Assert : aucune navigation vers le détail (le RDV reste consultable uniquement).
Assert.Equal(AppPage.Home, _navigation.CurrentPage);
}
[Fact]
public async Task Back_SansHistorique_RetourneAccueil()
{
// Act
AgendaEquipeViewModel vm = CreateViewModel([], [], []);
await vm.InitializeAsync();
vm.BackCommand.Execute(null);
// Assert
Assert.Equal(AppPage.Home, _navigation.CurrentPage);
}
[Fact]
public async Task ShowCalendar_PasseEnModeCalendrier()
{
// Arrange
AgendaEquipeViewModel vm = CreateViewModel([], [Membre(Guid.NewGuid(), "Solo")], []);
await vm.InitializeAsync();
// Act
vm.ShowCalendarCommand.Execute(null);
// Assert
Assert.True(vm.IsCalendarMode);
Assert.False(vm.IsListMode);
}
[Fact]
public async Task MonthDays_Contient42Jours_EnModeCalendrier()
{
// Arrange
Guid solo = Guid.NewGuid();
DateTime jour = new(2026, 8, 12);
AgendaEquipeViewModel vm = CreateViewModel(
[],
[Membre(solo, "Solo")],
[Item(Guid.NewGuid(), jour.AddHours(9), solo)],
jour);
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Act
vm.ShowCalendarCommand.Execute(null);
// Assert
Assert.True(vm.IsCalendarMode);
Assert.Equal(42, vm.MonthDays.Count);
Assert.Equal(new DateTime(2026, 7, 27), vm.MonthDays[0].Date);
AgendaMonthDayItem cell = vm.MonthDays.Single(d => d.Date == jour);
Assert.True(cell.HasAppointments);
Assert.Single(cell.Appointments);
}
[Fact]
public async Task SelectCalendarDay_OuvreLaVueJour()
{
// Arrange
Guid solo = Guid.NewGuid();
DateTime jour = new(2026, 8, 12);
AgendaEquipeViewModel vm = CreateViewModel([], [Membre(solo, "Solo")], [], jour);
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
vm.ShowCalendarCommand.Execute(null);
AgendaMonthDayItem target = vm.MonthDays.Single(d => d.Date == new DateTime(2026, 8, 13));
// Act
vm.SelectCalendarDayCommand.Execute(target);
// Assert
Assert.False(vm.IsCalendarMode);
Assert.True(vm.IsDayMode);
Assert.Equal(new DateTime(2026, 8, 13), vm.SelectedDate);
}
private sealed class FakeAgendaService : IAgendaService
{
private readonly IReadOnlyList<AgendaItem> _items;
public FakeAgendaService(IReadOnlyList<AgendaItem> items)
{
_items = items;
}
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForCollaborateursAsync(
IReadOnlyList<Guid> collaborateurGuids,
DateTime startInclusive,
DateTime endExclusive,
CancellationToken cancellationToken = default)
{
var set = collaborateurGuids.ToHashSet();
return Task.FromResult<IReadOnlyList<AgendaItem>>(
_items.Where(i => i.CollaborateurGuids.Any(g => set.Contains(g))).ToList());
}
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForCollaborateurAsync(Guid collaborateurGuid, DateTime startInclusive, DateTime endExclusive, CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<AgendaItem>>([]);
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForDayAsync(DateTime date, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForRangeAsync(DateTime startInclusive, DateTime endExclusive, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task<AgendaItem?> GetRendezVousByIdAsync(Guid rendezVousGuid, CancellationToken cancellationToken = default, string? affectationId = null)
=> throw new NotSupportedException();
public Task EnrichSiteAccessAsync(AgendaItem item, CancellationToken cancellationToken = default)
=> Task.CompletedTask;
}
private sealed class FakeEquipeService : IEquipeLocalService
{
private readonly IReadOnlyList<EquipeListItem> _equipes;
public FakeEquipeService(IReadOnlyList<EquipeListItem> equipes)
{
_equipes = equipes;
}
public Task<IReadOnlyList<EquipeListItem>> GetEquipesAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(_equipes);
public Task<IReadOnlyList<EquipeListItem>> GetAllEquipesAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(_equipes);
}
private sealed class FakeCollaborateurService : ICollaborateurLocalService
{
private readonly IReadOnlyList<CollaborateurListItem> _collaborateurs;
public FakeCollaborateurService(IReadOnlyList<CollaborateurListItem> collaborateurs)
{
_collaborateurs = collaborateurs;
}
public Task<IReadOnlyList<CollaborateurListItem>> GetCollaborateursAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(_collaborateurs);
public Task<CollaborateurDetail?> GetCollaborateurByIdAsync(Guid collaborateurGuid, CancellationToken cancellationToken = default)
=> Task.FromResult<CollaborateurDetail?>(null);
}
private sealed class FakeSessionService : IMobileSessionService
{
private readonly IReadOnlyList<ParametreMetierDto> _parametresMetier;
public FakeSessionService(IReadOnlyList<ParametreMetierDto> parametresMetier)
=> _parametresMetier = parametresMetier;
public Task<LocalBootstrapState?> GetBootstrapAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<LocalBootstrapState?>(new LocalBootstrapState { ParametresMetier = _parametresMetier });
public Task<bool> HasValidSessionAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(false);
public Task<bool> HasExpiredSessionAsync(CancellationToken cancellationToken = default)
=> Task.FromResult(false);
public Task<LicenseResponse> ActivateAsync(string codeClient, string numeroLicence, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
public Task<LicenseResponse> ValidateAsync(CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
public Task<string?> GetAccessTokenAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<string?>(null);
public Task ClearSessionAsync(CancellationToken cancellationToken = default)
=> Task.CompletedTask;
public Task EnsureDevelopmentSessionAsync(CancellationToken cancellationToken = default)
=> Task.CompletedTask;
}
[Fact]
public async Task Load_AnnulationSousIOException_TokenAnnule_MasqueLErreur()
{
Guid solo = Guid.NewGuid();
var agenda = new FakeThrowingAgendaService();
var vm = new AgendaEquipeViewModel(
agenda,
new FakeEquipeService([]),
new FakeCollaborateurService([Membre(solo, "Solo")]),
_navigation,
new FakeSessionService([MobileTypeRdvParam()]),
new StubParametreMetierService(),
new RendezVousStateNotifier());
// Sélection d'un collaborateur sans erreur (le service ne lève pas encore).
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
// Puis annulation remontée sous IOException pendant un refresh annulé.
agenda.ExceptionToThrow = new IOException("Canceled");
using var cts = new CancellationTokenSource();
cts.Cancel();
await vm.RefreshAsync(cts.Token);
Assert.False(vm.IsLoading);
Assert.Null(vm.ErrorMessage);
}
/// <summary>
/// Une indisponibilité réseau n'est pas une erreur utilisateur : l'agenda d'équipe
/// signale l'état hors ligne (bandeau) sans message bloquant et sans état vide
/// trompeur — même langage que l'agenda personnel.
/// </summary>
[Fact]
public async Task Load_IOExceptionReelle_TokenNonAnnule_SignaleHorsLigne()
{
Guid solo = Guid.NewGuid();
var agenda = new FakeThrowingAgendaService { ExceptionToThrow = new IOException("Network unreachable") };
var vm = new AgendaEquipeViewModel(
agenda,
new FakeEquipeService([]),
new FakeCollaborateurService([Membre(solo, "Solo")]),
_navigation,
new FakeSessionService([MobileTypeRdvParam()]),
new StubParametreMetierService(),
new RendezVousStateNotifier());
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
await vm.RefreshAsync(CancellationToken.None);
Assert.True(vm.IsOffline);
Assert.Null(vm.ErrorMessage);
// Hors ligne ≠ planning vide : ne pas afficher « aucun rendez-vous ».
Assert.False(vm.IsEmpty);
}
/// <summary>
/// Contre-épreuve : une erreur NON réseau reste un incident affiché, avec son
/// message (elle n'est pas traduite et n'active pas le bandeau hors ligne).
/// </summary>
[Fact]
public async Task Load_ErreurMetier_ConserveLeMessageEtLErreur()
{
Guid solo = Guid.NewGuid();
var agenda = new FakeThrowingAgendaService { ExceptionToThrow = new InvalidOperationException("panne métier") };
var vm = new AgendaEquipeViewModel(
agenda,
new FakeEquipeService([]),
new FakeCollaborateurService([Membre(solo, "Solo")]),
_navigation,
new FakeSessionService([MobileTypeRdvParam()]),
new StubParametreMetierService(),
new RendezVousStateNotifier());
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
await vm.RefreshAsync(CancellationToken.None);
Assert.Equal("panne métier", vm.ErrorMessage);
Assert.False(vm.IsOffline);
}
/// <summary>
/// Aucune URL d'API configurée (appareil non inscrit) : état actionnable, pas
/// « hors ligne » — l'appareil peut être en ligne et l'utilisateur doit savoir
/// qu'il lui reste à rescanner le QR.
/// </summary>
[Fact]
public async Task Load_SansUrlDApi_SignaleLInscriptionIncompleteSansBandeauHorsLigne()
{
Guid solo = Guid.NewGuid();
var agenda = new FakeThrowingAgendaService
{
ExceptionToThrow = new MobileEnrollmentRequiredException()
};
var vm = new AgendaEquipeViewModel(
agenda,
new FakeEquipeService([]),
new FakeCollaborateurService([Membre(solo, "Solo")]),
_navigation,
new FakeSessionService([MobileTypeRdvParam()]),
new StubParametreMetierService(),
new RendezVousStateNotifier());
await vm.InitializeAsync();
vm.SelectedCollaborateur = vm.Collaborateurs[0];
await vm.RefreshAsync(CancellationToken.None);
Assert.False(vm.IsOffline);
Assert.Equal(
"Inscription incomplète — rescannez le QR code pour reconnecter l'application.",
vm.ErrorMessage);
}
/// <summary>Service d'agenda jetable dont la lecture d'équipe peut lever une exception configurée.</summary>
private sealed class FakeThrowingAgendaService : IAgendaService
{
public Exception? ExceptionToThrow { get; set; }
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForCollaborateursAsync(
IReadOnlyList<Guid> collaborateurGuids, DateTime startInclusive, DateTime endExclusive, CancellationToken cancellationToken = default)
{
if (ExceptionToThrow is { } ex)
{
throw ex;
}
return Task.FromResult<IReadOnlyList<AgendaItem>>([]);
}
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForCollaborateurAsync(Guid collaborateurGuid, DateTime startInclusive, DateTime endExclusive, CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<AgendaItem>>([]);
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForDayAsync(DateTime date, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task<IReadOnlyList<AgendaItem>> GetRendezVousForRangeAsync(DateTime startInclusive, DateTime endExclusive, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task<AgendaItem?> GetRendezVousByIdAsync(Guid rendezVousGuid, CancellationToken cancellationToken = default, string? affectationId = null)
=> throw new NotSupportedException();
public Task EnrichSiteAccessAsync(AgendaItem item, CancellationToken cancellationToken = default)
=> Task.CompletedTask;
}
}