307 lines
11 KiB
C#
307 lines
11 KiB
C#
using Omika.Core.Compatibility;
|
|
using Omika.Core.Domain.Entities.Organisation;
|
|
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 collaborateurs (table Collaborateur).
|
|
/// Aucune base réelle, aucun HFSQL : uniquement des objets en mémoire.
|
|
/// </summary>
|
|
public class BatikCollaborateurMapperTests
|
|
{
|
|
// ---- 1. Collaborateur Batik minimal -------------------------------------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_Minimal_MapsWithoutExceptionAndKeepsNoFabricatedValue()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow { COPKID = 1 };
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.Equal(DatabaseSchemaVersion.Batik, result.SourceVersion);
|
|
Assert.NotNull(result.Value);
|
|
Assert.Null(result.Value.Nom);
|
|
Assert.Null(result.Value.Prenom);
|
|
Assert.Null(result.Value.Civilite);
|
|
Assert.Null(result.Value.Statut);
|
|
Assert.Null(result.Value.Coordonnees);
|
|
Assert.False(result.Value.Actif);
|
|
Assert.False(result.Value.EstArchive);
|
|
Assert.NotNull(result.Value.SourceReference);
|
|
Assert.Equal(1, result.Value.SourceReference!.NumericId);
|
|
Assert.Equal(DatabaseSchemaVersion.Batik, result.Value.SourceReference!.Source);
|
|
Assert.Null(result.Value.SourceReference!.EntityGuid);
|
|
Assert.Empty(result.Warnings);
|
|
}
|
|
|
|
// ---- 2. Collaborateur Batik complet -------------------------------------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_Full_MapsAllCanonicalProperties()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow
|
|
{
|
|
COPKID = 42,
|
|
COIDCivilite = 2,
|
|
CONom = "Dupont",
|
|
COPrenom = "Jean",
|
|
COTrigramme = "JD",
|
|
COTelFixe = "0472000000",
|
|
COTelMobile = "0600000000",
|
|
COEmail = "jean.dupont@ville-lyon.fr",
|
|
COIDStatut = 3,
|
|
COActif = true,
|
|
COIDImport = "IMP-B-42"
|
|
};
|
|
|
|
var referenceRows = new Dictionary<long, BatikModels.ParametreMetierRow>
|
|
{
|
|
[2] = new() { PAPKID = 2, PACode = "C", PAValeur = "1", PALibelle = "M." },
|
|
[3] = new() { PAPKID = 3, PACode = "S", PAValeur = "1", PALibelle = "Actif" }
|
|
};
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row, referenceRows);
|
|
|
|
Collaborateur collaborateur = result.Value;
|
|
Assert.Equal("M.", collaborateur.Civilite!.Label);
|
|
Assert.Equal(2, collaborateur.Civilite!.LegacyId);
|
|
Assert.Equal("Actif", collaborateur.Statut!.Label);
|
|
Assert.Equal(3, collaborateur.Statut!.LegacyId);
|
|
Assert.Equal("Dupont", collaborateur.Nom);
|
|
Assert.Equal("Jean", collaborateur.Prenom);
|
|
Assert.Equal("JD", collaborateur.Code);
|
|
|
|
Assert.Equal("jean.dupont@ville-lyon.fr", collaborateur.Coordonnees!.Email);
|
|
Assert.Equal("0472000000", collaborateur.Coordonnees!.Phone);
|
|
Assert.Equal("0600000000", collaborateur.Coordonnees!.Mobile);
|
|
|
|
Assert.True(collaborateur.Actif);
|
|
|
|
Assert.Equal(42, collaborateur.SourceReference!.NumericId);
|
|
Assert.Equal(DatabaseSchemaVersion.Batik, collaborateur.SourceReference!.Source);
|
|
}
|
|
|
|
// ---- 3. Coordonnées nulles ----------------------------------------------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_EmptyCoordinates_ProducesNullCoordonnees()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow
|
|
{
|
|
COPKID = 5,
|
|
CONom = "Martin",
|
|
COEmail = " ",
|
|
COTelFixe = "",
|
|
COTelMobile = null
|
|
};
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.Null(result.Value.Coordonnees);
|
|
Assert.Null(result.Value.Prenom);
|
|
Assert.Equal("Martin", result.Value.Nom);
|
|
}
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_PartialCoordinates_KeepsOnlyProvidedValues()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow
|
|
{
|
|
COPKID = 6,
|
|
COEmail = "m@exemple.fr",
|
|
COTelFixe = null,
|
|
COTelMobile = "0600000000"
|
|
};
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value.Coordonnees);
|
|
Assert.Equal("m@exemple.fr", result.Value.Coordonnees!.Email);
|
|
Assert.Null(result.Value.Coordonnees!.Phone);
|
|
Assert.Equal("0600000000", result.Value.Coordonnees!.Mobile);
|
|
}
|
|
|
|
// ---- 4. Conservation de l'identifiant source ----------------------------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_SourceIdentifier_IsPreservedWithoutFabricatedGuid()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow { COPKID = 1234, COIDImport = "IMP-B" };
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.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);
|
|
}
|
|
|
|
// ---- 5. Aucune exception sur les chaînes vides ----------------------------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_EmptyOrNullStrings_NeverThrow()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow
|
|
{
|
|
CONom = "",
|
|
COPrenom = " ",
|
|
COEmail = "",
|
|
COTelFixe = null,
|
|
COTelMobile = " ",
|
|
COTrigramme = "",
|
|
COIDImport = ""
|
|
};
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value);
|
|
Assert.Null(result.Value.Nom);
|
|
Assert.Null(result.Value.Prenom);
|
|
Assert.Null(result.Value.Coordonnees);
|
|
Assert.Empty(result.Warnings);
|
|
}
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_DefaultRow_NeverThrows()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow();
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value);
|
|
Assert.Null(result.Value.SourceReference!.NumericId);
|
|
Assert.False(result.Value.Actif);
|
|
Assert.False(result.Value.EstArchive);
|
|
}
|
|
|
|
// ---- 6. Absence de noms physiques HFSQL dans le domaine canonique --------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_CanonicalDomain_DoesNotExposeHfSqlNames()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow
|
|
{
|
|
COPKID = 40,
|
|
COIDCivilite = 2,
|
|
CONom = "Dupont",
|
|
COPrenom = "Jean",
|
|
COTelFixe = "01",
|
|
COTelMobile = "06",
|
|
COEmail = "j@exemple.fr",
|
|
COActif = true,
|
|
COIDImport = "IMP-40"
|
|
};
|
|
|
|
var referenceRows = new Dictionary<long, BatikModels.ParametreMetierRow>
|
|
{
|
|
[2] = new() { PAPKID = 2, PACode = "C", PAValeur = "1", PALibelle = "M." }
|
|
};
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row, referenceRows);
|
|
Collaborateur collaborateur = result.Value;
|
|
|
|
string[] forbidden =
|
|
[
|
|
"CO_", "CL_", "PA_", "PKID", "HfSql", "HFSQL", "GUID"
|
|
];
|
|
|
|
AssertHasNoPhysicalNames(collaborateur, forbidden);
|
|
|
|
if (collaborateur.Coordonnees is not null)
|
|
{
|
|
AssertHasNoPhysicalNames(collaborateur.Coordonnees, forbidden);
|
|
}
|
|
|
|
if (collaborateur.SourceReference is not null)
|
|
{
|
|
AssertHasNoPhysicalNames(collaborateur.SourceReference, forbidden);
|
|
}
|
|
}
|
|
|
|
// ---- Référentiels non résolus --------------------------------------------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_UnresolvedCiviliteAndStatut_KeepsLegacyIdAndWarns()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow
|
|
{
|
|
COPKID = 7,
|
|
COIDCivilite = 77,
|
|
COIDStatut = 88
|
|
};
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value.Civilite);
|
|
Assert.Equal(77, result.Value.Civilite!.LegacyId);
|
|
Assert.Equal(string.Empty, result.Value.Civilite!.Label);
|
|
|
|
Assert.NotNull(result.Value.Statut);
|
|
Assert.Equal(88, result.Value.Statut!.LegacyId);
|
|
|
|
Assert.Contains(result.Warnings, w => w.Contains("CO_IDCivilite", StringComparison.Ordinal)
|
|
&& w.Contains(MappingWarningCodes.UnresolvedReference, StringComparison.Ordinal));
|
|
Assert.Contains(result.Warnings, w => w.Contains("CO_IDStatut", StringComparison.Ordinal)
|
|
&& w.Contains(MappingWarningCodes.UnresolvedReference, StringComparison.Ordinal));
|
|
}
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_ZeroCiviliteAndStatut_ProducesNoReference()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow { COPKID = 8, COIDCivilite = 0, COIDStatut = 0 };
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.Null(result.Value.Civilite);
|
|
Assert.Null(result.Value.Statut);
|
|
Assert.Empty(result.Warnings);
|
|
}
|
|
|
|
// ---- Rubriques sans équivalent --------------------------------------------------
|
|
|
|
[Fact]
|
|
public void CollaborateurBatik_FieldsWithoutCanonicalEquivalent_AreReportedAsIgnored()
|
|
{
|
|
var row = new BatikModels.CollaborateurRow
|
|
{
|
|
COPKID = 9,
|
|
COFonction = "Développeur",
|
|
COPonderation = 1.5f,
|
|
COIDImport = "IMP-9",
|
|
COAuPlanning = true,
|
|
COAccesBO = true,
|
|
COAccesMobile = true,
|
|
CreationDate = new DateTime(2024, 1, 1),
|
|
ModifDate = new DateTime(2024, 6, 1)
|
|
};
|
|
|
|
CanonicalMappingResult<Collaborateur> result = BatikMappers.BatikCollaborateurMapper.Map(row);
|
|
|
|
Assert.Equal("Développeur", result.Value.Fonction);
|
|
Assert.Contains(result.IgnoredFields, f => f == "CO_Ponderation");
|
|
Assert.Contains(result.IgnoredFields, f => f == "CO_IDImport");
|
|
Assert.Contains(result.IgnoredFields, f => f == "CO_AuPlanning");
|
|
Assert.Contains(result.IgnoredFields, f => f == "CO_AccesBO");
|
|
Assert.Contains(result.IgnoredFields, f => f == "CO_AccesMobile");
|
|
Assert.Contains(result.IgnoredFields, f => f == "CreationDate");
|
|
Assert.Contains(result.IgnoredFields, f => f == "ModifDate");
|
|
Assert.Null(result.Value.SocieteId);
|
|
}
|
|
|
|
// ---- 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));
|
|
}
|
|
}
|
|
}
|