diff --git a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DAO/FavouritesDAOTest.java b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DAO/FavouritesDAOTest.java index 80b9d09..0782566 100644 --- a/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DAO/FavouritesDAOTest.java +++ b/helpmehelpapplication/src/test/java/ntnu/systemutvikling/team6/database/DAO/FavouritesDAOTest.java @@ -1,4 +1,323 @@ package ntnu.systemutvikling.team6.database.DAO; +import ntnu.systemutvikling.team6.database.DatabaseConnection; +import ntnu.systemutvikling.team6.models.Charity; +import ntnu.systemutvikling.team6.models.user.*; +import org.junit.jupiter.api.*; +import java.sql.*; +import java.util.List; +import java.util.UUID; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + public class FavouritesDAOTest { -} + + // --- Mocks --- + private DatabaseConnection mockDbConnection; + private Connection mockConn; + private PreparedStatement mockStmt; + private ResultSet mockRs; + + private FavouritesDAO favouritesDAO; + + @BeforeEach + void setUp() throws SQLException { + mockDbConnection = mock(DatabaseConnection.class); + mockConn = mock(Connection.class); + mockStmt = mock(PreparedStatement.class); + mockRs = mock(ResultSet.class); + + when(mockDbConnection.getMySqlConnection()).thenReturn(mockConn); + when(mockConn.prepareStatement(anyString())).thenReturn(mockStmt); + + favouritesDAO = new FavouritesDAO(mockDbConnection); + } + + // ---------------------------------------------------------------- + // Helpers + // ---------------------------------------------------------------- + + 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 + ); + } + + // ---------------------------------------------------------------- + // isFavourite() + // ---------------------------------------------------------------- + + @Test + void isFavourite_returnsTrueWhenRowExists() throws SQLException { + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(true); + + String userId = UUID.randomUUID().toString(); + String charityId = UUID.randomUUID().toString(); + + assertTrue(favouritesDAO.isFavourite(buildTestUser(userId), buildTestCharity(charityId))); + } + + @Test + void isFavourite_returnsFalseWhenNoRowExists() throws SQLException { + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(false); + + assertFalse(favouritesDAO.isFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void isFavourite_returnsFalseOnSQLException() throws SQLException { + when(mockStmt.executeQuery()).thenThrow(new SQLException("Query failed")); + + assertFalse(favouritesDAO.isFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void isFavourite_setsCorrectParameters() throws SQLException { + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(false); + + String userId = UUID.randomUUID().toString(); + String charityId = UUID.randomUUID().toString(); + + favouritesDAO.isFavourite(buildTestUser(userId), buildTestCharity(charityId)); + + verify(mockStmt).setString(1, userId); // Favourer + verify(mockStmt).setString(2, charityId); // Favourite_Charity + } + + // ---------------------------------------------------------------- + // addFavourite() + // ---------------------------------------------------------------- + + @Test + void addFavourite_returnsTrueOnSuccess() throws SQLException { + when(mockStmt.executeUpdate()).thenReturn(1); + + assertTrue(favouritesDAO.addFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void addFavourite_returnsFalseWhenNoRowsAffected() throws SQLException { + when(mockStmt.executeUpdate()).thenReturn(0); + + assertFalse(favouritesDAO.addFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void addFavourite_returnsFalseOnSQLException() throws SQLException { + when(mockStmt.executeUpdate()).thenThrow(new SQLException("Insert failed")); + + assertFalse(favouritesDAO.addFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void addFavourite_setsCorrectParameters() throws SQLException { + when(mockStmt.executeUpdate()).thenReturn(1); + + String userId = UUID.randomUUID().toString(); + String charityId = UUID.randomUUID().toString(); + + favouritesDAO.addFavourite(buildTestUser(userId), buildTestCharity(charityId)); + + verify(mockStmt).setString(1, userId); // Favourer + verify(mockStmt).setString(2, charityId); // Favourite_charity + } + + // ---------------------------------------------------------------- + // removeFavourite() + // ---------------------------------------------------------------- + + @Test + void removeFavourite_returnsTrueOnSuccess() throws SQLException { + when(mockStmt.executeUpdate()).thenReturn(1); + + assertTrue(favouritesDAO.removeFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void removeFavourite_returnsFalseWhenNoRowsAffected() throws SQLException { + when(mockStmt.executeUpdate()).thenReturn(0); + + assertFalse(favouritesDAO.removeFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void removeFavourite_returnsFalseOnSQLException() throws SQLException { + when(mockStmt.executeUpdate()).thenThrow(new SQLException("Delete failed")); + + assertFalse(favouritesDAO.removeFavourite( + buildTestUser(UUID.randomUUID().toString()), + buildTestCharity(UUID.randomUUID().toString()) + )); + } + + @Test + void removeFavourite_setsCorrectParameters() throws SQLException { + when(mockStmt.executeUpdate()).thenReturn(1); + + String userId = UUID.randomUUID().toString(); + String charityId = UUID.randomUUID().toString(); + + favouritesDAO.removeFavourite(buildTestUser(userId), buildTestCharity(charityId)); + + verify(mockStmt).setString(1, userId); // Favourer + verify(mockStmt).setString(2, charityId); // Favourite_charity + } + + // ---------------------------------------------------------------- + // getFavouritesForUser() + // ---------------------------------------------------------------- + + @Test + void getFavouritesForUser_returnsCharityList() throws SQLException { + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(true, false); + + String charityId = UUID.randomUUID().toString(); + when(mockRs.getString("UUID_charities")).thenReturn(charityId); + when(mockRs.getString("org_number")).thenReturn("9999"); + when(mockRs.getString("charity_name")).thenReturn("SaveAll"); + when(mockRs.getString("charity_link")).thenReturn("saveall.org"); + when(mockRs.getString("status")).thenReturn("active"); + when(mockRs.getBoolean("pre_approved")).thenReturn(true); + when(mockRs.getString("description")).thenReturn("Saving people"); + when(mockRs.getString("logoURL")).thenReturn(null); + when(mockRs.getString("key_values")).thenReturn(null); + when(mockRs.getBytes("logoBLOB")).thenReturn(null); + when(mockRs.getString("category")).thenReturn(null); // no category + + List result = favouritesDAO.getFavouritesForUser(UUID.randomUUID().toString()); + + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals(charityId, result.getFirst().getUUID().toString()); + assertEquals("SaveAll", result.getFirst().getName()); + } + + @Test + void getFavouritesForUser_returnsEmptyListWhenNoFavourites() throws SQLException { + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(false); + + List result = favouritesDAO.getFavouritesForUser(UUID.randomUUID().toString()); + + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + void getFavouritesForUser_doesNotDuplicateCharityAcrossMultipleCategoryRows() throws SQLException { + // Same charity appearing in two rows (one per category) should produce only one Charity object + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(true, true, false); + + String charityId = UUID.randomUUID().toString(); + when(mockRs.getString("UUID_charities")).thenReturn(charityId); + when(mockRs.getString("org_number")).thenReturn("1111"); + when(mockRs.getString("charity_name")).thenReturn("EduOrg"); + when(mockRs.getString("charity_link")).thenReturn("eduorg.com"); + when(mockRs.getString("status")).thenReturn("active"); + when(mockRs.getBoolean("pre_approved")).thenReturn(false); + when(mockRs.getString("description")).thenReturn("Education"); + when(mockRs.getString("logoURL")).thenReturn(null); + when(mockRs.getString("key_values")).thenReturn(null); + when(mockRs.getBytes("logoBLOB")).thenReturn(null); + when(mockRs.getString("category")).thenReturn("Education", "Youth"); + + List result = favouritesDAO.getFavouritesForUser(UUID.randomUUID().toString()); + + assertEquals(1, result.size()); + assertEquals(2, result.getFirst().getCategory().size()); + assertTrue(result.getFirst().getCategory().contains("Education")); + assertTrue(result.getFirst().getCategory().contains("Youth")); + } + + @Test + void getFavouritesForUser_returnsMultipleDistinctCharities() throws SQLException { + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(true, true, false); + + String charityId1 = UUID.randomUUID().toString(); + String charityId2 = UUID.randomUUID().toString(); + + when(mockRs.getString("UUID_charities")).thenReturn(charityId1, charityId2); + when(mockRs.getString("org_number")).thenReturn("1111", "2222"); + when(mockRs.getString("charity_name")).thenReturn("OrgA", "OrgB"); + when(mockRs.getString("charity_link")).thenReturn("orga.com", "orgb.com"); + when(mockRs.getString("status")).thenReturn("active"); + when(mockRs.getBoolean("pre_approved")).thenReturn(true); + when(mockRs.getString("description")).thenReturn("Desc"); + when(mockRs.getString("logoURL")).thenReturn(null); + when(mockRs.getString("key_values")).thenReturn(null); + when(mockRs.getBytes("logoBLOB")).thenReturn(null); + when(mockRs.getString("category")).thenReturn(null); + + List result = favouritesDAO.getFavouritesForUser(UUID.randomUUID().toString()); + + assertEquals(2, result.size()); + } + + @Test + void getFavouritesForUser_throwsRuntimeExceptionOnSQLException() throws SQLException { + when(mockStmt.executeQuery()).thenThrow(new SQLException("Query failed")); + + assertThrows(RuntimeException.class, + () -> favouritesDAO.getFavouritesForUser(UUID.randomUUID().toString())); + } + + @Test + void getFavouritesForUser_passesCorrectUserIdToQuery() throws SQLException { + when(mockStmt.executeQuery()).thenReturn(mockRs); + when(mockRs.next()).thenReturn(false); + + String userId = UUID.randomUUID().toString(); + favouritesDAO.getFavouritesForUser(userId); + + verify(mockStmt).setString(1, userId); + } +} \ No newline at end of file