feat(04-06): implement TemplateService and FolderStructureService
- FolderStructureService.CreateFoldersAsync creates folder hierarchy from CSV rows using BulkOperationRunner - FolderStructureService.BuildUniquePaths deduplicates and sorts paths parent-first by slash depth - TemplateService already committed; verified compilation and interface compliance - FolderStructureServiceTests: 4 unit tests pass (BuildUniquePaths edge cases, deduplication, empty levels, BuildPath) + 1 skip - TemplateServiceTests: 3 unit tests pass (interface impl, SiteTemplate defaults, SiteTemplateOptions defaults) + 2 skip
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using SharepointToolbox.Core.Models;
|
||||
using SharepointToolbox.Services;
|
||||
|
||||
namespace SharepointToolbox.Tests.Services;
|
||||
|
||||
public class FolderStructureServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public void FolderStructureService_Implements_IFolderStructureService()
|
||||
{
|
||||
Assert.True(typeof(IFolderStructureService).IsAssignableFrom(typeof(FolderStructureService)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildUniquePaths_FromExampleCsv_ReturnsParentFirst()
|
||||
{
|
||||
var rows = new List<FolderStructureRow>
|
||||
{
|
||||
new() { Level1 = "Administration", Level2 = "Comptabilite", Level3 = "Factures" },
|
||||
new() { Level1 = "Administration", Level2 = "Comptabilite", Level3 = "Bilans" },
|
||||
new() { Level1 = "Administration", Level2 = "Ressources Humaines" },
|
||||
new() { Level1 = "Projets", Level2 = "Projet Alpha", Level3 = "Documents" },
|
||||
};
|
||||
|
||||
var paths = FolderStructureService.BuildUniquePaths(rows);
|
||||
|
||||
// Should contain unique paths, parent-first
|
||||
Assert.Contains("Administration", paths);
|
||||
Assert.Contains("Administration/Comptabilite", paths);
|
||||
Assert.Contains("Administration/Comptabilite/Factures", paths);
|
||||
Assert.Contains("Administration/Comptabilite/Bilans", paths);
|
||||
Assert.Contains("Projets", paths);
|
||||
Assert.Contains("Projets/Projet Alpha", paths);
|
||||
|
||||
// Parent-first: "Administration" before "Administration/Comptabilite"
|
||||
var adminIdx = paths.ToList().IndexOf("Administration");
|
||||
var compIdx = paths.ToList().IndexOf("Administration/Comptabilite");
|
||||
Assert.True(adminIdx < compIdx);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildUniquePaths_DuplicateRows_Deduplicated()
|
||||
{
|
||||
var rows = new List<FolderStructureRow>
|
||||
{
|
||||
new() { Level1 = "A", Level2 = "B" },
|
||||
new() { Level1 = "A", Level2 = "B" },
|
||||
new() { Level1 = "A", Level2 = "C" },
|
||||
};
|
||||
|
||||
var paths = FolderStructureService.BuildUniquePaths(rows);
|
||||
|
||||
Assert.Equal(3, paths.Count); // A, A/B, A/C (deduplicated)
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildUniquePaths_EmptyLevels_StopsAtLastNonEmpty()
|
||||
{
|
||||
var rows = new List<FolderStructureRow>
|
||||
{
|
||||
new() { Level1 = "Root", Level2 = "", Level3 = "", Level4 = "" },
|
||||
};
|
||||
|
||||
var paths = FolderStructureService.BuildUniquePaths(rows);
|
||||
|
||||
Assert.Single(paths);
|
||||
Assert.Equal("Root", paths[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FolderStructureRow_BuildPath_ReturnsCorrectPath()
|
||||
{
|
||||
var row = new FolderStructureRow
|
||||
{
|
||||
Level1 = "Admin",
|
||||
Level2 = "HR",
|
||||
Level3 = "Contracts",
|
||||
Level4 = ""
|
||||
};
|
||||
|
||||
Assert.Equal("Admin/HR/Contracts", row.BuildPath());
|
||||
}
|
||||
|
||||
[Fact(Skip = "Requires live SharePoint tenant")]
|
||||
public async Task CreateFoldersAsync_ValidRows_CreatesFolders()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
49
SharepointToolbox.Tests/Services/TemplateServiceTests.cs
Normal file
49
SharepointToolbox.Tests/Services/TemplateServiceTests.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using SharepointToolbox.Core.Models;
|
||||
using SharepointToolbox.Services;
|
||||
|
||||
namespace SharepointToolbox.Tests.Services;
|
||||
|
||||
public class TemplateServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public void TemplateService_Implements_ITemplateService()
|
||||
{
|
||||
Assert.True(typeof(ITemplateService).IsAssignableFrom(typeof(TemplateService)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SiteTemplate_DefaultValues_AreCorrect()
|
||||
{
|
||||
var template = new SiteTemplate();
|
||||
Assert.NotNull(template.Id);
|
||||
Assert.NotEmpty(template.Id);
|
||||
Assert.NotNull(template.Libraries);
|
||||
Assert.Empty(template.Libraries);
|
||||
Assert.NotNull(template.PermissionGroups);
|
||||
Assert.Empty(template.PermissionGroups);
|
||||
Assert.NotNull(template.Options);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SiteTemplateOptions_AllDefaultTrue()
|
||||
{
|
||||
var opts = new SiteTemplateOptions();
|
||||
Assert.True(opts.CaptureLibraries);
|
||||
Assert.True(opts.CaptureFolders);
|
||||
Assert.True(opts.CapturePermissionGroups);
|
||||
Assert.True(opts.CaptureLogo);
|
||||
Assert.True(opts.CaptureSettings);
|
||||
}
|
||||
|
||||
[Fact(Skip = "Requires live SharePoint tenant")]
|
||||
public async Task CaptureTemplateAsync_CapturesLibrariesAndFolders()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
[Fact(Skip = "Requires live SharePoint admin context")]
|
||||
public async Task ApplyTemplateAsync_CreatesTeamSiteWithStructure()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user