messages;
- /**
- * Creates an empty inbox with no messages.
- */
+ /** Creates an empty inbox with no messages. */
public Inbox() {
this.messages = new ArrayList<>();
}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Language.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Language.java
similarity index 69%
rename from helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Language.java
rename to helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Language.java
index d4ab0ae..ddc5d82 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Language.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Language.java
@@ -1,4 +1,4 @@
-package ntnu.sytemutvikling.team6.models;
+package ntnu.sytemutvikling.team6.models.user;
/**
* Supported application languages.
@@ -7,4 +7,4 @@
*/
public enum Language {
ENGLISH
-}
\ No newline at end of file
+}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Message.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Message.java
similarity index 80%
rename from helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Message.java
rename to helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Message.java
index 10ea569..ef9707b 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Message.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Message.java
@@ -1,4 +1,4 @@
-package ntnu.sytemutvikling.team6.models;
+package ntnu.sytemutvikling.team6.models.user;
import java.time.LocalDateTime;
import java.util.UUID;
@@ -8,7 +8,7 @@
/**
* Represents a message.
*
- * @author Robin Strand Prestmo
+ * @author Robin Strand Prestmo
*/
public class Message {
private final UUID id;
@@ -18,18 +18,15 @@ public class Message {
private final LocalDateTime timeAndDate;
/**
- * Creates a message with a unique identifier.
- * The message includes a title, a string who it's from,
- * content and the time and date.
+ * Creates a message with a unique identifier. The message includes a title, a string who it's
+ * from, content and the time and date.
*
* @param title the title of the message
* @param from who the message is from
* @param content the content of the message
* @throws IllegalArgumentException if title, from or content is null or blank.
*/
- public Message(String title,
- String from,
- String content) {
+ public Message(String title, String from, String content) {
if (title == null || title.isBlank()) {
throw new IllegalArgumentException("Title cannot be null or blank.");
@@ -69,4 +66,4 @@ public String getContent() {
public LocalDateTime getTimeAndDate() {
return timeAndDate;
}
-}
\ No newline at end of file
+}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Role.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Role.java
similarity index 70%
rename from helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Role.java
rename to helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Role.java
index cde9117..74e134f 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Role.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Role.java
@@ -1,4 +1,4 @@
-package ntnu.sytemutvikling.team6.models;
+package ntnu.sytemutvikling.team6.models.user;
/**
* Available users
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Settings.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Settings.java
similarity index 74%
rename from helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Settings.java
rename to helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Settings.java
index cd70f0a..dd76557 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/Settings.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/Settings.java
@@ -1,4 +1,4 @@
-package ntnu.sytemutvikling.team6.models;
+package ntnu.sytemutvikling.team6.models.user;
// Mangler Enhetstesting
@@ -12,21 +12,17 @@ public class Settings {
private Language language;
private boolean anonymous;
- /**
- * Sets standard settings.
- * LightMode enabled, language set to English,
- * Anonymous disabled
- */
+ /** Sets standard settings. LightMode enabled, language set to English, Anonymous disabled */
public Settings() {
this(true, Language.ENGLISH, false);
}
+
/**
* Creates settings for a user.
*
* @param lightMode choose between light or dark mode
* @param language choose language
* @param anonymous choose if user is anonymous
- *
*/
public Settings(boolean lightMode, Language language, boolean anonymous) {
if (language == null) {
@@ -37,16 +33,12 @@ public Settings(boolean lightMode, Language language, boolean anonymous) {
this.anonymous = anonymous;
}
- /**
- * Toggles between light and dark mode
- */
+ /** Toggles between light and dark mode */
public void toggleLightMode() {
lightMode = !lightMode;
}
- /**
- * Toggles anonymous mode on and off
- */
+ /** Toggles anonymous mode on and off */
public void toggleAnonymousMode() {
anonymous = !anonymous;
}
@@ -56,12 +48,12 @@ public void toggleAnonymousMode() {
*
* @param newLanguage the language to change to.
*/
- public void changeLanguage(Language newLanguage) {
- if (newLanguage == null) {
- throw new IllegalArgumentException("Language cannot be null");
- }
+ public void changeLanguage(Language newLanguage) {
+ if (newLanguage == null) {
+ throw new IllegalArgumentException("Language cannot be null");
+ }
language = newLanguage;
- }
+ }
public boolean isLightMode() {
return lightMode;
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/User.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/User.java
new file mode 100644
index 0000000..64594a0
--- /dev/null
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/models/user/User.java
@@ -0,0 +1,149 @@
+package ntnu.sytemutvikling.team6.models.user;
+
+import java.util.UUID;
+import ntnu.sytemutvikling.team6.security.PasswordHasher;
+
+/**
+ * Represents a user in the system.
+ *
+ * A user has a unique identifier, personal information, a hashed password, a role, settings and
+ * an inbox.
+ *
+ *
The password is never stored ad plain text. It is hashed using {@link PasswordHasher}
+ *
+ * @author Robin Strand Prestmo
+ */
+public class User {
+ private static final PasswordHasher passwordHasher = new PasswordHasher();
+
+ private final UUID id;
+ private String name;
+ private String email;
+ private String passwordHash;
+ private final Role role;
+ private final Settings settings;
+ private final Inbox inbox;
+
+ /**
+ * Creates a new user.
+ *
+ * @param id gives the user a unique identifier with UUID
+ * @param name the name of the user
+ * @param email the email of the user
+ * @param password the password for the user
+ * @param role users role
+ * @param settings the user´s settings
+ * @param inbox the user´s inbox
+ * @throws IllegalArgumentException if any required argument is invalid.
+ */
+ public User(
+ String name, String email, String password, Role role, Settings settings, Inbox inbox) {
+
+ if (name == null || name.isBlank()) {
+ throw new IllegalArgumentException("Name cannot be null or blank.");
+ }
+
+ if (email == null || email.isBlank() || !email.contains("@") || !email.contains(".")) {
+ throw new IllegalArgumentException(
+ "Email cannot be null or blank," + " and must contain '@' and '.'");
+ }
+
+ if (role == null) {
+ throw new IllegalArgumentException("Role cannot be null");
+ }
+
+ if (settings == null) {
+ throw new IllegalArgumentException("Settings cannot be null");
+ }
+
+ if (inbox == null) {
+ throw new IllegalArgumentException("Inbox cannot be null");
+ }
+
+ this.id = UUID.randomUUID();
+ this.name = name;
+ this.email = email;
+ this.passwordHash = passwordHasher.getHashPassword(password);
+ this.role = role;
+ this.settings = settings;
+ this.inbox = inbox;
+ }
+
+ // Add Getters
+
+ public UUID getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public Role getRole() {
+ return role;
+ }
+
+ public Settings getSettings() {
+ return settings;
+ }
+
+ public Inbox getInbox() {
+ return inbox;
+ }
+
+ // Add Setters
+
+ /**
+ * Updates the users name.
+ *
+ * @param name the new name
+ * @throws IllegalArgumentException if the name is null or blank
+ */
+ public void setName(String name) {
+ if (name == null || name.isBlank()) {
+ throw new IllegalArgumentException("Name cannot be null or blank.");
+ }
+ this.name = name;
+ }
+
+ /**
+ * Updates the users password.
+ *
+ *
The password is hashed before being stored.
+ *
+ * @param password the new password
+ */
+ public void setPassword(String password) {
+ this.passwordHash = passwordHasher.getHashPassword(password);
+ }
+
+ /**
+ * Updates the users email.
+ *
+ * @param email the new email
+ * @throws IllegalArgumentException if the email is null, blank, or does not contain '@' or '.'
+ */
+ public void setEmail(String email) {
+ if (email == null || email.isBlank() || !email.contains("@") || !email.contains(".")) {
+ throw new IllegalArgumentException(
+ "Email cannot be null or blank," + " and must contains '@' and '.'");
+ }
+ this.email = email;
+ }
+
+ // Other methods
+
+ /**
+ * Checks if the provided password matches the stored password.
+ *
+ * @param password the password to verify
+ * @return true if the password is correct, false otherwise
+ */
+ public boolean checkPassword(String password) {
+ return passwordHasher.isValidPassword(password, passwordHash);
+ }
+}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/security/PasswordHasher.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/security/PasswordHasher.java
new file mode 100644
index 0000000..8c2f7d9
--- /dev/null
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/security/PasswordHasher.java
@@ -0,0 +1,92 @@
+package ntnu.sytemutvikling.team6.security;
+
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.Base64;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * A utility for hashing and verifying passwords using PBKDF2.
+ *
+ *
The generated hash contains both a random salt and the hashed password, encoded as Base64
+ * string.
+ *
+ * @author Robin Strand Prestmo
+ */
+public final class PasswordHasher {
+ private static final SecureRandom RNG = new SecureRandom();
+
+ /**
+ * Hashes a password using PBKDF2 and a random salt.
+ *
+ * @param password the password to hash.
+ * @return a Base64 string containing the salt and the hashed password.
+ * @throws IllegalArgumentException if the password is null or blank.
+ */
+ public String getHashPassword(String password) {
+ if (password == null || password.isBlank()) {
+ throw new IllegalArgumentException("Password cannot be null or blank.");
+ }
+
+ String hashPass = "";
+
+ try {
+ // 1. Create salt
+ byte[] salt = new byte[16];
+ RNG.nextBytes(salt);
+
+ // 2. Create PBKDF2 Hash value
+ PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 100000, 32 * 8);
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
+ byte[] hash = factory.generateSecret(spec).getEncoded();
+
+ // 3. Combine salt and password bytes
+ byte[] hashBytes = new byte[48];
+ System.arraycopy(salt, 0, hashBytes, 0, 16);
+ System.arraycopy(hash, 0, hashBytes, 16, 32);
+
+ // 4. Turn the combined salt+hash into a string.
+ hashPass = Base64.getEncoder().encodeToString(hashBytes);
+ } catch (Exception e) {
+ throw new RuntimeException("Error while hashing password.", e);
+ }
+ return hashPass;
+ }
+
+ /**
+ * Checks if the password matches a perviously stored hash.
+ *
+ * @param password The password the user types.
+ * @param hashPass Is the stored hashed password
+ * @return True if password is valid, otherwise false.
+ */
+ public boolean isValidPassword(String password, String hashPass) {
+ if (password == null || password.isBlank()) {
+ return false;
+ }
+
+ try {
+ // Extract the bytes
+ byte[] hashBytes = Base64.getDecoder().decode(hashPass);
+
+ // Get salt
+ byte[] salt = new byte[16];
+ System.arraycopy(hashBytes, 0, salt, 0, 16);
+
+ // Compute the hash on the password the user entered
+ PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 100000, 32 * 8);
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
+ byte[] hash = factory.generateSecret(spec).getEncoded();
+
+ // Compare results
+ byte[] storedHash = new byte[32];
+ System.arraycopy(hashBytes, 16, storedHash, 0, 32);
+
+ return MessageDigest.isEqual(storedHash, hash);
+
+ } catch (Exception e) {
+ throw new RuntimeException("Error while validating password.", e);
+ }
+ }
+}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/AuthenticationService.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/AuthenticationService.java
index e69de29..8b13789 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/AuthenticationService.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/AuthenticationService.java
@@ -0,0 +1 @@
+
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/CharityService.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/CharityService.java
index 62fe87c..3b66851 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/CharityService.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/CharityService.java
@@ -1,5 +1,3 @@
package ntnu.sytemutvikling.team6.service;
-public class CharityService {
-
-}
+public class CharityService {}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/DonationService.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/DonationService.java
index ea3b1d7..17692d5 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/DonationService.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/DonationService.java
@@ -1,5 +1,3 @@
package ntnu.sytemutvikling.team6.service;
-public class DonationService {
-
-}
+public class DonationService {}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/FeedbackService.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/FeedbackService.java
index 8aedf7f..27eee23 100644
--- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/FeedbackService.java
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/service/FeedbackService.java
@@ -1,5 +1,3 @@
package ntnu.sytemutvikling.team6.service;
-public class FeedbackService {
-
-}
+public class FeedbackService {}
diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityRegistryTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityRegistryTest.java
new file mode 100644
index 0000000..232431f
--- /dev/null
+++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityRegistryTest.java
@@ -0,0 +1,91 @@
+package ntnu.systemutvikling.team6.models;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+import ntnu.sytemutvikling.team6.models.Charity;
+import ntnu.sytemutvikling.team6.models.CharityRegistry;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * UnitTest for CharityRegistry class
+ *
+ * @author Adrian Balunan
+ */
+public class CharityRegistryTest {
+ private CharityRegistry registry;
+ private Charity charity;
+
+ /* Setting up variables */
+ @BeforeEach
+ public void setup() {
+ registry = new CharityRegistry();
+ charity = new Charity("Charity1", "Something Somewhere Somehow", "Cancer");
+ }
+
+ @Test
+ void testAddCharitySuccessfully() {
+ registry.addCharity(charity);
+
+ assertEquals(1, registry.getAllCharities().size());
+ assertTrue(registry.getAllCharities().contains(charity));
+ }
+
+ @Test
+ void testAddCharityNullThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> registry.addCharity(null));
+ }
+
+ @Test
+ void testGetAllCharitiesReturnsUnmodifiableList() {
+ registry.addCharity(charity);
+
+ List charities = registry.getAllCharities();
+ assertThrows(UnsupportedOperationException.class, () -> charities.add(charity));
+ }
+
+ @Test
+ void testFindCharityByIdFound() {
+ registry.addCharity(charity);
+
+ Optional result = registry.findCharityById(charity.getId());
+
+ assertTrue(result.isPresent());
+ assertEquals(charity, result.get());
+ }
+
+ @Test
+ void testFindCharityByIdNotFound() {
+ Optional result = registry.findCharityById(UUID.randomUUID());
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ void testFindCharityByIdNullThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> registry.findCharityById(null));
+ }
+
+ @Test
+ void testRemoveCharitySuccessfully() {
+ registry.addCharity(charity);
+
+ boolean removed = registry.removeCharity(charity.getId());
+
+ assertTrue(removed);
+ assertTrue(registry.getAllCharities().isEmpty());
+ }
+
+ @Test
+ void testRemoveCharityNotFound() {
+ boolean removed = registry.removeCharity(UUID.randomUUID());
+ assertFalse(removed);
+ }
+
+ @Test
+ void testRemoveCharityNullThrowsException() {
+ assertThrows(IllegalArgumentException.class, () -> registry.removeCharity(null));
+ }
+}
diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityTest.java
new file mode 100644
index 0000000..5c2f9c2
--- /dev/null
+++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/CharityTest.java
@@ -0,0 +1,62 @@
+package ntnu.systemutvikling.team6.models;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.UUID;
+import ntnu.sytemutvikling.team6.models.Charity;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * UnitTesting for Charity.
+ *
+ * @author Adrian Balunan
+ */
+public class CharityTest {
+ private Charity charity;
+
+ @BeforeEach
+ public void setup() {
+ charity = new Charity("Charity1", "Something Somewhere Somehow", "Cancer");
+ }
+
+ /** Getters should work: */
+ @Test
+ public void testGettingIdShouldWork() {
+ assertInstanceOf(UUID.class, charity.getId());
+ }
+
+ @Test
+ public void testGettingCategoryShouldWork() {
+ assertEquals("Cancer", charity.getCategory());
+ }
+
+ @Test
+ public void testGettingNameShouldWork() {
+ assertEquals("Charity1", charity.getName());
+ }
+
+ @Test
+ public void testGettingDescriptionShouldWork() {
+ assertEquals("Something Somewhere Somehow", charity.getDescription());
+ }
+
+ /** Getter and setter for IsVerified should be able to switch between true and false */
+ @Test
+ public void testIsVerifiedReturnsCorrectly() {
+ assertFalse(charity.isVerified());
+ charity.setVerified();
+ assertTrue(charity.isVerified());
+ charity.setUnverified();
+ assertFalse(charity.isVerified());
+ }
+
+ /** totalDonations should display accuratly and adding works */
+ @Test
+ public void testTotalDonationsReturnsCorrectlyAfterChanges() {
+ assertEquals(0, charity.getTotalDonations());
+ charity.setTotalDonations(10);
+ charity.setTotalDonations(5);
+ assertEquals(15, charity.getTotalDonations());
+ }
+}
diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/DonationTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/DonationTest.java
new file mode 100644
index 0000000..17bfaef
--- /dev/null
+++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/DonationTest.java
@@ -0,0 +1,93 @@
+package ntnu.systemutvikling.team6.models;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.time.LocalDateTime;
+import ntnu.sytemutvikling.team6.models.Charity;
+import ntnu.sytemutvikling.team6.models.Donation;
+import ntnu.sytemutvikling.team6.models.user.Inbox;
+import ntnu.sytemutvikling.team6.models.user.Role;
+import ntnu.sytemutvikling.team6.models.user.Settings;
+import ntnu.sytemutvikling.team6.models.user.User;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class DonationTest {
+ private Settings settings;
+ private User user;
+ private Charity charity;
+
+ // -- Setup --
+ @BeforeEach
+ public void setup() {
+ charity = new Charity("name", "something somewhere somehow", "Meow");
+ user =
+ new User("Name", "Valid@gmail.com", "123", Role.NORMAL_USER, new Settings(), new Inbox());
+ }
+
+ // --- Tests ---
+ @Test
+ void testDonationInitialization() {
+ LocalDateTime now = LocalDateTime.now();
+
+ Donation donation = new Donation(500.0, now, charity, user);
+
+ assertNotNull(donation.getCharityId());
+ assertEquals(500.0, donation.getAmount());
+ assertEquals(now, donation.getDate());
+ assertEquals(charity, donation.getCharity());
+ assertEquals(user, donation.getDonor());
+ }
+
+ @Test
+ void testAnonymousFlagWhenUserIsAnonymous() {
+ Donation donation = new Donation(100, LocalDateTime.now(), charity, user);
+
+ assertFalse(donation.isAnonymous());
+ }
+
+ @Test
+ void testAnonymousFlagWhenUserIsNotAnonymous() {
+ Donation donation = new Donation(100, LocalDateTime.now(), charity, user);
+
+ assertFalse(donation.isAnonymous());
+ }
+
+ @Test
+ void testCharityIdIsUnique() {
+ Donation d1 = new Donation(50, LocalDateTime.now(), charity, user);
+ Donation d2 = new Donation(75, LocalDateTime.now(), charity, user);
+
+ assertNotEquals(d1.getCharityId(), d2.getCharityId());
+ }
+
+ @Test
+ void testAmountStoredCorrectly() {
+ Donation donation = new Donation(123.45, LocalDateTime.now(), charity, user);
+
+ assertEquals(123.45, donation.getAmount());
+ }
+
+ @Test
+ void testDateStoredCorrectly() {
+ LocalDateTime date = LocalDateTime.of(2024, 5, 10, 12, 30);
+
+ Donation donation = new Donation(200, date, charity, user);
+
+ assertEquals(date, donation.getDate());
+ }
+
+ @Test
+ void testCharityStoredCorrectly() {
+ Donation donation = new Donation(200, LocalDateTime.now(), charity, user);
+
+ assertEquals(charity, donation.getCharity());
+ }
+
+ @Test
+ void testDonorStoredCorrectly() {
+ Donation donation = new Donation(200, LocalDateTime.now(), charity, user);
+
+ assertEquals(user, donation.getDonor());
+ }
+}
diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/FeedbackTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/FeedbackTest.java
new file mode 100644
index 0000000..a9fc57d
--- /dev/null
+++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/FeedbackTest.java
@@ -0,0 +1,87 @@
+package ntnu.systemutvikling.team6.models;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.time.LocalDateTime;
+import ntnu.sytemutvikling.team6.models.Feedback;
+import ntnu.sytemutvikling.team6.models.user.Inbox;
+import ntnu.sytemutvikling.team6.models.user.Role;
+import ntnu.sytemutvikling.team6.models.user.Settings;
+import ntnu.sytemutvikling.team6.models.user.User;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class FeedbackTest {
+
+ private User user;
+ private Settings settings;
+
+ // -- Setup --
+ @BeforeEach
+ public void setup() {
+ settings = new Settings(); // default anonymous = true
+ user =
+ new User("Name", "Valid@gmail.com", "123", Role.NORMAL_USER, new Settings(), new Inbox());
+ }
+
+ // --- Tests ---
+
+ @Test
+ void testFeedbackInitialization() {
+ LocalDateTime before = LocalDateTime.now();
+ Feedback feedback = new Feedback(user, "Nice work!");
+ LocalDateTime after = LocalDateTime.now();
+
+ assertNotNull(feedback.getFeedbackId());
+ assertEquals("Nice work!", feedback.getComment());
+ assertEquals(user, feedback.getUser());
+
+ // Date should be between before and after
+ assertTrue(!feedback.getDate().isBefore(before) && !feedback.getDate().isAfter(after));
+ }
+
+ @Test
+ void testAnonymousFlagWhenUserIsAnonymous() {
+ // user.settings.isAnonymous() == true → feedback.isAnonymous = false
+ Feedback feedback = new Feedback(user, "Anonymous feedback");
+
+ assertFalse(feedback.isAnonymous());
+ }
+
+ @Test
+ void testAnonymousFlagWhenUserIsNotAnonymous() {
+ user.getSettings().toggleAnonymousMode();
+ Feedback feedback = new Feedback(user, "Not anonymous");
+
+ assertTrue(feedback.isAnonymous());
+ }
+
+ @Test
+ void testFeedbackIdIsUnique() {
+ Feedback f1 = new Feedback(user, "First");
+ Feedback f2 = new Feedback(user, "Second");
+
+ assertNotEquals(f1.getFeedbackId(), f2.getFeedbackId());
+ }
+
+ @Test
+ void testCommentStoredCorrectly() {
+ Feedback feedback = new Feedback(user, "This is a test comment");
+
+ assertEquals("This is a test comment", feedback.getComment());
+ }
+
+ @Test
+ void testUserStoredCorrectly() {
+ Feedback feedback = new Feedback(user, "Hello");
+
+ assertEquals(user, feedback.getUser());
+ }
+
+ @Test
+ void testDateIsSet() {
+ Feedback feedback = new Feedback(user, "Testing date");
+
+ assertNotNull(feedback.getDate());
+ }
+}
diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/user/SettingsTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/user/SettingsTest.java
new file mode 100644
index 0000000..18b2814
--- /dev/null
+++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/user/SettingsTest.java
@@ -0,0 +1,70 @@
+package ntnu.systemutvikling.team6.models.user;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import ntnu.sytemutvikling.team6.models.user.Language;
+import ntnu.sytemutvikling.team6.models.user.Settings;
+import org.junit.jupiter.api.Test;
+
+class SettingsTest {
+
+ @Test
+ void testDefaultConstructorSetsStandardValues() {
+ Settings settings = new Settings();
+
+ assertTrue(settings.isLightMode());
+ assertEquals(Language.ENGLISH, settings.getLanguage());
+ assertFalse(settings.isAnonymous());
+ }
+
+ @Test
+ void testCustomConstructorSetsValuesCorrectly() {
+ Settings settings = new Settings(false, Language.ENGLISH, true);
+
+ assertFalse(settings.isLightMode());
+ assertEquals(Language.ENGLISH, settings.getLanguage());
+ assertTrue(settings.isAnonymous());
+ }
+
+ @Test
+ void testConstructorThrowsExceptionWhenLanguageIsNull() {
+ assertThrows(IllegalArgumentException.class, () -> new Settings(true, null, false));
+ }
+
+ @Test
+ void testToggleLightMode() {
+ Settings settings = new Settings(true, Language.ENGLISH, false);
+
+ settings.toggleLightMode();
+ assertFalse(settings.isLightMode());
+
+ settings.toggleLightMode();
+ assertTrue(settings.isLightMode());
+ }
+
+ @Test
+ void testToggleAnonymousMode() {
+ Settings settings = new Settings(true, Language.ENGLISH, false);
+
+ settings.toggleAnonymousMode();
+ assertTrue(settings.isAnonymous());
+
+ settings.toggleAnonymousMode();
+ assertFalse(settings.isAnonymous());
+ }
+
+ @Test
+ void testChangeLanguageSuccessfully() {
+ Settings settings = new Settings();
+
+ settings.changeLanguage(Language.ENGLISH);
+ assertEquals(Language.ENGLISH, settings.getLanguage());
+ }
+
+ @Test
+ void testChangeLanguageThrowsExceptionWhenNull() {
+ Settings settings = new Settings();
+
+ assertThrows(IllegalArgumentException.class, () -> settings.changeLanguage(null));
+ }
+}
diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/user/UserTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/user/UserTest.java
new file mode 100644
index 0000000..fd20091
--- /dev/null
+++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/models/user/UserTest.java
@@ -0,0 +1,153 @@
+package ntnu.systemutvikling.team6.models.user;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.UUID;
+
+import ntnu.sytemutvikling.team6.models.user.Inbox;
+import ntnu.sytemutvikling.team6.models.user.Role;
+import ntnu.sytemutvikling.team6.models.user.Settings;
+import ntnu.sytemutvikling.team6.models.user.User;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class UserTest {
+
+ @Nested
+ class constructorTests {
+ private final UUID validID = UUID.randomUUID();
+ private final String validName = "Name";
+ private final String validEmail = "Email@gmail.com";
+ private final String validPassword = "Password";
+ private final Role validRole = Role.NORMAL_USER;
+ private final Settings validSettings = new Settings();
+ private final Inbox validInbox = new Inbox();
+
+ @Test
+ void shouldThrowIfNameIsNull() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+ null, validEmail, validPassword, validRole, validSettings, validInbox));
+ }
+
+ @Test
+ void shouldThrowIfNameIsBlank() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+ " ", validEmail, validPassword, validRole, validSettings, validInbox));
+ }
+
+ @Nested
+ class emailTests {
+
+ @Test
+ void shouldThrowIfEmailIsNull() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+ validName, null, validPassword, validRole, validSettings, validInbox));
+ }
+
+ @Test
+ void shouldThrowIfEmailIsBlank() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+ validName, " ", validPassword, validRole, validSettings, validInbox));
+ }
+
+ @Test
+ void shouldThrowIfEmailDoesNotContainAt() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+
+ validName,
+ "test.gmail.com",
+ validPassword,
+ validRole,
+ validSettings,
+ validInbox));
+ }
+
+ @Test
+ void shouldThrowIfEmailDoesNotContainPeriod() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+
+ validName,
+ "test@gmailcom",
+ validPassword,
+ validRole,
+ validSettings,
+ validInbox));
+ }
+ }
+
+ @Test
+ void shouldThrowIfPasswordIsNull() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User( validName, validEmail, null, validRole, validSettings, validInbox));
+ }
+
+ @Test
+ void shouldThrowIfRoleIsNull() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+ validName, validEmail, validPassword, null, validSettings, validInbox));
+ }
+
+ @Test
+ void shouldThrowIfPasswordIsBlank() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User( validName, validEmail, " ", validRole, validSettings, validInbox));
+ }
+
+ @Test
+ void shouldThrowIfSettingsIsNull() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User( validName, validEmail, validPassword, validRole, null, validInbox));
+ }
+
+ @Test
+ void shouldThrowIfInboxIsNull() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new User(
+ validName, validEmail, validPassword, validRole, validSettings, null));
+ }
+
+ @Test
+ void shouldCreateUser() {
+ User user =
+ new User(
+ validName, validEmail, validPassword, validRole, validSettings, validInbox);
+
+ assertAll(
+ () -> assertEquals(validName, user.getName()),
+ () -> assertEquals(validEmail, user.getEmail()),
+ () -> assertEquals(validRole, user.getRole()),
+ () -> assertEquals(validSettings, user.getSettings()),
+ () -> assertEquals(validInbox, user.getInbox()));
+ }
+ }
+}
diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/security/PasswordHasherTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/security/PasswordHasherTest.java
new file mode 100644
index 0000000..d195989
--- /dev/null
+++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/security/PasswordHasherTest.java
@@ -0,0 +1,71 @@
+package ntnu.systemutvikling.team6.security;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import ntnu.sytemutvikling.team6.security.PasswordHasher;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+class PasswordHasherTest {
+ private final PasswordHasher hasher = new PasswordHasher();
+
+ @Nested
+ class getHashPasswordTest {
+
+ @Test
+ void shouldThrowIfPasswordIsNull() {
+ assertThrows(IllegalArgumentException.class, () -> hasher.getHashPassword(null));
+ }
+
+ @Test
+ void shouldThrowIfPasswordIsBlank() {
+ assertThrows(IllegalArgumentException.class, () -> hasher.getHashPassword(" "));
+ }
+
+ @Test
+ void shouldReturnDifferentHashesForSamePasswordBecauseSaltIsRandom() {
+ String test1 = hasher.getHashPassword("Password");
+ String test2 = hasher.getHashPassword("Password");
+
+ assertNotEquals(test1, test2);
+ }
+ }
+
+ @Nested
+ class isValidPasswordTest {
+
+ @Test
+ void shouldReturnTrueForCorrectPassword() {
+ String test = hasher.getHashPassword("Password");
+ assertTrue(hasher.isValidPassword("Password", test));
+ }
+
+ @Test
+ void shouldReturnFalseForWrongPassword() {
+ String test = hasher.getHashPassword("Password");
+ assertFalse(hasher.isValidPassword("password", test));
+ }
+
+ @Test
+ void shouldReturnFalseIfPasswordIsBlank() {
+ String test = hasher.getHashPassword("Test");
+ assertFalse(hasher.isValidPassword(" ", test));
+ }
+
+ @Test
+ void shouldReturnFalseIfPasswordIsNull() {
+ String test = hasher.getHashPassword("Test");
+ assertFalse(hasher.isValidPassword(null, test));
+ }
+
+ @Test
+ void shouldThrowIfStoredHashIsNull() {
+ assertThrows(RuntimeException.class, () -> hasher.isValidPassword("Password", null));
+ }
+
+ @Test
+ void shouldThrowIfStoredHashIsBlank() {
+ assertThrows(RuntimeException.class, () -> hasher.isValidPassword("Password", " "));
+ }
+ }
+}
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Charity.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Charity.class
deleted file mode 100644
index 7803742..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Charity.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/CharityRegistry.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/CharityRegistry.class
deleted file mode 100644
index 61b8503..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/CharityRegistry.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Donation.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Donation.class
deleted file mode 100644
index 78d4151..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Donation.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/DonationRegistry.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/DonationRegistry.class
deleted file mode 100644
index 1b81460..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/DonationRegistry.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Feedback.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Feedback.class
deleted file mode 100644
index 28853ec..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Feedback.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Inbox.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Inbox.class
deleted file mode 100644
index 72613e7..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Inbox.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Language.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Language.class
deleted file mode 100644
index de22840..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Language.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Message.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Message.class
deleted file mode 100644
index 12c1cec..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Message.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Role.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Role.class
deleted file mode 100644
index f19f0d3..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Role.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Settings.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Settings.class
deleted file mode 100644
index 9420861..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Settings.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/User.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/User.class
deleted file mode 100644
index c0cc6c8..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/User.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/UserRegistry.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/UserRegistry.class
deleted file mode 100644
index 970aced..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/UserRegistry.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/CharityService.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/CharityService.class
deleted file mode 100644
index c52d762..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/CharityService.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/DonationService.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/DonationService.class
deleted file mode 100644
index 86d2996..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/DonationService.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/FeedbackService.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/FeedbackService.class
deleted file mode 100644
index 4b0e587..0000000
Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/service/FeedbackService.class and /dev/null differ
diff --git a/helpmehelpapplication/target/classes/tempClassDiagram.puml b/helpmehelpapplication/target/classes/tempClassDiagram.puml
deleted file mode 100644
index c32ad2a..0000000
--- a/helpmehelpapplication/target/classes/tempClassDiagram.puml
+++ /dev/null
@@ -1,307 +0,0 @@
-@startuml
-
-
-
-' =========================
-
-' DOMAIN LAYER
-
-' =========================
-
-
-
-package "Domain Layer" {
-
-
-
-class User {
-
- - idNext : static int
-
- - id : int
-
- - name : String
-
- - email : String
-
- - passwordHash : String
-
- - role : String
-
- - settings : Settings
-
- - inbox : Inbox
-
-
-
- + getUserId() : int
-
- + setUserId(id : int)
-
- + getUserName() : String
-
- + setUserName(name : String)
-
- + getUserEmail() : String
-
- + setUserEmail(email : String)
-
- + getUserPasswordHash() : String
-
- + setUserPasswordHash(passwordHash : String)
-
- + getUserRole() : String
-
- + setUserRole(role : String)
-
-}
-
-
-
-class Settings {
-
- - lightmode : boolean
-
- - language : String
-
- - anonymous : boolean
-
-
-
- + getSettings() : String
-
-}
-
-
-
-class Inbox {
-
- - messages : ArrayList
-
-
-
- + getMessages() : ArrayList
-
- + addMessage(message : Message)
-
- + removeMessage(message : Message)
-
-}
-
-
-
-class Message {
-
- - title : String
-
- - from : Charity
-
- - date : LocalDateTime
-
-
-
- + getTitle() : String
-
- + getFrom() : Charity
-
- + getDate() : LocalDateTime
-
-}
-
-
-
-class Charity {
-
- - idNext : static int
-
- - id : int
-
- - name : String
-
- - description : String
-
- - totalDonations : double
-
- - verified : boolean
-
- - category : String
-
-
-
- + getCharityId() : int
-
- + setCharityId(id : int)
-
- + getCharityName() : String
-
- + setCharityName(name : String)
-
- + getCharityDescription() : String
-
- + setCharityDescription(description : String)
-
- + getCharityTotalDonations() : double
-
- + setCharityTotalDonations(totalDonations : double)
-
-}
-
-
-
-abstract class Donation {
-
- - idNext : static int
-
- - id : int
-
- - amount : double
-
- - date : LocalDateTime
-
- - charity : Charity
-
- - user : User
-
-
-
- + getDonationId() : int
-
- + setDonationId(id : int)
-
- + getDonationAmount() : double
-
- + setDonationAmount(amount : double)
-
- + getDonationDate() : LocalDateTime
-
- + setDonationDate(date : LocalDateTime)
-
- + getDonorInfo() : String
-
-}
-
-
-
-class AnonymousDonation {
-
- - comment : String
-
-}
-
-
-
-class PublicDonation {
-
- - comment : String
-
-}
-
-
-
-class Feedback {
-
- - id : int
-
- - message : String
-
- - date : LocalDateTime
-
- - charityId : int
-
-
-
- + getId() : int
-
- + setId(id : int)
-
- + getMessage() : String
-
- + setMessage(message : String)
-
- + getDate() : LocalDateTime
-
- + setDate(date : LocalDateTime)
-
-}
-
-
-
-class UserRegistry {
-
- - users : List
-
- + addUser(user : User)
-
- + removeUser(user : User)
-
- + getUserById(id : int) : User
-
- + getAllUsers() : List
-
-}
-
-
-
-class CharityRegistry {
-
- - charities : List
-
- + addCharity(charity : Charity)
-
- + removeCharity(charity : Charity)
-
- + getCharityById(id : int) : Charity
-
- + getAllCharities() : List
-
-}
-
-
-
-class DonationRegistry {
-
- - donations : List
-
- + addDonation(donation : Donation)
-
- + removeDonation(donation : Donation)
-
- + getDonationById(id : int) : Donation
-
- + getAllDonations() : List
-
-}
-
-
-
-' Associations
-
-User "1" -- "0..*" Donation
-
-Charity "1" -- "0..*" Donation
-
-
-
-User "1" -- "0..*" Feedback
-
-Charity "1" -- "0..*" Feedback
-
-
-
-Donation <|-- AnonymousDonation
-
-Donation <|-- PublicDonation
-
-
-
-User "1" *-- "1" Settings
-
-User "1" *-- "1" Inbox
-
-Inbox "1" -- "0..*" Message
-
-Message "1" --> "1" Charity
-
-
-
-}
\ No newline at end of file