- 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>
428 lines
10 KiB
C#
428 lines
10 KiB
C#
using System;
|
|
using GermanApp.Domain.Entities;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
|
namespace GermanApp.Tests.Unit.Domain.Entities;
|
|
|
|
/// <summary>
|
|
/// Unit tests for User domain entity.
|
|
/// Tests the user factory methods and business logic.
|
|
/// </summary>
|
|
[TestClass]
|
|
public class UserTests
|
|
{
|
|
#region Factory Method Tests
|
|
|
|
[TestMethod]
|
|
[TestCategory("Factory")]
|
|
public void Create_WithValidParameters_ReturnsUser()
|
|
{
|
|
// Arrange
|
|
string username = "testuser";
|
|
string email = "test@example.com";
|
|
string passwordHash = "hashed-password";
|
|
|
|
// Act
|
|
var user = User.Create(username, email, passwordHash);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(user);
|
|
Assert.AreEqual(username, user.Username);
|
|
Assert.AreEqual(email, user.Email);
|
|
Assert.AreEqual(passwordHash, user.PasswordHash);
|
|
Assert.AreEqual("A1", user.CurrentLevel);
|
|
Assert.AreEqual(0, user.Streak);
|
|
Assert.AreEqual(0, user.TotalPoints);
|
|
Assert.IsNotNull(user.CreatedAt);
|
|
Assert.IsTrue(user.CreatedAt <= DateTime.UtcNow);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Factory")]
|
|
public void Create_WithEmptyPasswordHash_ReturnsUser()
|
|
{
|
|
// Arrange
|
|
string username = "testuser";
|
|
string email = "test@example.com";
|
|
string passwordHash = "";
|
|
|
|
// Act
|
|
var user = User.Create(username, email, passwordHash);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(user);
|
|
Assert.AreEqual(passwordHash, user.PasswordHash);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Factory")]
|
|
public void Create_LowercasesEmail()
|
|
{
|
|
// Arrange
|
|
string username = "testuser";
|
|
string email = "TEST@EXAMPLE.COM";
|
|
string passwordHash = "hashed-password";
|
|
|
|
// Act
|
|
var user = User.Create(username, email, passwordHash);
|
|
|
|
// Assert
|
|
Assert.AreEqual("test@example.com", user.Email);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Factory")]
|
|
public void Create_WithMixedCaseUsername_PreservesUsernameCase()
|
|
{
|
|
// Arrange
|
|
string username = "TestUser123";
|
|
string email = "test@example.com";
|
|
string passwordHash = "hashed-password";
|
|
|
|
// Act
|
|
var user = User.Create(username, email, passwordHash);
|
|
|
|
// Assert
|
|
Assert.AreEqual(username, user.Username);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ChangePassword Method Tests
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangePassword_WithValidHash_UpdatesPassword()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "initial-hash");
|
|
string newHash = "new-hashed-password";
|
|
|
|
// Act
|
|
user.ChangePassword(newHash);
|
|
|
|
// Assert
|
|
Assert.AreEqual(newHash, user.PasswordHash);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangePassword_WithEmptyHash_UpdatesPassword()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "initial-hash");
|
|
|
|
// Act
|
|
user.ChangePassword("");
|
|
|
|
// Assert
|
|
Assert.AreEqual("", user.PasswordHash);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangePassword_MultipleTimes_UpdatesCorrectly()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash1");
|
|
|
|
// Act
|
|
user.ChangePassword("hash2");
|
|
user.ChangePassword("hash3");
|
|
|
|
// Assert
|
|
Assert.AreEqual("hash3", user.PasswordHash);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ChangeEmail Method Tests
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangeEmail_WithValidEmail_UpdatesEmail()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
var newEmail = "new@example.com";
|
|
|
|
// Act
|
|
user.ChangeEmail(newEmail);
|
|
|
|
// Assert
|
|
Assert.AreEqual("new@example.com", user.Email);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangeEmail_LowercasesEmail()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act
|
|
user.ChangeEmail("UPPERCASE@EXAMPLE.COM");
|
|
|
|
// Assert
|
|
Assert.AreEqual("uppercase@example.com", user.Email);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangeEmail_WithMixedCase_Values()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act
|
|
user.ChangeEmail("TeSt@ExAmPlE.cOm");
|
|
|
|
// Assert
|
|
Assert.AreEqual("test@example.com", user.Email);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangeEmail_WithNullEmail_UpdatesEmailToEmpty()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act - Note: This won't throw, it will just set to empty string
|
|
user.ChangeEmail(null!);
|
|
|
|
// Assert
|
|
Assert.AreEqual("", user.Email);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Behavior")]
|
|
public void ChangeEmail_WithEmptyString_SetsEmptyEmail()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act
|
|
user.ChangeEmail("");
|
|
|
|
// Assert
|
|
Assert.AreEqual("", user.Email);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Gamification Methods Tests
|
|
|
|
[TestMethod]
|
|
[TestCategory("Gamification")]
|
|
public void AddPoints_IncreasesTotalPoints()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
int initialPoints = user.TotalPoints;
|
|
|
|
// Act
|
|
user.AddPoints(10);
|
|
|
|
// Assert
|
|
Assert.AreEqual(initialPoints + 10, user.TotalPoints);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Gamification")]
|
|
public void AddPoints_MultipleTimes_AccumulatesCorrectly()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act
|
|
user.AddPoints(10);
|
|
user.AddPoints(20);
|
|
user.AddPoints(30);
|
|
|
|
// Assert
|
|
Assert.AreEqual(60, user.TotalPoints);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Gamification")]
|
|
public void AddPoints_WithNegativePoints_DecreasesTotal()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
user.AddPoints(100);
|
|
|
|
// Act
|
|
user.AddPoints(-10);
|
|
|
|
// Assert
|
|
Assert.AreEqual(90, user.TotalPoints);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Gamification")]
|
|
public void UpdateStreak_SetsNewStreak()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act
|
|
user.UpdateStreak(5);
|
|
|
|
// Assert
|
|
Assert.AreEqual(5, user.Streak);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Gamification")]
|
|
public void UpdateStreak_WithZero_ResetsStreak()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
user.UpdateStreak(10);
|
|
|
|
// Act
|
|
user.UpdateStreak(0);
|
|
|
|
// Assert
|
|
Assert.AreEqual(0, user.Streak);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Gamification")]
|
|
public void UpdateLevel_SetsNewLevel()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act
|
|
user.UpdateLevel("B1");
|
|
|
|
// Assert
|
|
Assert.AreEqual("B1", user.CurrentLevel);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Gamification")]
|
|
public void UpdateLevel_ToHigherLevel_UpdatesCorrectly()
|
|
{
|
|
// Arrange
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Act
|
|
user.UpdateLevel("A2");
|
|
user.UpdateLevel("B1");
|
|
user.UpdateLevel("C1");
|
|
|
|
// Assert
|
|
Assert.AreEqual("C1", user.CurrentLevel);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Property Tests
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void Id_HasDefaultValueOfZero()
|
|
{
|
|
// Arrange & Act
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Assert
|
|
Assert.AreEqual(0, user.Id);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void Username_HasPrivateSetter()
|
|
{
|
|
// Arrange
|
|
var username = "testuser";
|
|
|
|
// Act
|
|
var user = User.Create(username, "test@example.com", "hash");
|
|
|
|
// Assert
|
|
Assert.AreEqual(username, user.Username);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void Email_HasPrivateSetter()
|
|
{
|
|
// Arrange
|
|
var email = "test@example.com";
|
|
|
|
// Act
|
|
var user = User.Create("testuser", email, "hash");
|
|
|
|
// Assert
|
|
Assert.AreEqual(email, user.Email);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void PasswordHash_HasPrivateSetter()
|
|
{
|
|
// Arrange
|
|
var passwordHash = "hashed-password-123";
|
|
|
|
// Act
|
|
var user = User.Create("testuser", "test@example.com", passwordHash);
|
|
|
|
// Assert
|
|
Assert.AreEqual(passwordHash, user.PasswordHash);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void CurrentLevel_HasDefaultValueOf_A1()
|
|
{
|
|
// Arrange & Act
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Assert
|
|
Assert.AreEqual("A1", user.CurrentLevel);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void Streak_HasDefaultValueOfZero()
|
|
{
|
|
// Arrange & Act
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Assert
|
|
Assert.AreEqual(0, user.Streak);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void TotalPoints_HasDefaultValueOfZero()
|
|
{
|
|
// Arrange & Act
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
|
|
// Assert
|
|
Assert.AreEqual(0, user.TotalPoints);
|
|
}
|
|
|
|
[TestMethod]
|
|
[TestCategory("Property")]
|
|
public void CreatedAt_IsSetToCurrentTime()
|
|
{
|
|
// Arrange
|
|
var beforeCreation = DateTime.UtcNow;
|
|
|
|
// Act
|
|
var user = User.Create("testuser", "test@example.com", "hash");
|
|
var afterCreation = DateTime.UtcNow;
|
|
|
|
// Assert
|
|
Assert.IsTrue(user.CreatedAt >= beforeCreation);
|
|
Assert.IsTrue(user.CreatedAt <= afterCreation);
|
|
}
|
|
|
|
#endregion
|
|
}
|