001package edu.pdx.cs.joy.family; 002 003import edu.pdx.cs.joy.jdbc.H2DatabaseHelper; 004import org.junit.jupiter.api.AfterEach; 005import org.junit.jupiter.api.BeforeEach; 006import org.junit.jupiter.api.Test; 007 008import java.sql.Connection; 009import java.sql.SQLException; 010import java.util.Calendar; 011import java.util.Date; 012 013import static org.hamcrest.MatcherAssert.assertThat; 014import static org.hamcrest.Matchers.*; 015 016/** 017 * Unit test for FamilyTree DAO classes. 018 * Tests persistence of Person, Marriage, and FamilyTree objects to an H2 database. 019 */ 020public class FamilyTreeDAOTest { 021 022 private Connection connection; 023 private FamilyTreeDAO familyTreeDAO; 024 025 @BeforeEach 026 public void setUp() throws SQLException { 027 // Create an in-memory H2 database 028 connection = H2DatabaseHelper.createInMemoryConnection("familyTreeTest"); 029 030 // Drop and create tables 031 FamilyTreeDAO.dropTables(connection); 032 FamilyTreeDAO.createTables(connection); 033 034 // Initialize the DAO 035 familyTreeDAO = new FamilyTreeDAOImpl(connection); 036 } 037 038 @AfterEach 039 public void tearDown() throws SQLException { 040 if (connection != null && !connection.isClosed()) { 041 FamilyTreeDAO.dropTables(connection); 042 connection.close(); 043 } 044 } 045 046 @Test 047 public void testPersistAndLoadSimpleFamilyTree() throws SQLException { 048 // Create a simple family tree 049 FamilyTree familyTree = new FamilyTree(); 050 051 Person father = new Person(1, Person.MALE); 052 father.setFirstName("John"); 053 father.setLastName("Doe"); 054 father.setDateOfBirth(createDate(1970, 1, 15)); 055 056 Person mother = new Person(2, Person.FEMALE); 057 mother.setFirstName("Jane"); 058 mother.setLastName("Smith"); 059 mother.setDateOfBirth(createDate(1972, 3, 20)); 060 061 Person child = new Person(3, Person.MALE); 062 child.setFirstName("Jack"); 063 child.setLastName("Doe"); 064 child.setDateOfBirth(createDate(2000, 6, 10)); 065 child.setFather(father); 066 child.setMother(mother); 067 068 familyTree.addPerson(father); 069 familyTree.addPerson(mother); 070 familyTree.addPerson(child); 071 072 // Add marriage 073 Marriage marriage = new Marriage(father, mother); 074 marriage.setDate(createDate(1998, 5, 15)); 075 marriage.setLocation("Portland, OR"); 076 father.addMarriage(marriage); 077 mother.addMarriage(marriage); 078 079 // Save to database 080 familyTreeDAO.save(familyTree); 081 082 // Load from database 083 FamilyTree loadedTree = familyTreeDAO.load(); 084 085 // Validate 086 assertThat(loadedTree.getPeople(), hasSize(3)); 087 assertThat(loadedTree.containsPerson(1), is(true)); 088 assertThat(loadedTree.containsPerson(2), is(true)); 089 assertThat(loadedTree.containsPerson(3), is(true)); 090 091 // Validate father 092 Person loadedFather = loadedTree.getPerson(1); 093 assertThat(loadedFather.getFirstName(), is(equalTo("John"))); 094 assertThat(loadedFather.getLastName(), is(equalTo("Doe"))); 095 assertThat(loadedFather.getGender(), is(equalTo(Person.MALE))); 096 assertThat(loadedFather.getMarriages(), hasSize(1)); 097 098 // Validate mother 099 Person loadedMother = loadedTree.getPerson(2); 100 assertThat(loadedMother.getFirstName(), is(equalTo("Jane"))); 101 assertThat(loadedMother.getLastName(), is(equalTo("Smith"))); 102 assertThat(loadedMother.getGender(), is(equalTo(Person.FEMALE))); 103 104 // Validate child 105 Person loadedChild = loadedTree.getPerson(3); 106 assertThat(loadedChild.getFirstName(), is(equalTo("Jack"))); 107 assertThat(loadedChild.getFather(), is(notNullValue())); 108 assertThat(loadedChild.getFather().getId(), is(equalTo(1))); 109 assertThat(loadedChild.getMother(), is(notNullValue())); 110 assertThat(loadedChild.getMother().getId(), is(equalTo(2))); 111 112 // Validate marriage 113 Marriage loadedMarriage = loadedFather.getMarriages().iterator().next(); 114 assertThat(loadedMarriage.getHusband().getId(), is(equalTo(1))); 115 assertThat(loadedMarriage.getWife().getId(), is(equalTo(2))); 116 assertThat(loadedMarriage.getLocation(), is(equalTo("Portland, OR"))); 117 } 118 119 @Test 120 public void testPersistMultipleGenerations() throws SQLException { 121 FamilyTree familyTree = new FamilyTree(); 122 123 // Grandparents 124 Person grandfather = new Person(1, Person.MALE); 125 grandfather.setFirstName("William"); 126 grandfather.setLastName("Doe"); 127 128 Person grandmother = new Person(2, Person.FEMALE); 129 grandmother.setFirstName("Mary"); 130 grandmother.setLastName("Johnson"); 131 132 // Parents 133 Person father = new Person(3, Person.MALE); 134 father.setFirstName("John"); 135 father.setLastName("Doe"); 136 father.setFather(grandfather); 137 father.setMother(grandmother); 138 139 Person mother = new Person(4, Person.FEMALE); 140 mother.setFirstName("Jane"); 141 mother.setLastName("Smith"); 142 143 // Child 144 Person child = new Person(5, Person.FEMALE); 145 child.setFirstName("Emily"); 146 child.setLastName("Doe"); 147 child.setFather(father); 148 child.setMother(mother); 149 150 familyTree.addPerson(grandfather); 151 familyTree.addPerson(grandmother); 152 familyTree.addPerson(father); 153 familyTree.addPerson(mother); 154 familyTree.addPerson(child); 155 156 // Save and load 157 familyTreeDAO.save(familyTree); 158 FamilyTree loadedTree = familyTreeDAO.load(); 159 160 // Validate multi-generation relationships 161 assertThat(loadedTree.getPeople(), hasSize(5)); 162 163 Person loadedChild = loadedTree.getPerson(5); 164 assertThat(loadedChild.getFather(), is(notNullValue())); 165 assertThat(loadedChild.getFather().getId(), is(equalTo(3))); 166 167 Person loadedFather = loadedChild.getFather(); 168 assertThat(loadedFather.getFather(), is(notNullValue())); 169 assertThat(loadedFather.getFather().getId(), is(equalTo(1))); 170 assertThat(loadedFather.getMother(), is(notNullValue())); 171 assertThat(loadedFather.getMother().getId(), is(equalTo(2))); 172 } 173 174 @Test 175 public void testPersistPersonWithDates() throws SQLException { 176 FamilyTree familyTree = new FamilyTree(); 177 178 Person person = new Person(1, Person.MALE); 179 person.setFirstName("George"); 180 person.setLastName("Washington"); 181 person.setDateOfBirth(createDate(1732, 2, 22)); 182 person.setDateOfDeath(createDate(1799, 12, 14)); 183 184 familyTree.addPerson(person); 185 186 familyTreeDAO.save(familyTree); 187 FamilyTree loadedTree = familyTreeDAO.load(); 188 189 Person loadedPerson = loadedTree.getPerson(1); 190 assertThat(loadedPerson.getDateOfBirth(), is(notNullValue())); 191 assertThat(loadedPerson.getDateOfDeath(), is(notNullValue())); 192 } 193 194 @Test 195 public void testLoadEmptyFamilyTree() throws SQLException { 196 FamilyTree loadedTree = familyTreeDAO.load(); 197 assertThat(loadedTree.getPeople(), is(empty())); 198 } 199 200 @Test 201 public void testPersistPersonWithoutParents() throws SQLException { 202 FamilyTree familyTree = new FamilyTree(); 203 204 Person person = new Person(1, Person.FEMALE); 205 person.setFirstName("Alice"); 206 person.setLastName("Unknown"); 207 208 familyTree.addPerson(person); 209 210 familyTreeDAO.save(familyTree); 211 FamilyTree loadedTree = familyTreeDAO.load(); 212 213 Person loadedPerson = loadedTree.getPerson(1); 214 assertThat(loadedPerson, is(notNullValue())); 215 assertThat(loadedPerson.getFather(), is(nullValue())); 216 assertThat(loadedPerson.getMother(), is(nullValue())); 217 } 218 219 /** 220 * Helper method to create a Date object. 221 */ 222 private Date createDate(int year, int month, int day) { 223 Calendar cal = Calendar.getInstance(); 224 cal.set(year, month - 1, day, 0, 0, 0); 225 cal.set(Calendar.MILLISECOND, 0); 226 return cal.getTime(); 227 } 228} 229