353 lines
8.9 KiB
C#
353 lines
8.9 KiB
C#
using FluentAssertions;
|
|
using StorageService.Domain.AggregatesModel.FolderAggregate;
|
|
using Xunit;
|
|
|
|
namespace StorageService.UnitTests.Domain;
|
|
/// <summary>
|
|
/// EN: Tests for Folder aggregate root.
|
|
/// VI: Kiểm thử cho aggregate root Folder.
|
|
/// </summary>
|
|
public class FolderTests
|
|
{
|
|
private const string ValidUserId = "user-123";
|
|
private const string ValidFolderName = "Documents";
|
|
|
|
#region CreateRoot Tests
|
|
|
|
[Fact]
|
|
public void CreateRoot_ValidParams_CreatesRootFolder()
|
|
{
|
|
// Arrange & Act
|
|
var folder = Folder.CreateRoot(ValidUserId, ValidFolderName);
|
|
|
|
// Assert
|
|
folder.Should().NotBeNull();
|
|
folder.Id.Should().NotBeEmpty();
|
|
folder.UserId.Should().Be(ValidUserId);
|
|
folder.Name.Should().Be(ValidFolderName);
|
|
folder.IsDeleted.Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateRoot_SetsLevelToZero()
|
|
{
|
|
// Arrange & Act
|
|
var folder = Folder.CreateRoot(ValidUserId, ValidFolderName);
|
|
|
|
// Assert
|
|
folder.Level.Should().Be(0);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateRoot_SetsPathCorrectly()
|
|
{
|
|
// Arrange & Act
|
|
var folder = Folder.CreateRoot(ValidUserId, ValidFolderName);
|
|
|
|
// Assert
|
|
folder.Path.Should().Be($"/{ValidFolderName}/");
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateRoot_SetsParentIdToNull()
|
|
{
|
|
// Arrange & Act
|
|
var folder = Folder.CreateRoot(ValidUserId, ValidFolderName);
|
|
|
|
// Assert
|
|
folder.ParentId.Should().BeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateRoot_SetsCreatedAtAndUpdatedAt()
|
|
{
|
|
// Arrange & Act
|
|
var beforeCreate = DateTime.UtcNow;
|
|
var folder = Folder.CreateRoot(ValidUserId, ValidFolderName);
|
|
|
|
// Assert
|
|
folder.CreatedAt.Should().BeOnOrAfter(beforeCreate);
|
|
folder.UpdatedAt.Should().BeOnOrAfter(beforeCreate);
|
|
folder.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region CreateChild Tests
|
|
|
|
[Fact]
|
|
public void CreateChild_InheritsUserId()
|
|
{
|
|
// Arrange
|
|
var parentFolder = Folder.CreateRoot(ValidUserId, "Parent");
|
|
|
|
// Act
|
|
var childFolder = parentFolder.CreateChild("Child");
|
|
|
|
// Assert
|
|
childFolder.UserId.Should().Be(ValidUserId);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateChild_SetsParentId()
|
|
{
|
|
// Arrange
|
|
var parentFolder = Folder.CreateRoot(ValidUserId, "Parent");
|
|
|
|
// Act
|
|
var childFolder = parentFolder.CreateChild("Child");
|
|
|
|
// Assert
|
|
childFolder.ParentId.Should().Be(parentFolder.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateChild_IncrementsLevel()
|
|
{
|
|
// Arrange
|
|
var rootFolder = Folder.CreateRoot(ValidUserId, "Root");
|
|
|
|
// Act
|
|
var level1 = rootFolder.CreateChild("Level1");
|
|
var level2 = level1.CreateChild("Level2");
|
|
var level3 = level2.CreateChild("Level3");
|
|
|
|
// Assert
|
|
rootFolder.Level.Should().Be(0);
|
|
level1.Level.Should().Be(1);
|
|
level2.Level.Should().Be(2);
|
|
level3.Level.Should().Be(3);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateChild_AppendsToPath()
|
|
{
|
|
// Arrange
|
|
var rootFolder = Folder.CreateRoot(ValidUserId, "Root");
|
|
|
|
// Act
|
|
var childFolder = rootFolder.CreateChild("Child");
|
|
var grandchildFolder = childFolder.CreateChild("Grandchild");
|
|
|
|
// Assert
|
|
rootFolder.Path.Should().Be("/Root/");
|
|
childFolder.Path.Should().Be("/Root/Child/");
|
|
grandchildFolder.Path.Should().Be("/Root/Child/Grandchild/");
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateChild_GeneratesUniqueId()
|
|
{
|
|
// Arrange
|
|
var parentFolder = Folder.CreateRoot(ValidUserId, "Parent");
|
|
|
|
// Act
|
|
var child1 = parentFolder.CreateChild("Child1");
|
|
var child2 = parentFolder.CreateChild("Child2");
|
|
|
|
// Assert
|
|
child1.Id.Should().NotBe(child2.Id);
|
|
child1.Id.Should().NotBe(parentFolder.Id);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Rename Tests
|
|
|
|
[Fact]
|
|
public void Rename_ValidName_UpdatesNameAndPath()
|
|
{
|
|
// Arrange
|
|
var folder = Folder.CreateRoot(ValidUserId, "OldName");
|
|
var beforeRename = folder.UpdatedAt;
|
|
|
|
// Act
|
|
Thread.Sleep(10); // Ensure time difference
|
|
folder.Rename("NewName");
|
|
|
|
// Assert
|
|
folder.Name.Should().Be("NewName");
|
|
folder.Path.Should().Be("/NewName/");
|
|
folder.UpdatedAt.Should().BeAfter(beforeRename);
|
|
}
|
|
|
|
[Fact]
|
|
public void Rename_ChildFolder_UpdatesPathCorrectly()
|
|
{
|
|
// Arrange
|
|
var rootFolder = Folder.CreateRoot(ValidUserId, "Root");
|
|
var childFolder = rootFolder.CreateChild("OldChild");
|
|
|
|
// Act
|
|
childFolder.Rename("NewChild");
|
|
|
|
// Assert
|
|
childFolder.Name.Should().Be("NewChild");
|
|
childFolder.Path.Should().Be("/Root/NewChild/");
|
|
}
|
|
|
|
[Fact]
|
|
public void Rename_DeletedFolder_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var folder = Folder.CreateRoot(ValidUserId, "Folder");
|
|
folder.Delete();
|
|
|
|
// Act
|
|
var act = () => folder.Rename("NewName");
|
|
|
|
// Assert
|
|
act.Should().Throw<InvalidOperationException>()
|
|
.WithMessage("*deleted*");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MoveTo Tests
|
|
|
|
[Fact]
|
|
public void MoveTo_NullParent_BecomesRoot()
|
|
{
|
|
// Arrange
|
|
var rootFolder = Folder.CreateRoot(ValidUserId, "Root");
|
|
var childFolder = rootFolder.CreateChild("Child");
|
|
|
|
// Act
|
|
childFolder.MoveTo(null);
|
|
|
|
// Assert
|
|
childFolder.ParentId.Should().BeNull();
|
|
childFolder.Level.Should().Be(0);
|
|
childFolder.Path.Should().Be("/Child/");
|
|
}
|
|
|
|
[Fact]
|
|
public void MoveTo_ValidParent_UpdatesHierarchy()
|
|
{
|
|
// Arrange
|
|
var folder1 = Folder.CreateRoot(ValidUserId, "Folder1");
|
|
var folder2 = Folder.CreateRoot(ValidUserId, "Folder2");
|
|
var childFolder = folder1.CreateChild("Child");
|
|
|
|
// Act
|
|
childFolder.MoveTo(folder2);
|
|
|
|
// Assert
|
|
childFolder.ParentId.Should().Be(folder2.Id);
|
|
childFolder.Level.Should().Be(1);
|
|
childFolder.Path.Should().Be("/Folder2/Child/");
|
|
}
|
|
|
|
[Fact]
|
|
public void MoveTo_DifferentUser_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var folder1 = Folder.CreateRoot("user-1", "Folder1");
|
|
var folder2 = Folder.CreateRoot("user-2", "Folder2");
|
|
|
|
// Act
|
|
var act = () => folder1.MoveTo(folder2);
|
|
|
|
// Assert
|
|
act.Should().Throw<InvalidOperationException>()
|
|
.WithMessage("*different user*");
|
|
}
|
|
|
|
[Fact]
|
|
public void MoveTo_DeletedFolder_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var folder = Folder.CreateRoot(ValidUserId, "Folder");
|
|
var targetFolder = Folder.CreateRoot(ValidUserId, "Target");
|
|
folder.Delete();
|
|
|
|
// Act
|
|
var act = () => folder.MoveTo(targetFolder);
|
|
|
|
// Assert
|
|
act.Should().Throw<InvalidOperationException>()
|
|
.WithMessage("*deleted*");
|
|
}
|
|
|
|
[Fact]
|
|
public void MoveTo_UpdatesUpdatedAt()
|
|
{
|
|
// Arrange
|
|
var folder1 = Folder.CreateRoot(ValidUserId, "Folder1");
|
|
var folder2 = Folder.CreateRoot(ValidUserId, "Folder2");
|
|
var beforeMove = folder1.UpdatedAt;
|
|
|
|
// Act
|
|
Thread.Sleep(10);
|
|
folder1.MoveTo(folder2);
|
|
|
|
// Assert
|
|
folder1.UpdatedAt.Should().BeAfter(beforeMove);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Delete Tests
|
|
|
|
[Fact]
|
|
public void Delete_SetsIsDeletedAndDeletedAt()
|
|
{
|
|
// Arrange
|
|
var folder = Folder.CreateRoot(ValidUserId, ValidFolderName);
|
|
|
|
// Act
|
|
folder.Delete();
|
|
|
|
// Assert
|
|
folder.IsDeleted.Should().BeTrue();
|
|
folder.DeletedAt.Should().NotBeNull();
|
|
folder.DeletedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
|
}
|
|
|
|
[Fact]
|
|
public void Delete_AlreadyDeleted_DoesNotUpdateDeletedAt()
|
|
{
|
|
// Arrange
|
|
var folder = Folder.CreateRoot(ValidUserId, ValidFolderName);
|
|
folder.Delete();
|
|
var firstDeletedAt = folder.DeletedAt;
|
|
|
|
// Act
|
|
Thread.Sleep(10);
|
|
folder.Delete();
|
|
|
|
// Assert
|
|
folder.DeletedAt.Should().Be(firstDeletedAt);
|
|
}
|
|
|
|
[Fact]
|
|
public void Delete_RootFolder_SetsDeleted()
|
|
{
|
|
// Arrange
|
|
var folder = Folder.CreateRoot(ValidUserId, "Root");
|
|
|
|
// Act
|
|
folder.Delete();
|
|
|
|
// Assert
|
|
folder.IsDeleted.Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Delete_ChildFolder_SetsDeleted()
|
|
{
|
|
// Arrange
|
|
var rootFolder = Folder.CreateRoot(ValidUserId, "Root");
|
|
var childFolder = rootFolder.CreateChild("Child");
|
|
|
|
// Act
|
|
childFolder.Delete();
|
|
|
|
// Assert
|
|
childFolder.IsDeleted.Should().BeTrue();
|
|
rootFolder.IsDeleted.Should().BeFalse(); // Parent should not be affected
|
|
}
|
|
|
|
#endregion
|
|
}
|