Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
using System.Text.Json;
|
||||
using Omika.App.Local.Models;
|
||||
using Omika.App.Local.Services;
|
||||
using Omika.App.Navigation;
|
||||
using Omika.App.ViewModels;
|
||||
using Omika.Core.Contracts.Organisation;
|
||||
|
||||
namespace Omika.Tests.Mobile.Local;
|
||||
|
||||
/// <summary>
|
||||
/// Tests du ViewModel de la liste des collaborateurs : chargement local,
|
||||
/// états vide/erreur, recherche locale et navigation vers la fiche
|
||||
/// Collaborateur par identité publique. Aucun appel API.
|
||||
/// </summary>
|
||||
public class CollaborateursViewModelTests : LocalTestBase
|
||||
{
|
||||
private readonly CollaborateursViewModel _viewModel;
|
||||
private readonly NavigationService _navigation;
|
||||
|
||||
public CollaborateursViewModelTests()
|
||||
{
|
||||
var service = new CollaborateurLocalService(CollaborateurRepository, RendezVousRepository, ContextInterventionCacheRepository, ApiClient, SessionService);
|
||||
_navigation = new NavigationService();
|
||||
_viewModel = new CollaborateursViewModel(service, _navigation);
|
||||
}
|
||||
|
||||
private static LocalCollaborateur CreateCollaborateur(
|
||||
Guid id,
|
||||
string? nom = null,
|
||||
string? prenom = null,
|
||||
string? code = null,
|
||||
string? statut = null,
|
||||
string? email = null)
|
||||
{
|
||||
var dto = new CollaborateurDetailsDto
|
||||
{
|
||||
Id = id.ToString(),
|
||||
Nom = nom,
|
||||
Prenom = prenom,
|
||||
Code = code,
|
||||
Statut = statut is null ? null : new Omika.Core.Contracts.Common.ReferenceValueDto { Label = statut },
|
||||
Coordonnees = email is null ? null : new Omika.Core.Contracts.Common.ContactDetailsDto { Email = email }
|
||||
};
|
||||
return new LocalCollaborateur
|
||||
{
|
||||
Id = id,
|
||||
PayloadJson = JsonSerializer.Serialize(dto),
|
||||
UpdatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_ChargementPuisListe()
|
||||
{
|
||||
// Arrange
|
||||
Guid collaborateurId = Guid.NewGuid();
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(collaborateurId, "Dupont", "Jean", "C001"));
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Assert : après chargement, liste affichée et chargement terminé.
|
||||
Assert.False(_viewModel.IsLoading);
|
||||
Assert.True(_viewModel.HasCollaborateurs);
|
||||
var item = Assert.Single(_viewModel.Collaborateurs);
|
||||
Assert.Equal(collaborateurId, item.CollaborateurGuid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_ListeVide_EmptyState()
|
||||
{
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Assert : liste vide sans erreur.
|
||||
Assert.False(_viewModel.IsLoading);
|
||||
Assert.False(_viewModel.HasCollaborateurs);
|
||||
Assert.True(_viewModel.IsEmpty);
|
||||
Assert.Null(_viewModel.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_Erreur_MessageAffiche()
|
||||
{
|
||||
// Arrange : un payload invalide ne provoque pas d'erreur (ignoré).
|
||||
await CollaborateurRepository.UpsertAsync(new LocalCollaborateur
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
PayloadJson = "not-json",
|
||||
UpdatedAtUtc = DateTimeOffset.UtcNow
|
||||
});
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Assert : l'entrée invalide est ignorée, liste vide sans erreur.
|
||||
Assert.False(_viewModel.IsLoading);
|
||||
Assert.False(_viewModel.HasCollaborateurs);
|
||||
Assert.True(_viewModel.IsEmpty);
|
||||
Assert.Null(_viewModel.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Recherche_FiltreParNom()
|
||||
{
|
||||
// Arrange
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(Guid.NewGuid(), "Dupont", "Jean", "C001"));
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(Guid.NewGuid(), "Martin", "Paul", "C002"));
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Act
|
||||
_viewModel.SearchText = "dupont";
|
||||
|
||||
// Assert : la recherche filtre par nom (insensible à la casse).
|
||||
var item = Assert.Single(_viewModel.Collaborateurs);
|
||||
Assert.Equal("Jean Dupont", item.DisplayName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Recherche_SansResultat_ListeVide()
|
||||
{
|
||||
// Arrange
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(Guid.NewGuid(), "Dupont", "Jean", "C001"));
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Act
|
||||
_viewModel.SearchText = "introuvable";
|
||||
|
||||
// Assert : aucun résultat.
|
||||
Assert.Empty(_viewModel.Collaborateurs);
|
||||
Assert.False(_viewModel.HasCollaborateurs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Recherche_Reinitialise_RetourneTous()
|
||||
{
|
||||
// Arrange
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(Guid.NewGuid(), "Dupont", "Jean", "C001"));
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(Guid.NewGuid(), "Martin", "Paul", "C002"));
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Act : recherche puis réinitialisation.
|
||||
_viewModel.SearchText = "dupont";
|
||||
Assert.Single(_viewModel.Collaborateurs);
|
||||
_viewModel.SearchText = string.Empty;
|
||||
|
||||
// Assert : tous les collaborateurs sont de nouveau affichés.
|
||||
Assert.Equal(2, _viewModel.Collaborateurs.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenCollaborateur_NavigueVersDetail()
|
||||
{
|
||||
// Arrange
|
||||
Guid collaborateurId = Guid.NewGuid();
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(collaborateurId, "Dupont", "Jean", "C001"));
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Act
|
||||
_viewModel.OpenCollaborateurCommand.Execute(_viewModel.Collaborateurs[0]);
|
||||
|
||||
// Assert : navigation vers la fiche Collaborateur avec le GUID public.
|
||||
Assert.Equal(AppPage.CollaborateurDetail, _navigation.CurrentPage);
|
||||
Assert.Equal(collaborateurId, _navigation.CurrentParameter);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenCollaborateur_Null_NeNaviguePas()
|
||||
{
|
||||
// Act
|
||||
_viewModel.OpenCollaborateurCommand.Execute(null);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(AppPage.Home, _navigation.CurrentPage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FonctionneOffline_SansAppelApi()
|
||||
{
|
||||
// Arrange : aucune dépendance réseau, uniquement SQLite local.
|
||||
await CollaborateurRepository.UpsertAsync(CreateCollaborateur(Guid.NewGuid(), "Dupont", "Jean", "C001"));
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(null);
|
||||
|
||||
// Assert
|
||||
Assert.True(_viewModel.HasCollaborateurs);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user