Skip to content

Commit

Permalink
Perf: Update model classes and write Customer class
Browse files Browse the repository at this point in the history
  • Loading branch information
Fredrik Marjoni committed Mar 2, 2026
1 parent e4b38a5 commit 0db6023
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 35 deletions.
41 changes: 41 additions & 0 deletions src/main/java/edu/group5/app/model/donation/DonationService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package edu.group5.app.service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import edu.group5.app.model.donation.Donation;
import edu.group5.app.model.organization.Organization;
import edu.group5.app.model.organization.OrganizationRepository;
import edu.group5.app.model.user.Customer;
import edu.group5.app.model.donation.DonationRepository;

public class DonationService {

private final DonationRepository donationRepository;
private final OrganizationRepository organizationRepository;

public DonationService(DonationRepository donationRepository,
OrganizationRepository organizationRepository) {
this.donationRepository = donationRepository;
this.organizationRepository = organizationRepository;
}

public boolean donate(Customer customer,
int orgNumber,
BigDecimal amount) {
if (customer == null || amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
return false;
}
Organization org = organizationRepository.findByOrgNumber(orgNumber);
if (org == null) {
return false;
}
Donation donation = new Donation(
customer.getUserId(),
org.getOrgNumber(),
amount,
new Timestamp(System.currentTimeMillis())
);
donationRepository.addDonation(donation);
return true;
}
}
49 changes: 49 additions & 0 deletions src/main/java/edu/group5/app/model/user/Customer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package edu.group5.app.model.user;

import java.util.HashMap;
import java.util.Map;

import edu.group5.app.model.organization.Organization;

/**
* Customer class represents a customer in the system.
* It extends the User class and includes additional functionality specific to customers,
* such as managing their preferences for organizations.
* Each customer has a map of preferences that associates organization numbers with the corresponding Organization objects.
*/
public class Customer extends User {
private List<Integer> preferences;

/**
* Constructs a Customer object.
* Calls the {@link User} superclass constructor to initialize common user fields
* and initializes the preferences list.
* @param userId the unique identifier for the user, must be a positive integer
* @param firstName the first name of the customer
* @param lastName the last name of the customer
* @param email the email address of the customer
* @param passwordHash the hashed password of the customer
* @throws IllegalArgumentException if any required field is invalid
*/
public Customer(int userId,
String firstName,
String lastName,
String email,
String passwordHash) {

super(userId, "Customer", firstName, lastName, email, passwordHash);
this.preferences = new ArrayList<>();
}

public List<Integer> getPreferences() {
return preferences;
}

public void addPreference(int orgNumber) {
preferences.add(orgNumber);
}

public void removePreference(int orgNumber) {
preferences.remove(Integer.valueOf(orgNumber));
}
}
2 changes: 1 addition & 1 deletion src/main/java/edu/group5/app/model/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* by comparing the provided plaintext password with the stored hashed password using BCrypt.
*
*/
public class User {
public abstract class User {
private int userId;
private String role;
private String firstName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
package edu.group5.app.model.user;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
Expand All @@ -9,10 +8,9 @@
import org.junit.jupiter.api.Test;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class UserTest {
public class CustomerTest {

private int testUserId;
private String testRole;
private String testFirstName;
private String testLastName;
private String testEmail;
Expand All @@ -22,133 +20,126 @@ public class UserTest {
@BeforeEach
void setUp() {
testUserId = 1;
testRole = "Donor";
testFirstName = "John";
testLastName = "Doe";
testEmail = "john.doe@example.com";
testPassword = "password123";
testPasswordHash = new BCryptPasswordEncoder().encode(testPassword);
}

private void constructorTest(int userId, String role, String firstName,
private void constructorTest(int userId, String firstName,
String lastName, String email, String passwordHash,
String expectedMessage) {
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> new User(userId, role, firstName, lastName, email, passwordHash)
() -> new Customer(userId, firstName, lastName, email, passwordHash)
);

assertEquals(expectedMessage, exception.getMessage());
}

@Test
void constructorCreatesValidUser() {
User user = new User(testUserId, testRole, testFirstName,
User user = new Customer(testUserId, testFirstName,
testLastName, testEmail, testPasswordHash);
assertEquals(testUserId, user.getUserId());
assertEquals(testRole, user.getRole());
assertEquals(testFirstName, user.getFirstName());
assertEquals(testLastName, user.getLastName());
assertEquals(testEmail, user.getEmail());
assertEquals(testPasswordHash, user.getPasswordHash());
}

@Test
void constructorWithNegativeUserIdThrowsException() {
constructorTest(-1, testRole, testFirstName, testLastName,
testEmail, testPasswordHash, "User ID must be positive");
}

@Test
void constructorWithNullRoleThrowsException() {
constructorTest(testUserId, null, testFirstName, testLastName,
testEmail, testPasswordHash, "Role cannot be null or empty");
void testInstanceOfCustomer() {
User user = new Customer(testUserId, testFirstName,
testLastName, testEmail, testPasswordHash);
assertTrue(user instanceof Customer);
}

@Test
void constructorWithEmptyRoleThrowsException() {
constructorTest(testUserId, "", testFirstName, testLastName,
testEmail, testPasswordHash, "Role cannot be null or empty");
void constructorWithNegativeUserIdThrowsException() {
constructorTest(-1, testFirstName, testLastName,
testEmail, testPasswordHash, "User ID must be positive");
}

@Test
void constructorWithNullFirstNameThrowsException() {
constructorTest(testUserId, testRole, null, testLastName,
constructorTest(testUserId, null, testLastName,
testEmail, testPasswordHash, "First name cannot be null or empty");
}

@Test
void constructorWithEmptyFirstNameThrowsException() {
constructorTest(testUserId, testRole, "", testLastName,
constructorTest(testUserId, "", testLastName,
testEmail, testPasswordHash, "First name cannot be null or empty");
}

@Test
void constructorWithNullLastNameThrowsException() {
constructorTest(testUserId, testRole, testFirstName, null,
constructorTest(testUserId, testFirstName, null,
testEmail, testPasswordHash, "Last name cannot be null or empty");
}

@Test
void constructorWithEmptyLastNameThrowsException() {
constructorTest(testUserId, testRole, testFirstName, "",
testEmail, testPasswordHash, "Last name cannot be null or empty");
constructorTest(testUserId, testFirstName,
"", testEmail, testPasswordHash, "Last name cannot be null or empty");
}

@Test
void constructorWithNullEmailThrowsException() {
constructorTest(testUserId, testRole, testFirstName, testLastName,
constructorTest(testUserId, testFirstName, testLastName,
null, testPasswordHash, "Email cannot be null or empty");
}

@Test
void constructorWithEmptyEmailThrowsException() {
constructorTest(testUserId, testRole, testFirstName, testLastName,
constructorTest(testUserId, testFirstName, testLastName,
"", testPasswordHash, "Email cannot be null or empty");
}

@Test
void constructorWithNullPasswordHashThrowsException() {
constructorTest(testUserId, testRole, testFirstName, testLastName,
constructorTest(testUserId, testFirstName, testLastName,
testEmail, null, "Password hash cannot be null or empty");
}

@Test
void constructorWithEmptyPasswordHashThrowsException() {
constructorTest(testUserId, testRole, testFirstName, testLastName,
constructorTest(testUserId, testFirstName, testLastName,
testEmail, "", "Password hash cannot be null or empty");
}


@Test
void verifyPasswordReturnsTrueForCorrectPassword() {
User user = new User(testUserId, testRole, testFirstName,
User user = new Customer(testUserId, testFirstName,
testLastName, testEmail, testPasswordHash);

assertTrue(user.verifyPassword(testPassword));
}

@Test
void verifyPasswordReturnsFalseForIncorrectPassword() {
User user = new User(testUserId, testRole, testFirstName,
User user = new Customer(testUserId, testFirstName,
testLastName, testEmail, testPasswordHash);

assertFalse(user.verifyPassword("wrongPassword"));
}

@Test
void verifyPasswordReturnsFalseForNullPassword() {
User user = new User(testUserId, testRole, testFirstName,
User user = new Customer(testUserId, testFirstName,
testLastName, testEmail, testPasswordHash);

assertFalse(user.verifyPassword(null));
}

@Test
void verifyPasswordReturnsFalseForEmptyPassword() {
User user = new User(testUserId, testRole, testFirstName,
User user = new Customer(testUserId, testFirstName,
testLastName, testEmail, testPasswordHash);

assertFalse(user.verifyPassword(""));
}
}
}

0 comments on commit 0db6023

Please sign in to comment.