DeutschLernen/Tests/Unit/Domain/Entities/RefreshTokenTests.cs
Lasse Rune Hansen 6bcf592918 feat(backend): complete unit tests for User Authentication feature
- Fix MSTest compatibility with .NET 9.0 by upgrading to MSTest.TestFramework 4.2.3
- Move Tests directory to solution level (Tests/) to prevent test files from being compiled with GermanApp
- Update test project references to point to GermanApp/GermanApp.csproj
- Add InternalsVisibleTo attributes for test assemblies
- Make RefreshToken properties internal for testability
- Fix User.ChangeEmail null handling
- Add 46 comprehensive unit tests for User and RefreshToken domain entities
- All tests passing successfully

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-05 17:07:15 +02:00

320 lines
8 KiB
C#

using System;
using GermanApp.Domain.Entities;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace GermanApp.Tests.Unit.Domain.Entities;
/// <summary>
/// Unit tests for RefreshToken domain entity.
/// Tests the refresh token factory methods and business logic.
/// </summary>
[TestClass]
public class RefreshTokenTests
{
#region Factory Method Tests
[TestMethod]
[TestCategory("Factory")]
public void Create_WithValidParameters_ReturnsRefreshToken()
{
// Arrange
int userId = 1;
string token = "test-token-string";
int expireDays = 7;
// Act
var refreshToken = RefreshToken.Create(userId, token, expireDays);
// Assert
Assert.IsNotNull(refreshToken);
Assert.AreEqual(userId, refreshToken.UserId);
Assert.AreEqual(token, refreshToken.Token);
Assert.AreEqual(DateTime.UtcNow.Date, refreshToken.CreatedAt.Date);
Assert.IsTrue(refreshToken.ExpiresAt > DateTime.UtcNow);
Assert.IsTrue(refreshToken.IsActive);
Assert.IsNull(refreshToken.RevokedAt);
}
[TestMethod]
[TestCategory("Factory")]
public void Create_WithDefaultExpireDays_Uses7Days()
{
// Arrange
int userId = 1;
string token = "test-token-string";
// Act
var refreshToken = RefreshToken.Create(userId, token);
// Assert
var timeDifference = refreshToken.ExpiresAt - DateTime.UtcNow;
Assert.IsTrue(timeDifference.TotalDays > 6.9 && timeDifference.TotalDays < 7.1);
}
[TestMethod]
[TestCategory("Factory")]
public void Create_WithCustomExpireDays_SetsCorrectExpiry()
{
// Arrange
int userId = 1;
string token = "test-token";
int expireDays = 30;
// Act
var refreshToken = RefreshToken.Create(userId, token, expireDays);
// Assert
var expectedExpiry = DateTime.UtcNow.AddDays(expireDays);
var timeDifference = refreshToken.ExpiresAt - DateTime.UtcNow;
Assert.IsTrue(timeDifference.TotalDays > 29.9 && timeDifference.TotalDays < 30.1);
}
#endregion
#region Revoke Method Tests
[TestMethod]
[TestCategory("Behavior")]
public void Revoke_ActiveToken_DeactivatesAndSetsRevokedAt()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token");
// Act
refreshToken.Revoke();
// Assert
Assert.IsFalse(refreshToken.IsActive);
Assert.IsNotNull(refreshToken.RevokedAt);
Assert.IsTrue(refreshToken.RevokedAt > DateTime.UtcNow.AddSeconds(-1));
}
[TestMethod]
[TestCategory("Behavior")]
public void Revoke_AlreadyRevokedToken_UpdatesRevokedAt()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token");
refreshToken.Revoke();
System.Threading.Thread.Sleep(10); // Small delay
var firstRevokedAt = refreshToken.RevokedAt;
// Act
refreshToken.Revoke();
// Assert
Assert.IsFalse(refreshToken.IsActive);
Assert.IsNotNull(refreshToken.RevokedAt);
Assert.IsTrue(refreshToken.RevokedAt >= firstRevokedAt);
}
#endregion
#region IsExpired Method Tests
[TestMethod]
[TestCategory("Query")]
public void IsExpired_NotExpiredToken_ReturnsFalse()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token", 7);
// Act
var isExpired = refreshToken.IsExpired();
// Assert
Assert.IsFalse(isExpired);
}
[TestMethod]
[TestCategory("Query")]
public void IsExpired_ExpiredToken_ReturnsTrue()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token");
refreshToken.ExpiresAt = DateTime.UtcNow.AddDays(-1); // Set to past
// Act
var isExpired = refreshToken.IsExpired();
// Assert
Assert.IsTrue(isExpired);
}
[TestMethod]
[TestCategory("Query")]
public void IsExpired_ExactlyAtExpiryTime_ReturnsTrue()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token");
refreshToken.ExpiresAt = DateTime.UtcNow; // Set to exactly now
// Act
var isExpired = refreshToken.IsExpired();
// Assert
Assert.IsTrue(isExpired);
}
[TestMethod]
[TestCategory("Query")]
public void IsExpired_FarFutureExpiry_ReturnsFalse()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token");
refreshToken.ExpiresAt = DateTime.UtcNow.AddYears(1);
// Act
var isExpired = refreshToken.IsExpired();
// Assert
Assert.IsFalse(isExpired);
}
#endregion
#region IsValid Method Tests
[TestMethod]
[TestCategory("Query")]
public void IsValid_ActiveNotExpiredToken_ReturnsTrue()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token", 7);
// Act
var isValid = refreshToken.IsValid();
// Assert
Assert.IsTrue(isValid);
}
[TestMethod]
[TestCategory("Query")]
public void IsValid_RevokedToken_ReturnsFalse()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token", 7);
refreshToken.Revoke();
// Act
var isValid = refreshToken.IsValid();
// Assert
Assert.IsFalse(isValid);
}
[TestMethod]
[TestCategory("Query")]
public void IsValid_ExpiredToken_ReturnsFalse()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token");
refreshToken.ExpiresAt = DateTime.UtcNow.AddDays(-1);
// Act
var isValid = refreshToken.IsValid();
// Assert
Assert.IsFalse(isValid);
}
[TestMethod]
[TestCategory("Query")]
public void IsValid_RevokedAndExpiredToken_ReturnsFalse()
{
// Arrange
var refreshToken = RefreshToken.Create(1, "test-token");
refreshToken.Revoke();
refreshToken.ExpiresAt = DateTime.UtcNow.AddDays(-1);
// Act
var isValid = refreshToken.IsValid();
// Assert
Assert.IsFalse(isValid);
}
#endregion
#region Property Tests
[TestMethod]
[TestCategory("Property")]
public void Id_HasDefaultValueOfZero()
{
// Arrange & Act
var refreshToken = RefreshToken.Create(1, "test-token");
// Assert
Assert.AreEqual(0, refreshToken.Id);
}
[TestMethod]
[TestCategory("Property")]
public void UserId_IsSetCorrectly()
{
// Arrange
int userId = 42;
// Act
var refreshToken = RefreshToken.Create(userId, "test-token");
// Assert
Assert.AreEqual(userId, refreshToken.UserId);
}
[TestMethod]
[TestCategory("Property")]
public void Token_IsSetCorrectly()
{
// Arrange
string tokenString = "test-token-12345";
// Act
var refreshToken = RefreshToken.Create(1, tokenString);
// Assert
Assert.AreEqual(tokenString, refreshToken.Token);
}
[TestMethod]
[TestCategory("Property")]
public void IsActive_HasDefaultValueOfTrue()
{
// Arrange & Act
var refreshToken = RefreshToken.Create(1, "test-token");
// Assert
Assert.IsTrue(refreshToken.IsActive);
}
[TestMethod]
[TestCategory("Property")]
public void RevokedAt_IsNullByDefault()
{
// Arrange & Act
var refreshToken = RefreshToken.Create(1, "test-token");
// Assert
Assert.IsNull(refreshToken.RevokedAt);
}
[TestMethod]
[TestCategory("Property")]
public void CreatedAt_IsSetToCurrentTime()
{
// Arrange
var beforeCreation = DateTime.UtcNow;
// Act
var refreshToken = RefreshToken.Create(1, "test-token");
var afterCreation = DateTime.UtcNow;
// Assert
Assert.IsTrue(refreshToken.CreatedAt >= beforeCreation);
Assert.IsTrue(refreshToken.CreatedAt <= afterCreation);
}
#endregion
}