282 lines
11 KiB
C#
282 lines
11 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 interventions.
|
|
/// Aucune base réelle, aucun HFSQL : uniquement des objets en mémoire.
|
|
/// </summary>
|
|
public class BatikInterventionMapperTests
|
|
{
|
|
// ---- 1. Intervention Batik minimale -------------------------------------------
|
|
|
|
[Fact]
|
|
public void InterventionBatik_Minimal_MapsWithoutExceptionAndKeepsNoFabricatedValue()
|
|
{
|
|
var row = new BatikModels.InterventionRow { INPKID = 1 };
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row);
|
|
|
|
Assert.Equal(DatabaseSchemaVersion.Batik, result.SourceVersion);
|
|
Assert.NotNull(result.Value);
|
|
Assert.Null(result.Value.Titre);
|
|
Assert.Null(result.Value.Reference);
|
|
Assert.Null(result.Value.Type);
|
|
Assert.Null(result.Value.Etat);
|
|
Assert.False(result.Value.EstArchive);
|
|
Assert.Empty(result.Warnings);
|
|
}
|
|
|
|
// ---- 2. Intervention Batik complète -------------------------------------------
|
|
|
|
[Fact]
|
|
public void InterventionBatik_Full_MapsAllCanonicalProperties()
|
|
{
|
|
var row = new BatikModels.InterventionRow
|
|
{
|
|
INPKID = 42,
|
|
INTitre = "Réparation chaudière",
|
|
INRefInterne = "INT-042",
|
|
INDescription = "Remplacement de la chaudière",
|
|
INIDTypeIntervention = 2,
|
|
INIDEtatIntervention = 3,
|
|
INDateIntervention = new DateOnly(2026, 3, 15),
|
|
Archive = true,
|
|
INIDImport = "IMP-B-42"
|
|
};
|
|
|
|
var referenceRows = new Dictionary<long, BatikModels.ParametreMetierRow>
|
|
{
|
|
[2] = new() { PAPKID = 2, PACode = "T", PAValeur = "1", PALibelle = "Maintenance" },
|
|
[3] = new() { PAPKID = 3, PACode = "S", PAValeur = "1", PALibelle = "En cours" }
|
|
};
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row, referenceRows);
|
|
|
|
Intervention intervention = result.Value;
|
|
Assert.Equal("Réparation chaudière", intervention.Titre);
|
|
Assert.Equal("INT-042", intervention.Reference);
|
|
Assert.Equal("Remplacement de la chaudière", intervention.Description);
|
|
Assert.Equal("Maintenance", intervention.Type!.Label);
|
|
Assert.Equal(2, intervention.Type!.LegacyId);
|
|
Assert.Equal("En cours", intervention.Etat!.Label);
|
|
Assert.Equal(3, intervention.Etat!.LegacyId);
|
|
Assert.Equal(new DateTime(2026, 3, 15), intervention.DatePrevueDebut);
|
|
Assert.True(intervention.EstArchive);
|
|
}
|
|
|
|
// ---- 4. Type et état ----------------------------------------------------------
|
|
|
|
[Fact]
|
|
public void InterventionBatik_Type_IsResolvedFromLegacyId()
|
|
{
|
|
var row = new BatikModels.InterventionRow { INPKID = 5, INIDTypeIntervention = 7 };
|
|
|
|
var referenceRows = new Dictionary<long, BatikModels.ParametreMetierRow>
|
|
{
|
|
[7] = new() { PAPKID = 7, PACode = "T", PAValeur = "2", PALibelle = "Urgence" }
|
|
};
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row, referenceRows);
|
|
|
|
Assert.NotNull(result.Value.Type);
|
|
Assert.Equal("Urgence", result.Value.Type!.Label);
|
|
Assert.Equal(7, result.Value.Type!.LegacyId);
|
|
Assert.Empty(result.Warnings);
|
|
}
|
|
|
|
[Fact]
|
|
public void InterventionBatik_UnresolvedType_KeepsLegacyIdAndWarns()
|
|
{
|
|
var row = new BatikModels.InterventionRow { INPKID = 6, INIDTypeIntervention = 77 };
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value.Type);
|
|
Assert.Equal(77, result.Value.Type!.LegacyId);
|
|
Assert.Equal(string.Empty, result.Value.Type!.Label);
|
|
Assert.Contains(result.Warnings, w => w.Contains("IN_IDTypeIntervention", StringComparison.Ordinal)
|
|
&& w.Contains(MappingWarningCodes.UnresolvedReference, StringComparison.Ordinal));
|
|
}
|
|
|
|
[Fact]
|
|
public void InterventionBatik_ZeroType_ProducesNoReference()
|
|
{
|
|
var row = new BatikModels.InterventionRow { INPKID = 8, INIDTypeIntervention = 0 };
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row);
|
|
|
|
Assert.Null(result.Value.Type);
|
|
Assert.Empty(result.Warnings);
|
|
}
|
|
|
|
[Fact]
|
|
public void InterventionBatik_UnresolvedEtat_KeepsLegacyIdAndWarns()
|
|
{
|
|
var row = new BatikModels.InterventionRow { INPKID = 9, INIDEtatIntervention = 88 };
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value.Etat);
|
|
Assert.Equal(88, result.Value.Etat!.LegacyId);
|
|
Assert.Contains(result.Warnings, w => w.Contains("IN_IDEtatIntervention", StringComparison.Ordinal)
|
|
&& w.Contains(MappingWarningCodes.UnresolvedReference, StringComparison.Ordinal));
|
|
}
|
|
|
|
// ---- 5. Champs ignorés --------------------------------------------------------
|
|
|
|
[Fact]
|
|
public void InterventionBatik_FieldsWithoutCanonicalEquivalent_AreReportedAsIgnored()
|
|
{
|
|
var row = new BatikModels.InterventionRow
|
|
{
|
|
INPKID = 15,
|
|
INIDClient = 1,
|
|
INIDLieu = 2,
|
|
INIDDossier = 3,
|
|
INIDSuiviPar = 4,
|
|
INIDDemandeur = 5,
|
|
INIDSociete = 6,
|
|
INAttestationTVAPresente = true,
|
|
INNoteInterne = "note",
|
|
INRefExterne = "EXT-1",
|
|
INDureePrevue = 2.5f,
|
|
INNumDevis = "DEV-1",
|
|
INDateDevis = new DateOnly(2026, 1, 1),
|
|
INNumFacture = "FAC-1",
|
|
INDateFacture = new DateOnly(2026, 2, 1),
|
|
INNumIntervention = "N-1",
|
|
ModifDate = new DateTime(2024, 1, 1),
|
|
CreationDate = new DateTime(2023, 1, 1),
|
|
DateArchivage = new DateTime(2024, 6, 1)
|
|
};
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row);
|
|
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_IDClient");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_IDLieu");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_IDDossier");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_IDSuiviPar");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_IDDemandeur");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_IDSociete");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_AttestationTVAPresente");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_NoteInterne");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_DureePrevue");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_DateDevis");
|
|
Assert.Contains(result.IgnoredFields, f => f == "IN_DateFacture");
|
|
Assert.Equal(new DateTime(2024, 1, 1), result.Value.DateModification);
|
|
Assert.Contains(result.IgnoredFields, f => f == "CreationDate");
|
|
Assert.Contains(result.IgnoredFields, f => f == "DateArchivage");
|
|
|
|
// Champs désormais dotés d'un équivalent canonique : ils ne sont plus
|
|
// ignorés, ils sont mappés dans l'entité Intervention.
|
|
Assert.Equal("EXT-1", result.Value.ReferenceExterne);
|
|
Assert.Equal("DEV-1", result.Value.NumeroDevis);
|
|
Assert.Equal("N-1", result.Value.NumeroIntervention);
|
|
Assert.Equal("FAC-1", result.Value.NumeroFacture);
|
|
}
|
|
|
|
// ---- 6. Aucune exception sur les chaînes vides --------------------------------
|
|
|
|
[Fact]
|
|
public void InterventionBatik_EmptyOrNullStrings_NeverThrow()
|
|
{
|
|
var row = new BatikModels.InterventionRow
|
|
{
|
|
INTitre = "",
|
|
INRefInterne = " ",
|
|
INDescription = "",
|
|
INNoteInterne = " ",
|
|
INRefExterne = "",
|
|
INIDImport = " "
|
|
};
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value);
|
|
Assert.Null(result.Value.Titre);
|
|
Assert.Null(result.Value.Reference);
|
|
Assert.Null(result.Value.Description);
|
|
Assert.Empty(result.Warnings);
|
|
}
|
|
|
|
[Fact]
|
|
public void InterventionBatik_DefaultRow_NeverThrows()
|
|
{
|
|
var row = new BatikModels.InterventionRow();
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row);
|
|
|
|
Assert.NotNull(result.Value);
|
|
Assert.False(result.Value.EstArchive);
|
|
}
|
|
|
|
// ---- 7. Absence de noms physiques HFSQL dans le domaine canonique -------------
|
|
|
|
[Fact]
|
|
public void InterventionBatik_CanonicalDomain_DoesNotExposeHfSqlNames()
|
|
{
|
|
var row = new BatikModels.InterventionRow
|
|
{
|
|
INPKID = 40,
|
|
INTitre = "Titre",
|
|
INRefInterne = "INT-040",
|
|
INDescription = "desc",
|
|
INIDTypeIntervention = 2,
|
|
INIDEtatIntervention = 3,
|
|
INDateIntervention = new DateOnly(2026, 1, 1),
|
|
Archive = false,
|
|
INIDImport = "IMP-40",
|
|
INIDClient = 1,
|
|
INIDLieu = 2,
|
|
INIDDossier = 3,
|
|
INIDSuiviPar = 4,
|
|
INIDDemandeur = 5,
|
|
INIDSociete = 6,
|
|
INAttestationTVAPresente = true,
|
|
INNoteInterne = "note",
|
|
INRefExterne = "EXT",
|
|
INDureePrevue = 1f,
|
|
INNumDevis = "DEV",
|
|
INNumFacture = "FAC",
|
|
INNumIntervention = "N"
|
|
};
|
|
|
|
var referenceRows = new Dictionary<long, BatikModels.ParametreMetierRow>
|
|
{
|
|
[2] = new() { PAPKID = 2, PACode = "T", PAValeur = "1", PALibelle = "Maintenance" },
|
|
[3] = new() { PAPKID = 3, PACode = "S", PAValeur = "1", PALibelle = "En cours" }
|
|
};
|
|
|
|
CanonicalMappingResult<Intervention> result = BatikMappers.BatikInterventionMapper.Map(row, referenceRows);
|
|
Intervention intervention = result.Value;
|
|
|
|
string[] forbidden =
|
|
[
|
|
"IN_", "PA_", "PKID", "HfSql", "HFSQL", "GUID"
|
|
];
|
|
|
|
AssertHasNoPhysicalNames(intervention, forbidden);
|
|
|
|
if (intervention.SourceReference is not null)
|
|
{
|
|
AssertHasNoPhysicalNames(intervention.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));
|
|
}
|
|
}
|
|
}
|