using ColaFlow.Modules.Identity.Domain.Aggregates.Users; using ColaFlow.Modules.Identity.Domain.Entities; using FluentAssertions; using Xunit; namespace ColaFlow.Modules.Identity.Domain.Tests.Entities; public sealed class EmailVerificationTokenTests { private readonly UserId _userId = UserId.CreateUnique(); private const string TestTokenHash = "hashed_token_value"; [Fact] public void Create_WithValidData_ShouldSucceed() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); // Act var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Assert token.Should().NotBeNull(); token.Id.Should().NotBe(Guid.Empty); token.UserId.Should().Be(_userId); token.TokenHash.Should().Be(TestTokenHash); token.ExpiresAt.Should().Be(expiresAt); token.VerifiedAt.Should().BeNull(); token.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1)); token.IsExpired.Should().BeFalse(); token.IsVerified.Should().BeFalse(); token.IsValid.Should().BeTrue(); } [Fact] public void IsExpired_WithFutureExpiration_ShouldReturnFalse() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Act & Assert token.IsExpired.Should().BeFalse(); } [Fact] public void IsExpired_WithPastExpiration_ShouldReturnTrue() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(-1); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Act & Assert token.IsExpired.Should().BeTrue(); } [Fact] public void IsVerified_WhenNotVerified_ShouldReturnFalse() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Act & Assert token.IsVerified.Should().BeFalse(); } [Fact] public void IsVerified_WhenVerified_ShouldReturnTrue() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); token.MarkAsVerified(); // Act & Assert token.IsVerified.Should().BeTrue(); } [Fact] public void IsValid_WithValidToken_ShouldReturnTrue() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Act & Assert token.IsValid.Should().BeTrue(); } [Fact] public void IsValid_WithExpiredToken_ShouldReturnFalse() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(-1); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Act & Assert token.IsValid.Should().BeFalse(); } [Fact] public void IsValid_WithVerifiedToken_ShouldReturnFalse() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); token.MarkAsVerified(); // Act & Assert token.IsValid.Should().BeFalse(); } [Fact] public void MarkAsVerified_WithValidToken_ShouldSetVerifiedAt() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Act token.MarkAsVerified(); // Assert token.VerifiedAt.Should().NotBeNull(); token.VerifiedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1)); token.IsVerified.Should().BeTrue(); token.IsValid.Should().BeFalse(); } [Fact] public void MarkAsVerified_WithExpiredToken_ShouldThrowException() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(-1); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); // Act var act = () => token.MarkAsVerified(); // Assert act.Should().Throw() .WithMessage("*Token is not valid for verification*"); } [Fact] public void MarkAsVerified_WithAlreadyVerifiedToken_ShouldThrowException() { // Arrange var expiresAt = DateTime.UtcNow.AddHours(24); var token = EmailVerificationToken.Create(_userId, TestTokenHash, expiresAt); token.MarkAsVerified(); // Act var act = () => token.MarkAsVerified(); // Assert act.Should().Throw() .WithMessage("*Token is not valid for verification*"); } }