Skip to content

Commit

Permalink
Merge branch 'release/v1.0.0' into feat/organisation
Browse files Browse the repository at this point in the history
  • Loading branch information
emilfa authored Mar 3, 2026
2 parents f97f5ee + 1c15398 commit ba59aca
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 1 deletion.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@
<artifactId>spring-security-crypto</artifactId>
<version>7.0.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.3.5</version>
</dependency>
</dependencies>

<build>
Expand Down
117 changes: 116 additions & 1 deletion src/main/java/edu/group5/app/model/user/User.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,120 @@
package edu.group5.app.model.user;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* User class represents a user in the system. It is an abstract class that will be extended by specific user types such as Donor, Recipient, and Admin.
* Each user has a unique userId, a role that defines their permissions in the system, and personal information such as first name, last name, email, and password hash.
* The constructor validates that all required fields are provided and throws an IllegalArgumentException if any of the fields are null or empty.
* This ensures that the User objects are always in a valid state when created.
* The class also includes a method to verify the user's password
* by comparing the provided plaintext password with the stored hashed password using BCrypt.
*
*/
public class User {
private int userId;
private String role;
private String firstName;
private String lastName;
private String email;
private String passwordHash;

/**
* Constructor for User class. Validates that all required fields
* are provided and throws an IllegalArgumentException if any of the fields are null or empty.
* @param userId the unique identifier for the user, must be a positive integer
* @param role the role of the user (e.g., "Donor", "Recipient", "Admin")
* @param firstName the first name of the user
* @param lastName the last name of the user
* @param email the email address of the user
* @param passwordHash the hashed password of the user, used for authentication purposes
*/
public User(int userId, String role, String firstName,
String lastName, String email, String passwordHash) {
if (userId <= 0) {
throw new IllegalArgumentException("User ID must be positive");
}
if (role == null || role.trim().isEmpty()) {
throw new IllegalArgumentException("Role cannot be null or empty");
}
if (firstName == null || firstName.trim().isEmpty()) {
throw new IllegalArgumentException("First name cannot be null or empty");
}
if (lastName == null || lastName.trim().isEmpty()) {
throw new IllegalArgumentException("Last name cannot be null or empty");
}
if (email == null || email.trim().isEmpty()) {
throw new IllegalArgumentException("Email cannot be null or empty");
}
if (passwordHash == null || passwordHash.trim().isEmpty()) {
throw new IllegalArgumentException("Password hash cannot be null or empty");
}
this.userId = userId;
this.role = role.trim();
this.firstName = firstName.trim();
this.lastName = lastName.trim();
this.email = email.trim();
this.passwordHash = passwordHash;
}

/**
* Gets the unique identifier for the user.
* @return the userId of the user
*/
public int getUserId() {
return userId;
}

/**
* Gets the role of the user, which defines their permissions in the system.
* @return the role of the user
*/
public String getRole() {
return role;
}

/**
* Gets the first name of the user.
* @return the first name of the user
*/
public String getFirstName() {
return firstName;
}

/**
* Gets the last name of the user.
* @return the last name of the user
*/
public String getLastName() {
return lastName;
}

/**
* Gets the email address of the user.
* @return the email of the user
*/
public String getEmail() {
return email;
}

/**
* Gets the hashed password of the user.
* This is used for authentication purposes and should not be exposed in plaintext.
* @return the password hash of the user
*/
public String getPasswordHash() {
return passwordHash;
}

/**
* Verifies if the provided password matches the stored password hash.
* This method uses BCrypt to compare the plaintext password with the hashed password.
* @param password the plaintext password to verify
* @return true if the password is correct, false otherwise
*/
public boolean verifyPassword(String password) {
if (password == null || password.isEmpty()) {
return false;
}
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder.matches(password, this.passwordHash);
}
}
5 changes: 5 additions & 0 deletions src/test/java/edu/group5/app/control/WrapperTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package edu.group5.app.control;

public class WrapperTest {

}
5 changes: 5 additions & 0 deletions src/test/java/edu/group5/app/model/donation/DonationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package edu.group5.app.model.donation;

public class DonationTest {

}
136 changes: 136 additions & 0 deletions src/test/java/edu/group5/app/model/user/UserTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package edu.group5.app.model.user;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class UserTest {
private static final int TEST_USER_ID = 1;
private static final String TEST_ROLE = "Donor";
private static final String TEST_FIRST_NAME = "John";
private static final String TEST_LAST_NAME = "Doe";
private static final String TEST_EMAIL = "john.doe@example.com";
private static final String TEST_PASSWORD = "password123";
private static final String TEST_PASSWORD_HASH = new BCryptPasswordEncoder().encode(TEST_PASSWORD);

private static final int WRONG_USER_ID = -5;
private static final String WRONG_ROLE = "";
private static final String WRONG_FIRST_NAME = "";
private static final String WRONG_LAST_NAME = "";
private static final String WRONG_EMAIL = "";
private static final String WRONG_PASSWORD_HASH = "";

private void constructorTest(int userId, String role, String firstName, String lastName, String email, String passwordHash, boolean negativeTest) {
boolean exceptionThrown = negativeTest;
try {
new User(userId, role, firstName, lastName, email, passwordHash);
} catch (Exception e) {
exceptionThrown = !negativeTest;
} finally {
assertFalse(exceptionThrown);
}
}

@Test
public void constructorThrowsNoException() {
constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, false);
}

@Test
public void constructorWithNegativeUserIdThrowsException() {
constructorTest(WRONG_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithEmptyRoleThrowsException() {
constructorTest(TEST_USER_ID, WRONG_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithEmptyFirstNameThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, WRONG_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithEmptyLastNameThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, WRONG_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithEmptyEmailThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, WRONG_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithEmptyPasswordHashThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, WRONG_PASSWORD_HASH, true);
}

private void getMethodComparer(User user, boolean negativeTest) {
if (user.getUserId() == TEST_USER_ID &&
user.getRole().equals(TEST_ROLE) &&
user.getFirstName().equals(TEST_FIRST_NAME) &&
user.getLastName().equals(TEST_LAST_NAME) &&
user.getEmail().equals(TEST_EMAIL) &&
user.getPasswordHash() != null) {
assertFalse(negativeTest);
}
}

@Test
public void getMethodsReturnCorrectInformation() {
User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH);
getMethodComparer(testUser, false);
}

@Test
public void verifyPasswordReturnsTrueForCorrectPassword() {
User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH);
assertTrue(testUser.verifyPassword(TEST_PASSWORD));
}

@Test
public void verifyPasswordReturnsFalseForIncorrectPassword() {
User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH);
assertFalse(testUser.verifyPassword("wrongPassword"));
}

@Test
public void verifyPasswordReturnsFalseForNullPassword() {
User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH);
assertFalse(testUser.verifyPassword(null));
}

@Test
public void verifyPasswordReturnsFalseForEmptyPassword() {
User testUser = new User(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH);
assertFalse(testUser.verifyPassword(""));
}

@Test
public void constructorWithNullRoleThrowsException() {
constructorTest(TEST_USER_ID, null, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithNullFirstNameThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, null, TEST_LAST_NAME, TEST_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithNullLastNameThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, null, TEST_EMAIL, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithNullEmailThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, null, TEST_PASSWORD_HASH, true);
}

@Test
public void constructorWithNullPasswordHashThrowsException() {
constructorTest(TEST_USER_ID, TEST_ROLE, TEST_FIRST_NAME, TEST_LAST_NAME, TEST_EMAIL, null, true);
}
}
5 changes: 5 additions & 0 deletions src/test/java/edu/group5/app/utils/UtilitiesTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package edu.group5.app.utils;

public class UtilitiesTest {

}
5 changes: 5 additions & 0 deletions src/test/java/edu/group5/app/view/ViewTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package edu.group5.app.view;

public class ViewTest {

}

0 comments on commit ba59aca

Please sign in to comment.