Files
Omika/tests/Omika.Tests/Mapping/BatikDossierMapperTests.cs
2026-10-23 18:46:50 +02:00

182 lines
6.6 KiB
C#

using Omika.Core.Compatibility;
using Omika.Core.Domain.Entities.Interventions;
using Omika.Core.Domain.ValueObjects;
using Omika.Data.Mapping.Common;
using BatikModels = Omika.Data.HfSql.Models.Batik;
using BatikMappers = Omika.Data.Mapping.Batik;
namespace Omika.Tests.Mapping;
/// <summary>
/// Tests unitaires du mapper Batik → canonique des dossiers (table Dossier).
/// Aucune base réelle, aucun HFSQL : uniquement des objets en mémoire.
/// </summary>
public class BatikDossierMapperTests
{
// ---- 1. Dossier Batik minimal ------------------------------------------------
[Fact]
public void DossierBatik_Minimal_MapsWithoutExceptionAndKeepsNoFabricatedValue()
{
var row = new BatikModels.DossierRow { DOPKID = 1 };
CanonicalMappingResult<Dossier> result = BatikMappers.BatikDossierMapper.Map(row);
Assert.Equal(DatabaseSchemaVersion.Batik, result.SourceVersion);
Assert.NotNull(result.Value);
Assert.Null(result.Value.ReferenceMetier);
Assert.Null(result.Value.Titre);
Assert.Null(result.Value.Type);
Assert.Null(result.Value.Statut);
Assert.False(result.Value.EstArchive);
Assert.Empty(result.Warnings);
}
// ---- 2. Conservation de l'identifiant source (cause du count=0 snapshot) -----
[Fact]
public void DossierBatik_SourceReference_IsPreservedWithNumericId()
{
// Cause réelle du micro-lot 19 : le mapper ne remplissait pas SourceReference,
// donc LoadDossiersAsync skippait tous les dossiers (NumericId null) → count=0.
var row = new BatikModels.DossierRow { DOPKID = 1234 };
CanonicalMappingResult<Dossier> result = BatikMappers.BatikDossierMapper.Map(row);
Assert.NotNull(result.Value.SourceReference);
Assert.Equal(DatabaseSchemaVersion.Batik, result.Value.SourceReference!.Source);
Assert.Equal(1234, result.Value.SourceReference!.NumericId);
Assert.Equal("1234", result.Value.SourceReference!.PublicIdentifier);
Assert.Null(result.Value.SourceReference!.EntityGuid);
Assert.Null(result.Value.SourceReference!.PhysicalGuid);
}
// ---- 3. Dossier Batik complet ------------------------------------------------
[Fact]
public void DossierBatik_Full_MapsAllCanonicalProperties()
{
var row = new BatikModels.DossierRow
{
DOPKID = 42,
DOIDTypeDossier = 2,
DOIDStatut = 3,
DOTitre = "Dossier chantier",
DONumDossier = "DOS-2024-001",
DOIDClient = 7,
Archive = false,
DODateDebut = new DateOnly(2024, 1, 15)
};
var referenceRows = new Dictionary<long, BatikModels.ParametreMetierRow>
{
[2] = new() { PAPKID = 2, PACode = "T", PAValeur = "1", PALibelle = "Chantier" },
[3] = new() { PAPKID = 3, PACode = "S", PAValeur = "1", PALibelle = "Ouvert" }
};
CanonicalMappingResult<Dossier> result = BatikMappers.BatikDossierMapper.Map(row, referenceRows);
Dossier dossier = result.Value;
Assert.Equal("DOS-2024-001", dossier.ReferenceMetier);
Assert.Equal("Dossier chantier", dossier.Titre);
Assert.Equal("Chantier", dossier.Type!.Label);
Assert.Equal(2, dossier.Type!.LegacyId);
Assert.Equal("Ouvert", dossier.Statut!.Label);
Assert.Equal(3, dossier.Statut!.LegacyId);
Assert.Equal(new DateTime(2024, 1, 15), dossier.DateOuverture);
Assert.False(dossier.EstArchive);
Assert.Equal(42, dossier.SourceReference!.NumericId);
Assert.Equal(DatabaseSchemaVersion.Batik, dossier.SourceReference!.Source);
// La référence physique du client lié est conservée en interne.
Assert.NotNull(dossier.ClientSourceReference);
Assert.Equal(7, dossier.ClientSourceReference!.NumericId);
}
// ---- 4. Aucune exception sur les chaînes vides --------------------------------
[Fact]
public void DossierBatik_EmptyOrNullStrings_NeverThrow()
{
var row = new BatikModels.DossierRow
{
DOPKID = 5,
DOTitre = "",
DONumDossier = " "
};
CanonicalMappingResult<Dossier> result = BatikMappers.BatikDossierMapper.Map(row);
Assert.NotNull(result.Value);
Assert.Null(result.Value.Titre);
Assert.Null(result.Value.ReferenceMetier);
Assert.Empty(result.Warnings);
}
[Fact]
public void DossierBatik_DefaultRow_NeverThrows()
{
var row = new BatikModels.DossierRow();
CanonicalMappingResult<Dossier> result = BatikMappers.BatikDossierMapper.Map(row);
Assert.NotNull(result.Value);
// SourceReference est toujours rempli (porte DO_PKID) ; avec une ligne par
// défaut DO_PKID = 0, NumericId vaut 0 (jamais null en production car la
// clé primaire est auto-générée et strictement positive).
Assert.NotNull(result.Value.SourceReference);
Assert.Equal(0, result.Value.SourceReference!.NumericId);
Assert.False(result.Value.EstArchive);
}
// ---- 5. Absence de noms physiques HFSQL dans le domaine canonique --------------
[Fact]
public void DossierBatik_CanonicalDomain_DoesNotExposeHfSqlNames()
{
var row = new BatikModels.DossierRow
{
DOPKID = 40,
DOIDTypeDossier = 2,
DOIDStatut = 3,
DOTitre = "Dossier",
DONumDossier = "DOS-40",
DOIDClient = 7,
Archive = false
};
var referenceRows = new Dictionary<long, BatikModels.ParametreMetierRow>
{
[2] = new() { PAPKID = 2, PACode = "T", PAValeur = "1", PALibelle = "Chantier" },
[3] = new() { PAPKID = 3, PACode = "S", PAValeur = "1", PALibelle = "Ouvert" }
};
CanonicalMappingResult<Dossier> result = BatikMappers.BatikDossierMapper.Map(row, referenceRows);
Dossier dossier = result.Value;
string[] forbidden =
[
"DO_", "PA_", "PKID", "HfSql", "HFSQL", "GUID"
];
AssertHasNoPhysicalNames(dossier, forbidden);
if (dossier.SourceReference is not null)
{
AssertHasNoPhysicalNames(dossier.SourceReference, forbidden);
}
}
// ---- Helper ---------------------------------------------------------------------
private static void AssertHasNoPhysicalNames(object value, string[] forbidden)
{
foreach (var property in value.GetType().GetProperties())
{
Assert.DoesNotContain(forbidden, f => property.Name.Contains(f, StringComparison.Ordinal));
}
}
}