- CsvValidationService: CsvHelper-based parsing with DetectDelimiter, BOM detection, per-row validation for BulkMemberRow/BulkSiteRow/FolderStructureRow - TemplateRepository: atomic JSON write (tmp + File.Move) with SemaphoreSlim, supports GetAll/GetById/Save/Delete/Rename operations - CsvValidationServiceTests: 9 passing tests (email validation, delimiter detection, BOM handling, folder/site/member validation) - TemplateRepositoryTests: 6 passing tests (round-trip, GetAll, delete, rename, empty directory, non-existent id) - All previously-skipped scaffold tests now active and passing (15 total)
108 lines
3.1 KiB
C#
108 lines
3.1 KiB
C#
using System.IO;
|
|
using SharepointToolbox.Core.Models;
|
|
using SharepointToolbox.Infrastructure.Persistence;
|
|
|
|
namespace SharepointToolbox.Tests.Services;
|
|
|
|
public class TemplateRepositoryTests : IDisposable
|
|
{
|
|
private readonly string _tempDir;
|
|
private readonly TemplateRepository _repo;
|
|
|
|
public TemplateRepositoryTests()
|
|
{
|
|
_tempDir = Path.Combine(Path.GetTempPath(), $"sptoolbox_test_{Guid.NewGuid():N}");
|
|
_repo = new TemplateRepository(_tempDir);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(_tempDir))
|
|
Directory.Delete(_tempDir, true);
|
|
}
|
|
|
|
private static SiteTemplate CreateTestTemplate(string name = "Test Template")
|
|
{
|
|
return new SiteTemplate
|
|
{
|
|
Id = Guid.NewGuid().ToString(),
|
|
Name = name,
|
|
SourceUrl = "https://contoso.sharepoint.com/sites/test",
|
|
CapturedAt = DateTime.UtcNow,
|
|
SiteType = "Team",
|
|
Options = new SiteTemplateOptions(),
|
|
Settings = new TemplateSettings { Title = "Test", Description = "Desc", Language = 1033 },
|
|
Libraries = new List<TemplateLibraryInfo>
|
|
{
|
|
new() { Name = "Documents", BaseType = "DocumentLibrary", BaseTemplate = 101 }
|
|
},
|
|
};
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SaveAndLoad_RoundTrips_Correctly()
|
|
{
|
|
var template = CreateTestTemplate();
|
|
await _repo.SaveAsync(template);
|
|
|
|
var loaded = await _repo.GetByIdAsync(template.Id);
|
|
|
|
Assert.NotNull(loaded);
|
|
Assert.Equal(template.Name, loaded!.Name);
|
|
Assert.Equal(template.SiteType, loaded.SiteType);
|
|
Assert.Equal(template.SourceUrl, loaded.SourceUrl);
|
|
Assert.Single(loaded.Libraries);
|
|
Assert.Equal("Documents", loaded.Libraries[0].Name);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetAll_ReturnsAllSavedTemplates()
|
|
{
|
|
await _repo.SaveAsync(CreateTestTemplate("Template A"));
|
|
await _repo.SaveAsync(CreateTestTemplate("Template B"));
|
|
await _repo.SaveAsync(CreateTestTemplate("Template C"));
|
|
|
|
var all = await _repo.GetAllAsync();
|
|
|
|
Assert.Equal(3, all.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Delete_RemovesTemplate()
|
|
{
|
|
var template = CreateTestTemplate();
|
|
await _repo.SaveAsync(template);
|
|
Assert.NotNull(await _repo.GetByIdAsync(template.Id));
|
|
|
|
await _repo.DeleteAsync(template.Id);
|
|
|
|
Assert.Null(await _repo.GetByIdAsync(template.Id));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Rename_UpdatesTemplateName()
|
|
{
|
|
var template = CreateTestTemplate("Old Name");
|
|
await _repo.SaveAsync(template);
|
|
|
|
await _repo.RenameAsync(template.Id, "New Name");
|
|
|
|
var loaded = await _repo.GetByIdAsync(template.Id);
|
|
Assert.Equal("New Name", loaded!.Name);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetAll_EmptyDirectory_ReturnsEmptyList()
|
|
{
|
|
var all = await _repo.GetAllAsync();
|
|
Assert.Empty(all);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetById_NonExistent_ReturnsNull()
|
|
{
|
|
var result = await _repo.GetByIdAsync("nonexistent-id");
|
|
Assert.Null(result);
|
|
}
|
|
}
|