feat(template-folder): move with cycle detection and sibling uniqueness
This commit is contained in:
@@ -107,4 +107,64 @@ public class TemplateFolderServiceTests
|
||||
Assert.True(result.IsFailure);
|
||||
Assert.Contains("already exists", result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MoveFolder_ValidParent_ReturnsSuccess()
|
||||
{
|
||||
var f1 = new TemplateFolder("A") { Id = 1, ParentFolderId = null };
|
||||
var f2 = new TemplateFolder("B") { Id = 2, ParentFolderId = null };
|
||||
_repoMock.Setup(r => r.GetFolderByIdAsync(1, It.IsAny<CancellationToken>())).ReturnsAsync(f1);
|
||||
_repoMock.Setup(r => r.GetFolderByIdAsync(2, It.IsAny<CancellationToken>())).ReturnsAsync(f2);
|
||||
_repoMock.Setup(r => r.GetAllFoldersAsync(It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new List<TemplateFolder> { f1, f2 });
|
||||
|
||||
var result = await _sut.MoveFolderAsync(1, 2, "admin");
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(2, result.Value.ParentFolderId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MoveFolder_OntoSelf_ReturnsFailure()
|
||||
{
|
||||
var f1 = new TemplateFolder("A") { Id = 1 };
|
||||
_repoMock.Setup(r => r.GetFolderByIdAsync(1, It.IsAny<CancellationToken>())).ReturnsAsync(f1);
|
||||
|
||||
var result = await _sut.MoveFolderAsync(1, 1, "admin");
|
||||
|
||||
Assert.True(result.IsFailure);
|
||||
Assert.Contains("cycle", result.Error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MoveFolder_OntoDescendant_ReturnsFailure()
|
||||
{
|
||||
// A -> B -> C; attempting to move A under C must fail.
|
||||
var fa = new TemplateFolder("A") { Id = 1, ParentFolderId = null };
|
||||
var fb = new TemplateFolder("B") { Id = 2, ParentFolderId = 1 };
|
||||
var fc = new TemplateFolder("C") { Id = 3, ParentFolderId = 2 };
|
||||
_repoMock.Setup(r => r.GetFolderByIdAsync(1, It.IsAny<CancellationToken>())).ReturnsAsync(fa);
|
||||
_repoMock.Setup(r => r.GetFolderByIdAsync(3, It.IsAny<CancellationToken>())).ReturnsAsync(fc);
|
||||
_repoMock.Setup(r => r.GetAllFoldersAsync(It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new List<TemplateFolder> { fa, fb, fc });
|
||||
|
||||
var result = await _sut.MoveFolderAsync(1, 3, "admin");
|
||||
|
||||
Assert.True(result.IsFailure);
|
||||
Assert.Contains("cycle", result.Error, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task MoveFolder_ToRoot_ReturnsSuccess()
|
||||
{
|
||||
var f = new TemplateFolder("Sub") { Id = 1, ParentFolderId = 99 };
|
||||
_repoMock.Setup(r => r.GetFolderByIdAsync(1, It.IsAny<CancellationToken>())).ReturnsAsync(f);
|
||||
_repoMock.Setup(r => r.GetAllFoldersAsync(It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new List<TemplateFolder> { f });
|
||||
|
||||
var result = await _sut.MoveFolderAsync(1, null, "admin");
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Null(result.Value.ParentFolderId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user