242 lines
8.1 KiB
C#
242 lines
8.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Headless;
|
|
using Avalonia.Threading;
|
|
using Avalonia.VisualTree;
|
|
using Omika.App.Local.Models;
|
|
using Omika.App.Navigation;
|
|
using Omika.App.Services;
|
|
using Omika.App.ViewModels;
|
|
using Omika.App.Views;
|
|
using Omika.Core.Constants;
|
|
using Xunit;
|
|
|
|
namespace Omika.Tests.Mobile;
|
|
|
|
/// <summary>
|
|
/// Les blocs « Informations » (fiche Client) et « Accès et note » (fiche Site)
|
|
/// n'ont plus de titre (les champs sont explicites) et ne sont plus affichés du
|
|
/// tout quand aucune information n'est renseignée : plus de carte vide.
|
|
/// Ces tests inspectent l'arbre visuel RÉELLEMENT affiché.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Session Avalonia headless : la classe rejoint la collection
|
|
/// « ApplicationRuntimeContext » pour qu'aucune autre session Avalonia ne
|
|
/// tourne en parallèle (le localisateur d'Avalonia est global au processus).
|
|
/// </remarks>
|
|
[Collection("ApplicationRuntimeContext")]
|
|
public sealed class BlocsInformationsFicheTests : IDisposable
|
|
{
|
|
private readonly HeadlessUnitTestSession _session =
|
|
HeadlessUnitTestSession.StartNew(typeof(LayoutTestAppBuilder));
|
|
|
|
public void Dispose() => _session.Dispose();
|
|
|
|
// ===== Fiche Client =====
|
|
|
|
[Fact]
|
|
public void FicheClient_BlocInformations_MasqueQuandVide_EtSansTitre()
|
|
{
|
|
Executer(() =>
|
|
{
|
|
var vueModele = new ClientDetailViewModel(null!, new NavigationService(), Permissions())
|
|
{
|
|
Client = new ClientDetail
|
|
{
|
|
ClientGuid = Guid.NewGuid(),
|
|
Nom = "REPETTO IMMOBILIER",
|
|
Code = "CLI-00123"
|
|
}
|
|
};
|
|
|
|
Window fenetre = MesureGeometrique.Ouvrir(new ClientDetailView { DataContext = vueModele }, 420);
|
|
|
|
IReadOnlyList<string> textes = TextesAffiches(fenetre);
|
|
|
|
// Aucune information renseignée : le bloc entier disparaît.
|
|
Assert.DoesNotContain("Informations", textes);
|
|
Assert.DoesNotContain("Forme juridique", textes);
|
|
Assert.DoesNotContain("SIREN", textes);
|
|
Assert.DoesNotContain("SIRET", textes);
|
|
Assert.DoesNotContain("Pays", textes);
|
|
Assert.DoesNotContain("Note", textes);
|
|
|
|
// Le reste de la fiche reste affiché.
|
|
Assert.Contains("REPETTO IMMOBILIER", textes);
|
|
Assert.Contains("← Retour", textes);
|
|
|
|
fenetre.Close();
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void FicheClient_BlocInformations_AfficheSansTitre_QuandRenseigne()
|
|
{
|
|
Executer(() =>
|
|
{
|
|
var vueModele = new ClientDetailViewModel(null!, new NavigationService(), Permissions())
|
|
{
|
|
Client = new ClientDetail
|
|
{
|
|
ClientGuid = Guid.NewGuid(),
|
|
Nom = "REPETTO IMMOBILIER",
|
|
FormeJuridique = "SARL",
|
|
InformationsComplementaires = "Client historique depuis 2011."
|
|
}
|
|
};
|
|
|
|
Window fenetre = MesureGeometrique.Ouvrir(new ClientDetailView { DataContext = vueModele }, 420);
|
|
|
|
IReadOnlyList<string> textes = TextesAffiches(fenetre);
|
|
|
|
// Les champs renseignés sont affichés, sans titre de bloc.
|
|
Assert.Contains("Forme juridique", textes);
|
|
Assert.Contains("SARL", textes);
|
|
Assert.Contains("Note", textes);
|
|
Assert.Contains("Client historique depuis 2011.", textes);
|
|
Assert.DoesNotContain("Informations", textes);
|
|
|
|
// Les champs non renseignés restent masqués (pas de libellé orphelin).
|
|
Assert.DoesNotContain("SIREN", textes);
|
|
Assert.DoesNotContain("SIRET", textes);
|
|
Assert.DoesNotContain("Pays", textes);
|
|
|
|
fenetre.Close();
|
|
});
|
|
}
|
|
|
|
// ===== Fiche Site =====
|
|
|
|
[Fact]
|
|
public void FicheSite_BlocAccesEtNote_MasqueQuandVide_EtSansTitre()
|
|
{
|
|
Executer(() =>
|
|
{
|
|
var vueModele = new SiteDetailViewModel(null!, new NavigationService(), Permissions(), null!)
|
|
{
|
|
Site = new SiteDetail
|
|
{
|
|
SiteGuid = Guid.NewGuid(),
|
|
Nom = "Siège social Marseille",
|
|
Code = "SIT-0001"
|
|
}
|
|
};
|
|
|
|
Window fenetre = MesureGeometrique.Ouvrir(new SiteDetailView { DataContext = vueModele }, 420);
|
|
|
|
IReadOnlyList<string> textes = TextesAffiches(fenetre);
|
|
|
|
Assert.DoesNotContain("Accès et note", textes);
|
|
Assert.DoesNotContain("Code d'accès", textes);
|
|
Assert.DoesNotContain("Note", textes);
|
|
|
|
// Le reste de la fiche reste affiché.
|
|
Assert.Contains("Siège social Marseille", textes);
|
|
Assert.Contains("← Retour", textes);
|
|
|
|
fenetre.Close();
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void FicheSite_BlocAccesEtNote_AfficheSansTitre_QuandRenseigne()
|
|
{
|
|
Executer(() =>
|
|
{
|
|
var vueModele = new SiteDetailViewModel(null!, new NavigationService(), Permissions(), null!)
|
|
{
|
|
Site = new SiteDetail
|
|
{
|
|
SiteGuid = Guid.NewGuid(),
|
|
Nom = "Siège social Marseille",
|
|
CodeAcces = "4512A",
|
|
InformationsComplementaires = "Sonner à l'interphone bâtiment B."
|
|
}
|
|
};
|
|
|
|
Window fenetre = MesureGeometrique.Ouvrir(new SiteDetailView { DataContext = vueModele }, 420);
|
|
|
|
IReadOnlyList<string> textes = TextesAffiches(fenetre);
|
|
|
|
Assert.Contains("Code d'accès", textes);
|
|
Assert.Contains("4512A", textes);
|
|
Assert.Contains("Note", textes);
|
|
Assert.Contains("Sonner à l'interphone bâtiment B.", textes);
|
|
Assert.DoesNotContain("Accès et note", textes);
|
|
|
|
fenetre.Close();
|
|
});
|
|
}
|
|
|
|
// ===== Calcul « renseigné » =====
|
|
|
|
[Fact]
|
|
public void Modele_UneInformationBlanche_CompteCommeAbsente()
|
|
{
|
|
var client = new ClientDetail
|
|
{
|
|
FormeJuridique = " ",
|
|
Siren = string.Empty,
|
|
Siret = null,
|
|
Pays = "\t",
|
|
InformationsComplementaires = " "
|
|
};
|
|
|
|
Assert.False(client.HasFormeJuridique);
|
|
Assert.False(client.HasSiren);
|
|
Assert.False(client.HasSiret);
|
|
Assert.False(client.HasPays);
|
|
Assert.False(client.HasInformationsComplementaires);
|
|
Assert.False(client.HasInformations);
|
|
|
|
var site = new SiteDetail { CodeAcces = " ", InformationsComplementaires = string.Empty };
|
|
|
|
Assert.False(site.HasCodeAcces);
|
|
Assert.False(site.HasInformationsComplementaires);
|
|
Assert.False(site.HasAccesOuNote);
|
|
|
|
Assert.True(new ClientDetail { Siren = "123456789" }.HasInformations);
|
|
Assert.True(new SiteDetail { CodeAcces = "4512A" }.HasAccesOuNote);
|
|
Assert.True(new SiteDetail { InformationsComplementaires = "Note seule" }.HasAccesOuNote);
|
|
}
|
|
|
|
// ===== Outils =====
|
|
|
|
private static PermissionService Permissions()
|
|
{
|
|
var permissions = new PermissionService();
|
|
permissions.SetRights(MobilePermissionKeys.All.ToDictionary(k => k, _ => true));
|
|
return permissions;
|
|
}
|
|
|
|
private void Executer(Action scenario)
|
|
=> _session.Dispatch(
|
|
() =>
|
|
{
|
|
scenario();
|
|
return true;
|
|
},
|
|
CancellationToken.None).GetAwaiter().GetResult();
|
|
|
|
/// <summary>
|
|
/// Textes réellement affichés : un contrôle dont un parent est masqué est
|
|
/// exclu (sinon un libellé d'un bloc masqué passerait pour visible).
|
|
/// </summary>
|
|
private static IReadOnlyList<string> TextesAffiches(Window fenetre)
|
|
{
|
|
Dispatcher.UIThread.RunJobs();
|
|
|
|
var textes = fenetre.GetVisualDescendants()
|
|
.OfType<TextBlock>()
|
|
.Where(t => t.IsEffectivelyVisible && !string.IsNullOrWhiteSpace(t.Text))
|
|
.Select(t => t.Text!)
|
|
.ToArray();
|
|
|
|
Assert.NotEmpty(textes);
|
|
return textes;
|
|
}
|
|
}
|