Files
Omika/tests/Omika.Tests/Data/DocumentAnchoredPathTests.cs
T
2026-10-23 18:46:50 +02:00

218 lines
8.2 KiB
C#

using Omika.Data.Repositories;
namespace Omika.Tests.Data;
/// <summary>
/// Tests de la résolution répertoire par répertoire des documents (ancres #id).
/// Le chemin est reconstruit depuis la structure Omika :
/// <c>[LI_CodeLieu] #[LI_PKID]\[CL_Nom] #[CL_PKID]\[IN_RefInterne] #[IN_PKID]\$DC_Categorie_Id$</c>.
/// Objectif : retrouver le répertoire existant même si un libellé a été modifié ou
/// contient des espaces en trop, sans jamais créer de doublon — et sans jamais
/// lancer de recherche sur le chemin complet.
/// </summary>
public class DocumentAnchoredPathTests : IDisposable
{
private const string ExpectedPath =
@"402 ORCHIDEES 2 #3512\Dupont #12\INT-0001 #3401\Photos #46";
private readonly string _root;
public DocumentAnchoredPathTests()
{
_root = Path.Combine(Path.GetTempPath(), "omika-anchors", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(_root);
}
public void Dispose()
{
if (Directory.Exists(_root))
{
Directory.Delete(_root, recursive: true);
}
}
// --- Extraction de l'ancre ------------------------------------------------
[Fact]
public void TryParseAnchor_ExtraitLeDernierIdentifiant()
{
bool parsed = DocumentPathResolver.TryParseAnchor("Dupont #2 #3512", out string label, out long id);
Assert.True(parsed);
Assert.Equal(3512, id);
Assert.Equal("Dupont #2", label);
}
[Fact]
public void TryParseAnchor_TolereLesEspacesAutourDuDiese()
{
Assert.True(DocumentPathResolver.TryParseAnchor("Photos # 46", out _, out long id1));
Assert.Equal(46, id1);
Assert.True(DocumentPathResolver.TryParseAnchor("Photos #46", out _, out long id2));
Assert.Equal(46, id2);
}
[Fact]
public void TryParseAnchor_SansIdentifiant_RetourneFaux()
{
Assert.False(DocumentPathResolver.TryParseAnchor("Intervention", out string label, out long id));
Assert.Equal(0, id);
Assert.Equal("Intervention", label);
}
[Fact]
public void NormalizeSegmentName_CompacteLesEspacesEtLaCasse()
{
Assert.Equal(
DocumentPathResolver.NormalizeSegmentName("402 ORCHIDEES 2 #3512"),
DocumentPathResolver.NormalizeSegmentName("402 ORCHIDEES 2 #3512"));
}
// --- Recherche du fichier -------------------------------------------------
[Fact]
public void RetrouveLeFichier_MalgreUnEspaceDoubleDansLeRepertoireRacine()
{
// Le disque porte « 402 ORCHIDEES 2 #3512 » (deux espaces), la base produit
// « 402 ORCHIDEES 2 #3512 » (un seul).
string actualDirectory = CreateDirectoryWithFile(@"402 ORCHIDEES 2 #3512\Dupont #12\INT-0001 #3401\Photos #46");
string? found = DocumentPathResolver.ResolveAnchoredDocumentFile(
_root, ExpectedPath, "photo.jpg", Guid.Empty);
Assert.NotNull(found);
Assert.Equal(
Path.GetFullPath(Path.Combine(actualDirectory, "photo.jpg")),
Path.GetFullPath(found!));
}
[Fact]
public void RetrouveLeFichier_MalgreUnLibelleModifie()
{
// Le client a été renommé : le disque porte « Dupont SA #12 », la base produit
// « Dupont #12 ». L'ancre #12 reste identique.
string actualDirectory = CreateDirectoryWithFile(@"402 ORCHIDEES 2 #3512\Dupont SA #12\INT-0001 #3401\Photos #46");
string? found = DocumentPathResolver.ResolveAnchoredDocumentFile(
_root, ExpectedPath, "photo.jpg", Guid.Empty);
Assert.NotNull(found);
Assert.Equal(
Path.GetFullPath(Path.Combine(actualDirectory, "photo.jpg")),
Path.GetFullPath(found!));
}
[Fact]
public void RetrouveLeFichier_QuandLeSegmentDeCategorieEstAbsent()
{
// Document historique : pas de sous-répertoire de catégorie sur le disque.
string interventionDirectory = CreateDirectoryWithFile(@"402 ORCHIDEES 2 #3512\Dupont #12\INT-0001 #3401");
string? found = DocumentPathResolver.ResolveAnchoredDocumentFile(
_root, ExpectedPath, "photo.jpg", Guid.Empty);
Assert.NotNull(found);
Assert.Equal(
Path.GetFullPath(Path.Combine(interventionDirectory, "photo.jpg")),
Path.GetFullPath(found!));
}
[Fact]
public void NeDescendPas_QuandUnNiveauIntermediaireManque()
{
// Le répertoire du client est absent : la descente doit s'arrêter là et ne
// jamais partir en recherche sur le chemin complet.
CreateDirectoryWithFile(@"402 ORCHIDEES 2 #3512\INT-0001 #3401\Photos #46");
string? found = DocumentPathResolver.ResolveAnchoredDocumentFile(
_root, ExpectedPath, "photo.jpg", Guid.Empty);
Assert.Null(found);
}
[Fact]
public void NeConfondPasDeuxIdentifiantsProches()
{
// #3512 attendu, le disque porte #13512 : aucune correspondance.
CreateDirectoryWithFile(@"402 ORCHIDEES 2 #13512\Dupont #12\INT-0001 #3401\Photos #46");
string? found = DocumentPathResolver.ResolveAnchoredDocumentFile(
_root, ExpectedPath, "photo.jpg", Guid.Empty);
Assert.Null(found);
}
// --- Création : réutilisation sans doublon --------------------------------
[Fact]
public void Creation_ReutiliseLeRepertoireExistant()
{
string existing = CreateDirectoryWithFile(@"402 ORCHIDEES 2 #3512\Dupont SA #12\INT-0001 #3401\Photos #46");
int directoriesBefore = Directory.GetDirectories(_root, "*", SearchOption.AllDirectories).Length;
DocumentPathResolver.AnchorResolution resolution = DocumentPathResolver.EnsureAnchoredDirectory(
_root, DocumentPathResolver.ParseAnchors(ExpectedPath));
// Le répertoire réel (deux espaces, libellé « Dupont SA ») est réutilisé tel quel.
Assert.NotNull(resolution.RelativeDirectory);
Assert.Equal(
Path.GetFullPath(existing),
Path.GetFullPath(Path.Combine(_root, resolution.RelativeDirectory!)));
// Aucun répertoire concurrent n'a été créé.
Assert.Equal(directoriesBefore, Directory.GetDirectories(_root, "*", SearchOption.AllDirectories).Length);
Assert.False(Directory.Exists(Path.Combine(_root, @"402 ORCHIDEES 2 #3512")));
}
[Fact]
public void Creation_AjouteUniquementLesSegmentsManquants()
{
// Client et intervention existent, la catégorie manque.
string interventionDirectory = Path.Combine(_root, @"402 ORCHIDEES 2 #3512\Dupont #12\INT-0001 #3401");
Directory.CreateDirectory(interventionDirectory);
Directory.CreateDirectory(Path.Combine(_root, @"402 ORCHIDEES 2 #3512\Dupont #12"));
DocumentPathResolver.AnchorResolution resolution = DocumentPathResolver.EnsureAnchoredDirectory(
_root, DocumentPathResolver.ParseAnchors(ExpectedPath));
Assert.True(resolution.IsComplete);
Assert.Equal(4, resolution.ResolvedDepth);
string expectedFinal = Path.Combine(interventionDirectory, "Photos #46");
Assert.Equal(Path.GetFullPath(expectedFinal), Path.GetFullPath(resolution.FullDirectory!));
Assert.True(Directory.Exists(expectedFinal));
}
[Fact]
public void Creation_DepuisUneRacineVide_CreeTouteLArborescence()
{
DocumentPathResolver.AnchorResolution resolution = DocumentPathResolver.EnsureAnchoredDirectory(
_root, DocumentPathResolver.ParseAnchors(ExpectedPath));
Assert.True(resolution.IsComplete);
Assert.Equal(
Path.GetFullPath(Path.Combine(_root, ExpectedPath)),
Path.GetFullPath(resolution.FullDirectory!));
}
[Fact]
public void ParseAnchors_IgnoreLesSeparateursMultiples()
{
IReadOnlyList<DocumentPathResolver.AnchoredSegment> segments =
DocumentPathResolver.ParseAnchors(@"\\402 ORCHIDEES 2 #3512\\Dupont #12\");
Assert.Equal(2, segments.Count);
Assert.Equal(3512, segments[0].Id);
Assert.Equal(12, segments[1].Id);
}
private string CreateDirectoryWithFile(string relativeDirectory)
{
string directory = Path.Combine(_root, relativeDirectory);
Directory.CreateDirectory(directory);
File.WriteAllBytes(Path.Combine(directory, "photo.jpg"), [1, 2, 3]);
return directory;
}
}