-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
AdrianBalunan
committed
Apr 24, 2026
1 parent
9a9cdec
commit 7d7a214
Showing
1 changed file
with
320 additions
and
55 deletions.
There are no files selected for viewing
375 changes: 320 additions & 55 deletions
375
...elpapplication/src/test/java/ntnu/systemutvikling/team6/database/DAO/DonationDAOTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,78 +1,343 @@ | ||
| package ntnu.systemutvikling.team6.database.DAO; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.*; | ||
|
|
||
| import java.sql.Connection; | ||
| import java.sql.PreparedStatement; | ||
| import java.sql.ResultSet; | ||
| import java.time.LocalDate; | ||
| import java.util.UUID; | ||
| import ntnu.systemutvikling.team6.database.DatabaseConnection; | ||
| import ntnu.systemutvikling.team6.database.DatabaseSetup; | ||
| import ntnu.systemutvikling.team6.models.Charity; | ||
| import ntnu.systemutvikling.team6.models.Donation; | ||
| import ntnu.systemutvikling.team6.models.user.Inbox; | ||
| import ntnu.systemutvikling.team6.models.user.Role; | ||
| import ntnu.systemutvikling.team6.models.user.Settings; | ||
| import ntnu.systemutvikling.team6.models.user.User; | ||
| import ntnu.systemutvikling.team6.service.APIToDatabaseService; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
| import ntnu.systemutvikling.team6.models.registry.DonationRegistry; | ||
| import ntnu.systemutvikling.team6.models.user.*; | ||
| import org.junit.jupiter.api.*; | ||
| import java.sql.*; | ||
| import java.time.LocalDate; | ||
| import java.util.UUID; | ||
| import static org.junit.jupiter.api.Assertions.*; | ||
| import static org.mockito.Mockito.*; | ||
|
|
||
| class DonationDAOTest { | ||
| public class DonationDAOTest { | ||
|
|
||
| private Charity charity; | ||
| // --- Mocks --- | ||
| private DatabaseConnection mockDbConnection; | ||
| private Connection mockConn; | ||
| private PreparedStatement mockStmt; | ||
| private Statement mockRawStmt; // getDonationFromDB() uses createStatement(), not prepareStatement() | ||
| private ResultSet mockRs; | ||
|
|
||
| private DonationDAO donationDAO; | ||
|
|
||
| @BeforeEach | ||
| void setUp() { | ||
| DatabaseConnection conn = new DatabaseConnection(); | ||
| DatabaseSetup manager = new DatabaseSetup(conn); | ||
| manager.createTables(); | ||
|
|
||
| charity = | ||
| new Charity( | ||
| "123456", | ||
| "https://www.innsamlingskontrollen.no/organisasjoner/adra-norge-adventist-development-and-relief-agency-norway/", | ||
| "Test Charity", | ||
| true, | ||
| "approved"); | ||
| void setUp() throws SQLException { | ||
| mockDbConnection = mock(DatabaseConnection.class); | ||
| mockConn = mock(Connection.class); | ||
| mockStmt = mock(PreparedStatement.class); | ||
| mockRawStmt = mock(Statement.class); | ||
| mockRs = mock(ResultSet.class); | ||
|
|
||
| when(mockDbConnection.getMySqlConnection()).thenReturn(mockConn); | ||
| when(mockConn.prepareStatement(anyString())).thenReturn(mockStmt); | ||
| when(mockConn.createStatement()).thenReturn(mockRawStmt); | ||
|
|
||
| APIToDatabaseService service = new APIToDatabaseService(conn); | ||
| service.addAPIDataToTable(java.util.List.of(charity)); | ||
| donationDAO = new DonationDAO(mockDbConnection); | ||
| } | ||
|
|
||
| @Test | ||
| void addDonationShouldInsertDonationIntoDatabase() throws Exception { | ||
| double amount = 100.0; | ||
| // ---------------------------------------------------------------- | ||
| // Helpers | ||
| // ---------------------------------------------------------------- | ||
|
|
||
| DonationDAO donationDAO = new DonationDAO(new DatabaseConnection()); | ||
| private User buildTestUser(String userId) { | ||
| User user = new User( | ||
| userId, | ||
| "TestUser", | ||
| "test@example.com", | ||
| "hashedpassword", | ||
| Role.NORMAL_USER.toString() | ||
| ); | ||
| user.setSettings(new Settings(false, Language.ENGLISH, true)); | ||
| user.setInbox(new Inbox()); | ||
| return user; | ||
| } | ||
|
|
||
| private Charity buildTestCharity(String charityId) { | ||
| return new Charity( | ||
| charityId, | ||
| "123456789", | ||
| "HelpOrg", | ||
| "helporg.com", | ||
| "active", | ||
| true, | ||
| "We help people", | ||
| null, | ||
| null, | ||
| null | ||
| ); | ||
| } | ||
|
|
||
| User user = new User( | ||
| UUID.randomUUID().toString(), | ||
| "ad", | ||
| "aduser", | ||
| Role.NORMAL_USER, | ||
| new Settings(), | ||
| new Inbox()); | ||
| donationDAO.addDonation(new Donation( | ||
| amount, | ||
| private Donation buildTestDonation(String donationId, User user, Charity charity) { | ||
| return new Donation( | ||
| donationId, | ||
| 100.0, | ||
| LocalDate.now(), | ||
| charity, | ||
| user | ||
| )); | ||
| user, | ||
| false | ||
| ); | ||
| } | ||
|
|
||
| try (Connection conn = new DatabaseConnection().getMySqlConnection()) { | ||
| PreparedStatement stmt = | ||
| conn.prepareStatement("SELECT amount FROM Donations WHERE charity_id = ?"); | ||
| /** Stubs all ResultSet columns shared by getDonationFromDB, getDonationForUser, getDonationForCharity. */ | ||
| private void stubFullDonationRow(String donationId, String charityId, String userId) throws SQLException { | ||
| when(mockRs.getString("UUID_Donations")).thenReturn(donationId); | ||
| when(mockRs.getDouble("amount")).thenReturn(250.0); | ||
| when(mockRs.getBoolean("isAnonymous")).thenReturn(false); | ||
| when(mockRs.getDate("date")).thenReturn(Date.valueOf(LocalDate.now())); | ||
|
|
||
| stmt.setString(1, charity.getUUID().toString()); | ||
| when(mockRs.getString("UUID_charities")).thenReturn(charityId); | ||
| when(mockRs.getString("org_number")).thenReturn("9999"); | ||
| when(mockRs.getString("charity_name")).thenReturn("HelpOrg"); | ||
| when(mockRs.getString("charity_link")).thenReturn("helporg.com"); | ||
| when(mockRs.getString("status")).thenReturn("active"); | ||
| when(mockRs.getBoolean("pre_approved")).thenReturn(true); | ||
| when(mockRs.getString("description")).thenReturn("We help"); | ||
| when(mockRs.getString("logoURL")).thenReturn(null); | ||
| when(mockRs.getString("key_values")).thenReturn(null); | ||
| when(mockRs.getBytes("logoBLOB")).thenReturn(null); | ||
|
|
||
| ResultSet rs = stmt.executeQuery(); | ||
| when(mockRs.getString("UUID_User")).thenReturn(userId); | ||
| when(mockRs.getString("user_name")).thenReturn("Alice"); | ||
| when(mockRs.getString("user_email")).thenReturn("alice@example.com"); | ||
| when(mockRs.getString("user_password")).thenReturn("hashedpw"); | ||
| when(mockRs.getString("role")).thenReturn(Role.NORMAL_USER.toString()); | ||
| } | ||
|
|
||
| assertTrue(rs.next(), "Donation should exist in database"); | ||
| // ---------------------------------------------------------------- | ||
| // getDonationFromDB() — uses createStatement(), not prepareStatement() | ||
| // ---------------------------------------------------------------- | ||
|
|
||
| assertEquals(amount, rs.getDouble("amount")); | ||
| } | ||
| @Test | ||
| void getDonationFromDB_returnsRegistryWithDonations() throws SQLException { | ||
| when(mockRawStmt.executeQuery(anyString())).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(true, false); | ||
|
|
||
| String donationId = UUID.randomUUID().toString(); | ||
| String charityId = UUID.randomUUID().toString(); | ||
| String userId = UUID.randomUUID().toString(); | ||
| stubFullDonationRow(donationId, charityId, userId); | ||
|
|
||
| DonationRegistry registry = donationDAO.getDonationFromDB(); | ||
|
|
||
| assertNotNull(registry); | ||
| assertEquals(1, registry.getAllDonations().size()); | ||
| assertEquals(donationId, registry.getAllDonations().getFirst().getDonationID().toString()); | ||
| assertEquals(250.0, registry.getAllDonations().getFirst().getAmount()); | ||
| assertEquals(charityId, registry.getAllDonations().getFirst().getCharity().getUUID().toString()); | ||
| assertEquals(userId, registry.getAllDonations().getFirst().getDonor().getId().toString()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationFromDB_returnsEmptyRegistryWhenNoDonations() throws SQLException { | ||
| when(mockRawStmt.executeQuery(anyString())).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(false); | ||
|
|
||
| DonationRegistry registry = donationDAO.getDonationFromDB(); | ||
|
|
||
| assertNotNull(registry); | ||
| assertTrue(registry.getAllDonations().isEmpty()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationFromDB_returnsMultipleDonations() throws SQLException { | ||
| when(mockRawStmt.executeQuery(anyString())).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(true, true, false); | ||
|
|
||
| when(mockRs.getString("UUID_Donations")).thenReturn( | ||
| UUID.randomUUID().toString(), UUID.randomUUID().toString()); | ||
| when(mockRs.getDouble("amount")).thenReturn(100.0, 200.0); | ||
| when(mockRs.getBoolean("isAnonymous")).thenReturn(false); | ||
| when(mockRs.getDate("date")).thenReturn(Date.valueOf(LocalDate.now())); | ||
| when(mockRs.getString("UUID_charities")).thenReturn(UUID.randomUUID().toString()); | ||
| when(mockRs.getString("org_number")).thenReturn("1111"); | ||
| when(mockRs.getBoolean("pre_approved")).thenReturn(true); | ||
| when(mockRs.getString("status")).thenReturn("active"); | ||
| when(mockRs.getString("UUID_User")).thenReturn(UUID.randomUUID().toString()); | ||
| when(mockRs.getString("user_name")).thenReturn("Bob"); | ||
| when(mockRs.getString("user_email")).thenReturn("bob@example.com"); | ||
| when(mockRs.getString("user_password")).thenReturn("pw"); | ||
| when(mockRs.getString("role")).thenReturn(Role.NORMAL_USER.toString()); | ||
|
|
||
| DonationRegistry registry = donationDAO.getDonationFromDB(); | ||
|
|
||
| assertEquals(2, registry.getAllDonations().size()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationFromDB_throwsRuntimeExceptionOnSQLException() throws SQLException { | ||
| when(mockConn.createStatement()).thenThrow(new SQLException("DB down")); | ||
|
|
||
| assertThrows(RuntimeException.class, () -> donationDAO.getDonationFromDB()); | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------- | ||
| // getDonationForUser() | ||
| // ---------------------------------------------------------------- | ||
|
|
||
| @Test | ||
| void getDonationForUser_returnsRegistryWithDonations() throws SQLException { | ||
| when(mockStmt.executeQuery()).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(true, false); | ||
|
|
||
| String donationId = UUID.randomUUID().toString(); | ||
| String charityId = UUID.randomUUID().toString(); | ||
| String userId = UUID.randomUUID().toString(); | ||
| stubFullDonationRow(donationId, charityId, userId); | ||
|
|
||
| DonationRegistry registry = donationDAO.getDonationForUser(userId); | ||
|
|
||
| assertNotNull(registry); | ||
| assertEquals(1, registry.getAllDonations().size()); | ||
| assertEquals(donationId, registry.getAllDonations().getFirst().getDonationID().toString()); | ||
| assertEquals(userId, registry.getAllDonations().getFirst().getDonor().getId().toString()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationForUser_returnsEmptyRegistryWhenNoDonations() throws SQLException { | ||
| when(mockStmt.executeQuery()).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(false); | ||
|
|
||
| DonationRegistry registry = donationDAO.getDonationForUser(UUID.randomUUID().toString()); | ||
|
|
||
| assertNotNull(registry); | ||
| assertTrue(registry.getAllDonations().isEmpty()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationForUser_passesCorrectUserIdToQuery() throws SQLException { | ||
| when(mockStmt.executeQuery()).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(false); | ||
|
|
||
| String userId = UUID.randomUUID().toString(); | ||
| donationDAO.getDonationForUser(userId); | ||
|
|
||
| verify(mockStmt).setString(1, userId); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationForUser_throwsRuntimeExceptionOnSQLException() throws SQLException { | ||
| when(mockConn.prepareStatement(anyString())).thenThrow(new SQLException("Query failed")); | ||
|
|
||
| assertThrows(RuntimeException.class, | ||
| () -> donationDAO.getDonationForUser(UUID.randomUUID().toString())); | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------- | ||
| // getDonationForCharity() | ||
| // ---------------------------------------------------------------- | ||
|
|
||
| @Test | ||
| void getDonationForCharity_returnsRegistryWithDonations() throws SQLException { | ||
| when(mockStmt.executeQuery()).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(true, false); | ||
|
|
||
| String donationId = UUID.randomUUID().toString(); | ||
| String charityId = UUID.randomUUID().toString(); | ||
| String userId = UUID.randomUUID().toString(); | ||
| stubFullDonationRow(donationId, charityId, userId); | ||
|
|
||
| DonationRegistry registry = donationDAO.getDonationForCharity(charityId); | ||
|
|
||
| assertNotNull(registry); | ||
| assertEquals(1, registry.getAllDonations().size()); | ||
| assertEquals(donationId, registry.getAllDonations().getFirst().getDonationID().toString()); | ||
| assertEquals(charityId, registry.getAllDonations().getFirst().getCharity().getUUID().toString()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationForCharity_returnsEmptyRegistryWhenNoDonations() throws SQLException { | ||
| when(mockStmt.executeQuery()).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(false); | ||
|
|
||
| DonationRegistry registry = donationDAO.getDonationForCharity(UUID.randomUUID().toString()); | ||
|
|
||
| assertNotNull(registry); | ||
| assertTrue(registry.getAllDonations().isEmpty()); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationForCharity_passesCorrectCharityIdToQuery() throws SQLException { | ||
| when(mockStmt.executeQuery()).thenReturn(mockRs); | ||
| when(mockRs.next()).thenReturn(false); | ||
|
|
||
| String charityId = UUID.randomUUID().toString(); | ||
| donationDAO.getDonationForCharity(charityId); | ||
|
|
||
| verify(mockStmt).setString(1, charityId); | ||
| } | ||
|
|
||
| @Test | ||
| void getDonationForCharity_throwsRuntimeExceptionOnSQLException() throws SQLException { | ||
| when(mockConn.prepareStatement(anyString())).thenThrow(new SQLException("Query failed")); | ||
|
|
||
| assertThrows(RuntimeException.class, | ||
| () -> donationDAO.getDonationForCharity(UUID.randomUUID().toString())); | ||
| } | ||
|
|
||
| // ---------------------------------------------------------------- | ||
| // addDonation() | ||
| // ---------------------------------------------------------------- | ||
|
|
||
| @Test | ||
| void addDonation_executesSuccessfully() throws SQLException { | ||
| String donationId = UUID.randomUUID().toString(); | ||
| String charityId = UUID.randomUUID().toString(); | ||
| String userId = UUID.randomUUID().toString(); | ||
| User user = buildTestUser(userId); | ||
| Donation donation = buildTestDonation(donationId, user, buildTestCharity(charityId)); | ||
|
|
||
| donationDAO.addDonation(donation); | ||
|
|
||
| verify(mockStmt).executeUpdate(); | ||
| verify(mockConn).setAutoCommit(false); | ||
| verify(mockConn).commit(); | ||
| } | ||
|
|
||
| @Test | ||
| void addDonation_setsCorrectParameterOrder() throws SQLException { | ||
| String donationId = UUID.randomUUID().toString(); | ||
| String charityId = UUID.randomUUID().toString(); | ||
| String userId = UUID.randomUUID().toString(); | ||
| User user = buildTestUser(userId); | ||
| Donation donation = buildTestDonation(donationId, user, buildTestCharity(charityId)); | ||
|
|
||
| donationDAO.addDonation(donation); | ||
|
|
||
| verify(mockStmt).setString(1, donationId); // UUID_Donations | ||
| verify(mockStmt).setDouble(2, donation.getAmount()); // amount | ||
| verify(mockStmt).setBoolean(3, user.getSettings().isAnonymous()); // isAnonymous | ||
| verify(mockStmt).setDate(4, Date.valueOf(donation.getDate())); // date | ||
| verify(mockStmt).setString(5, charityId); // charity_id | ||
| verify(mockStmt).setString(6, userId); // user_id | ||
| } | ||
|
|
||
| @Test | ||
| void addDonation_setsAnonymousTrueWhenUserIsAnonymous() throws SQLException { | ||
| String userId = UUID.randomUUID().toString(); | ||
| User anonymousUser = buildTestUser(userId); | ||
| anonymousUser.setSettings(new Settings(true, Language.ENGLISH, false)); | ||
|
|
||
| donationDAO.addDonation(buildTestDonation( | ||
| UUID.randomUUID().toString(), | ||
| anonymousUser, | ||
| buildTestCharity(UUID.randomUUID().toString()) | ||
| )); | ||
|
|
||
| verify(mockStmt).setBoolean(3, true); | ||
| } | ||
|
|
||
| @Test | ||
| void addDonation_throwsRuntimeExceptionOnSQLException() throws SQLException { | ||
| when(mockConn.prepareStatement(anyString())).thenThrow(new SQLException("Insert failed")); | ||
|
|
||
| assertThrows(RuntimeException.class, | ||
| () -> donationDAO.addDonation(buildTestDonation( | ||
| UUID.randomUUID().toString(), | ||
| buildTestUser(UUID.randomUUID().toString()), | ||
| buildTestCharity(UUID.randomUUID().toString()) | ||
| ))); | ||
| } | ||
| } | ||
| } |