feat(template-engine): TemplateService.MoveTemplateAsync

This commit is contained in:
Joseph Doherty
2026-05-11 11:02:03 -04:00
parent 723ab61bd8
commit 72b9f7e66e
2 changed files with 68 additions and 0 deletions

View File

@@ -155,6 +155,31 @@ public class TemplateService
return Result<bool>.Success(true); return Result<bool>.Success(true);
} }
public async Task<Result<Template>> MoveTemplateAsync(
int templateId,
int? newFolderId,
string user,
CancellationToken cancellationToken = default)
{
var template = await _repository.GetTemplateByIdAsync(templateId, cancellationToken);
if (template == null)
return Result<Template>.Failure($"Template with ID {templateId} not found.");
if (newFolderId.HasValue)
{
var folder = await _repository.GetFolderByIdAsync(newFolderId.Value, cancellationToken);
if (folder == null)
return Result<Template>.Failure($"Target folder with ID {newFolderId.Value} not found.");
}
template.FolderId = newFolderId;
await _repository.UpdateTemplateAsync(template, cancellationToken);
await _repository.SaveChangesAsync(cancellationToken);
await _auditService.LogAsync(user, "Move", "Template", template.Id.ToString(), template.Name, template, cancellationToken);
return Result<Template>.Success(template);
}
public async Task<Template?> GetTemplateByIdAsync(int templateId, CancellationToken cancellationToken = default) public async Task<Template?> GetTemplateByIdAsync(int templateId, CancellationToken cancellationToken = default)
{ {
return await _repository.GetTemplateByIdAsync(templateId, cancellationToken); return await _repository.GetTemplateByIdAsync(templateId, cancellationToken);

View File

@@ -507,4 +507,47 @@ public class TemplateServiceTests
Assert.True(result.IsFailure); Assert.True(result.IsFailure);
Assert.Contains("cycle", result.Error, StringComparison.OrdinalIgnoreCase); Assert.Contains("cycle", result.Error, StringComparison.OrdinalIgnoreCase);
} }
// ========================================================================
// Move template between folders
// ========================================================================
[Fact]
public async Task MoveTemplate_ToFolder_ReturnsSuccess()
{
var t = new Template("X") { Id = 1, FolderId = null };
var folder = new TemplateFolder("Dev") { Id = 7 };
_repoMock.Setup(r => r.GetTemplateByIdAsync(1, It.IsAny<CancellationToken>())).ReturnsAsync(t);
_repoMock.Setup(r => r.GetFolderByIdAsync(7, It.IsAny<CancellationToken>())).ReturnsAsync(folder);
var result = await _service.MoveTemplateAsync(1, 7, "admin");
Assert.True(result.IsSuccess);
Assert.Equal(7, result.Value.FolderId);
}
[Fact]
public async Task MoveTemplate_ToRoot_ReturnsSuccess()
{
var t = new Template("X") { Id = 1, FolderId = 7 };
_repoMock.Setup(r => r.GetTemplateByIdAsync(1, It.IsAny<CancellationToken>())).ReturnsAsync(t);
var result = await _service.MoveTemplateAsync(1, null, "admin");
Assert.True(result.IsSuccess);
Assert.Null(result.Value.FolderId);
}
[Fact]
public async Task MoveTemplate_TargetFolderMissing_ReturnsFailure()
{
var t = new Template("X") { Id = 1 };
_repoMock.Setup(r => r.GetTemplateByIdAsync(1, It.IsAny<CancellationToken>())).ReturnsAsync(t);
_repoMock.Setup(r => r.GetFolderByIdAsync(99, It.IsAny<CancellationToken>())).ReturnsAsync((TemplateFolder?)null);
var result = await _service.MoveTemplateAsync(1, 99, "admin");
Assert.True(result.IsFailure);
Assert.Contains("not found", result.Error);
}
} }