using System; using GermanApp.Domain.Entities; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace GermanApp.Tests.Unit.Domain.Entities; /// /// Unit tests for User domain entity. /// Tests the user factory methods and business logic. /// [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 }