using ColaFlow.Modules.Identity.Domain.Aggregates.Tenants; using ColaFlow.Modules.Identity.Domain.Aggregates.Users; using FluentAssertions; using Xunit; namespace ColaFlow.Modules.Identity.Domain.Tests.Entities; public sealed class UserTenantRoleTests { private readonly UserId _userId = UserId.CreateUnique(); private readonly TenantId _tenantId = TenantId.CreateUnique(); private readonly Guid _assignedByUserId = Guid.NewGuid(); [Fact] public void Create_WithValidData_ShouldSucceed() { // Arrange & Act var userTenantRole = UserTenantRole.Create( _userId, _tenantId, TenantRole.TenantMember, _assignedByUserId); // Assert userTenantRole.Should().NotBeNull(); userTenantRole.Id.Should().NotBe(Guid.Empty); userTenantRole.UserId.Should().Be(_userId); userTenantRole.TenantId.Should().Be(_tenantId); userTenantRole.Role.Should().Be(TenantRole.TenantMember); userTenantRole.AssignedByUserId.Should().Be(_assignedByUserId); userTenantRole.AssignedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1)); } [Fact] public void Create_WithoutAssignedByUserId_ShouldSucceed() { // Arrange & Act var userTenantRole = UserTenantRole.Create( _userId, _tenantId, TenantRole.TenantAdmin); // Assert userTenantRole.Should().NotBeNull(); userTenantRole.AssignedByUserId.Should().BeNull(); } [Fact] public void UpdateRole_WithValidRole_ShouldUpdate() { // Arrange var userTenantRole = UserTenantRole.Create( _userId, _tenantId, TenantRole.TenantMember); var originalAssignedAt = userTenantRole.AssignedAt; var updatedByUserId = Guid.NewGuid(); // Act userTenantRole.UpdateRole(TenantRole.TenantAdmin, updatedByUserId); // Assert userTenantRole.Role.Should().Be(TenantRole.TenantAdmin); userTenantRole.AssignedByUserId.Should().Be(updatedByUserId); userTenantRole.AssignedAt.Should().Be(originalAssignedAt); // AssignedAt should NOT change } [Fact] public void UpdateRole_WithSameRole_ShouldBeIdempotent() { // Arrange var userTenantRole = UserTenantRole.Create( _userId, _tenantId, TenantRole.TenantMember, _assignedByUserId); var originalAssignedByUserId = userTenantRole.AssignedByUserId; var originalRole = userTenantRole.Role; // Act userTenantRole.UpdateRole(TenantRole.TenantMember, Guid.NewGuid()); // Assert - Should not update if role is the same userTenantRole.Role.Should().Be(originalRole); userTenantRole.AssignedByUserId.Should().Be(originalAssignedByUserId); } [Fact] public void HasPermission_WithTenantOwner_ShouldReturnTrueForAllPermissions() { // Arrange var userTenantRole = UserTenantRole.Create( _userId, _tenantId, TenantRole.TenantOwner); // Act & Assert userTenantRole.HasPermission("read_projects").Should().BeTrue(); userTenantRole.HasPermission("write_projects").Should().BeTrue(); userTenantRole.HasPermission("delete_projects").Should().BeTrue(); userTenantRole.HasPermission("any_permission").Should().BeTrue(); } [Fact] public void HasPermission_WithAIAgent_ShouldReturnTrueForReadAndPreview() { // Arrange var userTenantRole = UserTenantRole.Create( _userId, _tenantId, TenantRole.AIAgent); // Act & Assert userTenantRole.HasPermission("read_projects").Should().BeTrue(); userTenantRole.HasPermission("read_users").Should().BeTrue(); userTenantRole.HasPermission("write_preview_changes").Should().BeTrue(); userTenantRole.HasPermission("write_direct_changes").Should().BeFalse(); userTenantRole.HasPermission("delete_projects").Should().BeFalse(); } }