/** * */ package net.frontlinesms.data.repository.hibernate; import java.util.HashSet; import java.util.List; import java.util.Set; import net.frontlinesms.data.DuplicateKeyException; import net.frontlinesms.data.domain.Contact; import net.frontlinesms.data.domain.Group; import net.frontlinesms.data.repository.ContactDao; import net.frontlinesms.data.repository.GroupDao; import net.frontlinesms.data.repository.GroupMembershipDao; import net.frontlinesms.junit.HibernateTestCase; import org.springframework.beans.factory.annotation.Required; /** * Test class for {@link HibernateContactDao} * @author Alex */ public class HibernateContactDaoTest extends HibernateTestCase { //> PROPERTIES private ContactDao contactDao; private GroupDao groupDao; private GroupMembershipDao groupMembershipDao; //> TEST METHODS /** Tests deletion of a contact who is member of a group */ public void testDeleteWithGroups() throws DuplicateKeyException { Contact c = new Contact("Jeremy Test", "+123456789", null, null, null, true); contactDao.saveContact(c); Group rootGroup = new Group(null, null); Group g = new Group(rootGroup, "agroup"); groupDao.saveGroup(g); groupMembershipDao.addMember(g, c); contactDao.deleteContact(c); } /** Test saving of contacts with duplicate phone numbers. */ public void testDuplicates() throws DuplicateKeyException { Contact one = new Contact("Jeremy 1", "+123456789", null, null, null, true); contactDao.saveContact(one); Contact two = new Contact("Jeremy 2", "+123456789", null, null, null, true); try { contactDao.saveContact(two); fail("Saving duplicate has not been successful."); } catch(DuplicateKeyException ex) {/* expected */} } /** Test cases for {@link ContactDao#getContactsFilteredByName(String, int, int)} */ public void testFilterByName() { // Set up the test data createContactForFiltering("Abril"); createContactForFiltering("Acacia"); createContactForFiltering("Alicia"); createContactForFiltering("Alita"); createContactForFiltering("Clara"); createContactForFiltering("Clarissa"); createContactForFiltering("Consuela"); createContactForFiltering("Crista"); // Test some filter strings testFilterByName("no-one"); testFilterByName("Abril", "Abril"); testFilterByName("Clar", "Clara", "Clarissa"); testFilterByName("la", "Clara", "Clarissa", "Consuela"); testFilterByName("l", "Abril", "Alicia", "Alita", "Clara", "Clarissa", "Consuela"); } /** Test individual cases for {@link ContactDao#getContactsFilteredByName(String, int, int)} */ private void testFilterByName(String filterString, String... expectedContactNames) { int actualCount = this.contactDao.getContactsFilteredByNameCount(filterString); int expectedCount = expectedContactNames.length; assertEquals(expectedCount, actualCount); List<Contact> actualContacts = this.contactDao.getContactsFilteredByName(filterString, 0, expectedCount); assertNamesEqual(expectedContactNames, actualContacts); } /** Check that the fetched contacts' names match the names we were expecting. */ private void assertNamesEqual(String[] expectedContactNames, final List<Contact> actualContacts) { assertEquals("Contact list length is different to that expected.", expectedContactNames.length, actualContacts.size()); Set<String> actualContactNames = new HashSet<String>(actualContacts.size()); for (Contact contact : actualContacts) { actualContactNames.add(contact.getName()); } for(String expectedName : expectedContactNames) { assertTrue("Contact not retrieved: " + expectedName, actualContactNames.remove(expectedName)); } if(actualContactNames.size() > 0) { String leftovers = ""; for(String leftover : actualContactNames) leftovers += ", " + leftover; fail("DAO retrieved extra contacts for filter: " + leftovers.substring(2)); } } /** Creates a new contact with a given name, and a generated phone number. */ private void createContactForFiltering(String name) { // Generate a random phone number, as we won't be testing with this TODO we may be testing with phone number at a later date String phoneNumber = Integer.toString(name.hashCode()); Contact contact = new Contact(name, phoneNumber, null, null, null, true); try { this.contactDao.saveContact(contact); } catch (DuplicateKeyException e) { throw new IllegalStateException("Failed to set up test. Could not save contact with name: " + name + " and phoneNumber: " + phoneNumber); } } //> TEST SETUP/TEARDOWN //> ACCESSORS /** @param d The DAO to use for the test. */ @Required public void setContactDao(ContactDao d) { this.contactDao = d; } @Required public void setGroupDao(GroupDao groupDao) { this.groupDao = groupDao; } @Required public void setGroupMembershipDao(GroupMembershipDao groupMembershipDao) { this.groupMembershipDao = groupMembershipDao; } }