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

177 lines
8.3 KiB
C#

using Avalonia;
using Avalonia.Headless;
using Omika.App.Local.Abstractions;
using Omika.App.Local.Models;
using Omika.App.Navigation;
using Omika.App.Services;
using Omika.App.ViewModels;
using Omika.App.Views;
using Omika.Core.Contracts.Common;
using Omika.Core.Contracts.Mobile.Interventions;
using Omika.Core.Contracts.Mobile.Sync;
using Omika.Tests.Mobile;
namespace Omika.Tests.Mobile.Local;
/// <summary>
/// Tests de construction de la vue Interventions (régression runtime du
/// micro-lot 36 : la page doit pouvoir être construite avec zéro donnée,
/// sans exception d'InitializeComponent ni de binding).
/// </summary>
/// <remarks>
/// La construction d'une vue Avalonia exige les services de plateforme : les
/// tests s'exécutent donc DANS une session Avalonia headless (sinon ils échouent
/// sur « Unable to locate Avalonia.Platform.IPlatformRenderInterface »), et la
/// classe rejoint la collection « ApplicationRuntimeContext » pour ne jamais
/// s'exécuter en parallèle d'une autre session headless.
/// </remarks>
[Collection("ApplicationRuntimeContext")]
public class InterventionsViewConstructionTests : IDisposable
{
private readonly HeadlessUnitTestSession _session =
HeadlessUnitTestSession.StartNew(typeof(LayoutTestAppBuilder));
public void Dispose() => _session.Dispose();
[Fact]
public void InterventionsView_Constructible_SansException()
{
// Dispatch générique : cette surcharge ATTEND la fin de l'action, ce qui
// n'est pas le cas de Dispatch(Action) — les assertions seraient alors
// évaluées hors du test.
_session.Dispatch(
() =>
{
var view = new InterventionsView();
Assert.NotNull(view);
Assert.NotNull(view.Content);
return true;
},
CancellationToken.None).GetAwaiter().GetResult();
}
[Fact]
public void InterventionsView_AvecViewModelVide_AucuneException()
{
_session.Dispatch(
() =>
{
var viewModel = new InterventionsViewModel(
new FakeInterventionService(),
new FakeParametreMetierService(),
new NavigationService(),
new PermissionService(),
Omika.Core.Observability.NullTelemetryService.Instance);
var view = new InterventionsView { DataContext = viewModel };
Assert.NotNull(view.Content);
return true;
},
CancellationToken.None).GetAwaiter().GetResult();
}
private sealed class FakeInterventionService : IInterventionLocalService
{
public Task<IReadOnlyList<InterventionListItem>> GetInterventionsAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<InterventionListItem>>([]);
public Task<InterventionDetail?> GetInterventionByIdAsync(Guid interventionGuid, CancellationToken cancellationToken = default)
=> Task.FromResult<InterventionDetail?>(null);
public Task<Guid> CreateAsync(InterventionSyncPayload payload, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task<Guid> UpdateAsync(Guid interventionGuid, InterventionSyncPayload payload, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task<Guid> ArchiveAsync(Guid interventionGuid, CancellationToken cancellationToken = default)
=> throw new NotSupportedException();
public Task<IReadOnlyList<InterventionCardItem>> SearchAsync(MobileInterventionSearchRequest request, CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<InterventionCardItem>>([]);
public Task<IReadOnlyList<InterventionCardItem>> GetLastSearchAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<InterventionCardItem>>([]);
public Task<IReadOnlyList<InterventionCardItem>> GetPinnedAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<InterventionCardItem>>([]);
public Task SetPinnedAsync(Guid interventionGuid, bool isPinned, CancellationToken cancellationToken = default)
=> Task.CompletedTask;
public Task RefreshPinnedAsync(CancellationToken cancellationToken = default)
=> Task.CompletedTask;
public Task RefreshInterventionAsync(Guid interventionGuid, CancellationToken cancellationToken = default)
=> Task.CompletedTask;
}
private sealed class FakeParametreMetierService : IParametreMetierLocalService
{
public Task<IReadOnlyList<ReferenceValueDto>> GetTypeTempsAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<Omika.Core.Contracts.Configuration.TypeTempsParametresDto?> GetTypeTempsParametresAsync(string typeTempsKey, CancellationToken ct = default)
=> Task.FromResult<Omika.Core.Contracts.Configuration.TypeTempsParametresDto?>(null);
public Task<Omika.Core.Contracts.Configuration.TypeRdvParametresDto?> GetTypeRdvParametresAsync(string typeRdvKey, CancellationToken ct = default)
=> Task.FromResult<Omika.Core.Contracts.Configuration.TypeRdvParametresDto?>(null);
public Task<Omika.Core.Contracts.Configuration.StatutRdvParametresDto?> GetStatutRdvParametresAsync(string statutRdvKey, CancellationToken ct = default)
=> Task.FromResult<Omika.Core.Contracts.Configuration.StatutRdvParametresDto?>(null);
public Task<IReadOnlyList<ReferenceValueDto>> GetInterventionTypesAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<IReadOnlyList<ReferenceValueDto>> GetInterventionEtatsAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<IReadOnlyList<ReferenceValueDto>> GetDossierTypesAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<IReadOnlyList<ReferenceValueDto>> GetDossierStatutsAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<IReadOnlyList<ReferenceValueDto>> GetClientTypesAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<IReadOnlyList<ReferenceValueDto>> GetClientStatutsAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<IReadOnlyList<ReferenceValueDto>> GetSiteTypesAsync(CancellationToken ct = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
public Task<IReadOnlyList<ReferenceValueDto>> GetTypeSignatairesAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<ReferenceValueDto>>([]);
}
private sealed class FakeClientService : IClientLocalService
{
public Task<IReadOnlyList<ClientListItem>> GetClientsAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<ClientListItem>>([]);
public Task<ClientDetail?> GetClientByIdAsync(Guid clientGuid, CancellationToken cancellationToken = default)
=> Task.FromResult<ClientDetail?>(null);
}
private sealed class FakeSiteService : ISiteLocalService
{
public Task<IReadOnlyList<SiteListItem>> GetSitesAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<SiteListItem>>([]);
public Task<SiteDetail?> GetSiteByIdAsync(Guid siteGuid, CancellationToken cancellationToken = default)
=> Task.FromResult<SiteDetail?>(null);
}
private sealed class FakeCollaborateurService : ICollaborateurLocalService
{
public Task<IReadOnlyList<CollaborateurListItem>> GetCollaborateursAsync(CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<CollaborateurListItem>>([]);
public Task<CollaborateurDetail?> GetCollaborateurByIdAsync(Guid collaborateurGuid, CancellationToken cancellationToken = default)
=> Task.FromResult<CollaborateurDetail?>(null);
}
}