Skip to content

Commit

Permalink
Feat: Added DonationDAOTest
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrianBalunan committed Apr 24, 2026
1 parent 9a9cdec commit 7d7a214
Showing 1 changed file with 320 additions and 55 deletions.
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())
)));
}
}
}

0 comments on commit 7d7a214

Please sign in to comment.