/** * */ package net.frontlinesms.plugins.forms.data.repository.hibernate; import java.util.Collection; import java.util.Collections; import java.util.HashSet; 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 net.frontlinesms.plugins.forms.data.domain.Form; import net.frontlinesms.plugins.forms.data.repository.FormDao; import net.frontlinesms.plugins.forms.request.NewFormRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Required; /** * Test class for {@link HibernateFormDao} * @author Morgan Belkadi <morgan@frontlinesms.com> */ public class HibernateFormDaoTest extends HibernateTestCase { //> PROPERTIES @Autowired private FormDao formDao; @Autowired private GroupDao groupDao; @Autowired private ContactDao contactDao; @Autowired private GroupMembershipDao groupMembershipDao; //> TEST METHODS public void testSaveAndDeleteForms() throws DuplicateKeyException { Form formOne = new Form("form1"); formDao.saveForm(formOne); assertEquals(1, formDao.getCount()); Form formTwo = new Form("form2"); formDao.saveForm(formTwo); assertEquals(2, formDao.getCount()); final int FORM_ID_ONE = (int)formOne.getFormMobileId(); final int FORM_ID_TWO = (int)formTwo.getFormMobileId(); Group group = new Group(new Group(null, null), "Group"); groupDao.saveGroup(group); formOne.setPermittedGroup(group); formOne.finalise(); assertEquals(formOne, formDao.getFromId(FORM_ID_ONE)); assertNotSame(formOne, formDao.getFromId(FORM_ID_TWO)); formDao.deleteForm(formOne); assertEquals(1, formDao.getCount()); } public void testFormsForUser () throws DuplicateKeyException { Form formOne = new Form("Form with no groups"); Form formTwo = new Form("Form with group"); Form formThree = new Form("Form with group"); formDao.saveForm(formOne); formDao.saveForm(formTwo); formDao.saveForm(formThree); Group groupOne = new Group(new Group(null, null), "Group without forms"); Group groupTwo = new Group(new Group(null, null), "Group with forms"); Group groupThree = new Group(new Group(null, null), "Another group with forms"); groupDao.saveGroup(groupOne); groupDao.saveGroup(groupTwo); groupDao.saveGroup(groupThree); Contact contactOne = createContact("Contact One in no group"); Contact contactTwo = createContact("Contact Two in one group with forms", groupOne, groupTwo); Contact contactThree = createContact("Contact Three in two group with forms", groupTwo, groupThree); final Collection<Integer> NO_FORM_IDS = Collections.emptySet(); NewFormRequest request = new NewFormRequest(NO_FORM_IDS); // Test with a contact with no groups. Shouldn't return any form. assertEquals(0, this.formDao.getFormsForUser(contactOne, request.getCurrentFormIds()).size()); // Test with a contact whose groups are not attached to a form. Shouldn't return any form. assertEquals(0, this.formDao.getFormsForUser(contactTwo, request.getCurrentFormIds()).size()); formOne.setPermittedGroup(groupTwo); formOne.finalise(); // Test with a contact with one group attached to a form. Should return one form. assertEquals(1, this.formDao.getFormsForUser(contactTwo, request.getCurrentFormIds()).size()); formTwo.setPermittedGroup(groupThree); formTwo.finalise(); // Test with a contact with two groups attached to two different forms. Should then return both forms. assertEquals(2, this.formDao.getFormsForUser(contactThree, request.getCurrentFormIds()).size()); Collection<Integer> formIds = new HashSet<Integer>(); formIds.add(formOne.getFormMobileId()); request = new NewFormRequest(formIds); // Test with the last contact, but specifying it already has one of the forms. Should then return only the other form. assertEquals(1, this.formDao.getFormsForUser(contactThree, request.getCurrentFormIds()).size()); formDao.deleteForm(formTwo); // Test with the last contact, but deleting the form it was still registered one. Shouldn't return any form. assertEquals(0, this.formDao.getFormsForUser(contactThree, request.getCurrentFormIds()).size()); } public void testDereferenceGroup() throws DuplicateKeyException { Group group1 = new Group(new Group(null, null), "Test group"); this.groupDao.saveGroup(group1); Group group2 = new Group(group1, "Test child group A"); this.groupDao.saveGroup(group2); Group group3 = new Group(group1, "Test child group B"); this.groupDao.saveGroup(group3); Form form1 = new Form("Test form 1"); form1.setPermittedGroup(group1); this.formDao.saveForm(form1); Form form2 = new Form("Test form 2"); form2.setPermittedGroup(group2); this.formDao.saveForm(form2); Form form3 = new Form("Test form 3"); form3.setPermittedGroup(group3); this.formDao.saveForm(form3); this.groupDao.deleteGroup(group1, false); this.groupDao.deleteGroup(group2, false); this.groupDao.deleteGroup(group3, false); // check that dereferencing the groups and THEN deleting them will succeed assertTrue(this.formDao.getFromId(form1.getFormMobileId()).getPermittedGroup() == null); assertTrue(this.formDao.getFromId(form2.getFormMobileId()).getPermittedGroup() == null); assertTrue(this.formDao.getFromId(form3.getFormMobileId()).getPermittedGroup() == null); } //> HELPER METHODS /** Creates a new contact with a given name, and a generated phone number. */ private Contact createContact(String name, Group ... groups) { // 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); } for (Group group : groups) { this.groupMembershipDao.addMember(group, contact); } return contact; } //> TEST SETUP/TEARDOWN //> ACCESSORS /** @param formDao The DAO to use for the test. */ @Required public void setFormDao(FormDao formDao) { this.formDao = formDao; } /** @param groupDao The DAO to use for the test. */ @Required public void setGroupDao(GroupDao groupDao) { this.groupDao = groupDao; } /** @param contactDao The DAO to use for the test. */ @Required public void setContactDao(ContactDao contactDao) { this.contactDao = contactDao; } /** @param groupMembershipDao The DAO to use for the test. */ @Required public void setGroupMembershipDao(GroupMembershipDao groupMembershipDao) { this.groupMembershipDao = groupMembershipDao; } }