Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
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.Clients;
|
||||
using Omika.Core.Contracts.Common;
|
||||
using Omika.Core.Contracts.Interventions;
|
||||
using Omika.Core.Contracts.Sites;
|
||||
|
||||
namespace Omika.Tests.Mobile.Local;
|
||||
|
||||
/// <summary>
|
||||
/// Tests du ViewModel du détail d'un dossier : chargement, état introuvable,
|
||||
/// données affichées, interventions liées et navigation vers une intervention.
|
||||
/// </summary>
|
||||
public class DossierDetailViewModelTests : LocalTestBase
|
||||
{
|
||||
private readonly DossierDetailViewModel _viewModel;
|
||||
private readonly NavigationService _navigation;
|
||||
|
||||
public DossierDetailViewModelTests()
|
||||
{
|
||||
var service = new DossierLocalService(DossierRepository, ClientRepository, DossierStateRepository, DossierInterventionCacheRepository, ApiClient);
|
||||
var clientService = new ClientLocalService(ClientRepository, DossierRepository, ContextInterventionCacheRepository, ClientStateRepository, ApiClient);
|
||||
_navigation = new NavigationService();
|
||||
_viewModel = new DossierDetailViewModel(service, clientService, _navigation);
|
||||
}
|
||||
|
||||
private static LocalDossier CreateDossier(Guid id, string reference, string titre, Guid? clientId = null, Guid? siteId = null)
|
||||
{
|
||||
var dto = new DossierDetailsDto
|
||||
{
|
||||
Id = id.ToString(),
|
||||
ReferenceMetier = reference,
|
||||
Titre = titre,
|
||||
ClientId = clientId?.ToString(),
|
||||
SiteId = siteId?.ToString(),
|
||||
Statut = new ReferenceValueDto { Label = "Ouvert" }
|
||||
};
|
||||
return new LocalDossier
|
||||
{
|
||||
Id = id,
|
||||
ClientId = clientId,
|
||||
SiteId = siteId,
|
||||
PayloadJson = JsonSerializer.Serialize(dto),
|
||||
UpdatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
private static LocalSite CreateSite(Guid id, string nom)
|
||||
{
|
||||
var dto = new SiteDetailsDto { Id = id.ToString(), Nom = nom };
|
||||
return new LocalSite
|
||||
{
|
||||
Id = id,
|
||||
PayloadJson = JsonSerializer.Serialize(dto),
|
||||
UpdatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
private static LocalClient CreateClient(Guid id, string nom)
|
||||
{
|
||||
var dto = new ClientDetailsDto
|
||||
{
|
||||
Id = id.ToString(),
|
||||
Nom = nom
|
||||
};
|
||||
return new LocalClient
|
||||
{
|
||||
Id = id,
|
||||
PayloadJson = JsonSerializer.Serialize(dto),
|
||||
UpdatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
private static LocalIntervention CreateIntervention(Guid id, Guid dossierId, string reference, string titre)
|
||||
{
|
||||
var dto = new InterventionDetailsDto
|
||||
{
|
||||
Id = id.ToString(),
|
||||
Reference = reference,
|
||||
Titre = titre,
|
||||
DossierId = dossierId.ToString()
|
||||
};
|
||||
return new LocalIntervention
|
||||
{
|
||||
Id = id,
|
||||
DossierId = dossierId,
|
||||
PayloadJson = JsonSerializer.Serialize(dto),
|
||||
UpdatedAtUtc = DateTimeOffset.UtcNow
|
||||
};
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_ChargementPuisDetail()
|
||||
{
|
||||
// Arrange
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "Dossier A"));
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
// Assert : après chargement, détail affiché et chargement terminé.
|
||||
Assert.False(_viewModel.IsLoading);
|
||||
Assert.NotNull(_viewModel.Dossier);
|
||||
Assert.Equal("DOS-001", _viewModel.Dossier.Reference);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_DossierIntrouvable_MessageErreur()
|
||||
{
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(Guid.NewGuid());
|
||||
|
||||
// Assert
|
||||
Assert.False(_viewModel.IsLoading);
|
||||
Assert.NotNull(_viewModel.ErrorMessage);
|
||||
Assert.Null(_viewModel.Dossier);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_DonneesAffichees()
|
||||
{
|
||||
// Arrange
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "Dossier A"));
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(_viewModel.Dossier);
|
||||
Assert.Equal("DOS-001", _viewModel.Dossier.Reference);
|
||||
Assert.Equal("Dossier A", _viewModel.Dossier.Titre);
|
||||
Assert.Equal("Ouvert", _viewModel.Dossier.Statut);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_InterventionsLiees()
|
||||
{
|
||||
// Arrange : cache contextuel (pas la table historique Intervention).
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
Guid interventionId = Guid.NewGuid();
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "A"));
|
||||
await DossierInterventionCacheRepository.ReplaceAsync(
|
||||
dossierId,
|
||||
[new InterventionDetailsDto { Id = interventionId.ToString(), Reference = "INT-001", Titre = "Intervention" }]);
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
// Assert
|
||||
Assert.True(_viewModel.HasInterventions);
|
||||
var intervention = Assert.Single(_viewModel.Interventions);
|
||||
Assert.Equal(interventionId, intervention.InterventionGuid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenIntervention_NavigueVersDetail()
|
||||
{
|
||||
// Arrange : cache contextuel.
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
Guid interventionId = Guid.NewGuid();
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "A"));
|
||||
await DossierInterventionCacheRepository.ReplaceAsync(
|
||||
dossierId,
|
||||
[new InterventionDetailsDto { Id = interventionId.ToString(), Reference = "INT-001", Titre = "Intervention" }]);
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
// Act
|
||||
_viewModel.OpenInterventionCommand.Execute(_viewModel.Interventions[0]);
|
||||
|
||||
// Assert : navigation vers le détail de l'intervention avec le GUID public et le retour vers la fiche Dossier.
|
||||
Assert.Equal(AppPage.InterventionDetail, _navigation.CurrentPage);
|
||||
var nav = Assert.IsType<DetailNavigation>(_navigation.CurrentParameter);
|
||||
Assert.Equal(interventionId, nav.Id);
|
||||
Assert.Equal(AppPage.DossierDetail, nav.ReturnContext.Page);
|
||||
Assert.Equal(dossierId, nav.ReturnContext.Parameter);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenIntervention_Null_NeNaviguePas()
|
||||
|
||||
{
|
||||
// Act
|
||||
_viewModel.OpenInterventionCommand.Execute(null);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(AppPage.Home, _navigation.CurrentPage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Back_RetourneALaListe()
|
||||
{
|
||||
// Act
|
||||
_viewModel.BackCommand.Execute(null);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(AppPage.Dossiers, _navigation.CurrentPage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_SansIntervention_EtatVide()
|
||||
{
|
||||
// Arrange
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "A"));
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
// Assert : dossier valide sans intervention.
|
||||
Assert.NotNull(_viewModel.Dossier);
|
||||
Assert.False(_viewModel.HasInterventions);
|
||||
Assert.Empty(_viewModel.Interventions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_AvecClient_HasClientVrai()
|
||||
{
|
||||
// Arrange
|
||||
Guid clientId = Guid.NewGuid();
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
await ClientRepository.UpsertAsync(CreateClient(clientId, "Client Alpha"));
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "A", clientId));
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
// Assert
|
||||
Assert.True(_viewModel.HasClient);
|
||||
Assert.Equal("Client Alpha", _viewModel.Dossier!.ClientNom);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_SansClient_HasClientFaux()
|
||||
{
|
||||
// Arrange
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "A"));
|
||||
|
||||
// Act
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
// Assert
|
||||
Assert.False(_viewModel.HasClient);
|
||||
Assert.Null(_viewModel.Dossier!.ClientGuid);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Load_NeReintroduitPasSite()
|
||||
{
|
||||
// La règle métier du lot 37B : le détail Dossier n'expose pas de Site.
|
||||
Guid dossierId = Guid.NewGuid();
|
||||
await DossierRepository.UpsertAsync(CreateDossier(dossierId, "DOS-001", "A"));
|
||||
|
||||
await _viewModel.LoadCommand.ExecuteAsync(dossierId);
|
||||
|
||||
Assert.NotNull(_viewModel.Dossier);
|
||||
Assert.Null(_viewModel.Dossier!.SiteNom);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user