Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user