001package edu.pdx.cs.joy.jdbc;
002
003import org.junit.jupiter.api.AfterEach;
004import org.junit.jupiter.api.BeforeEach;
005import org.junit.jupiter.api.Test;
006
007import java.sql.Connection;
008import java.sql.SQLException;
009import java.time.LocalDate;
010import java.util.List;
011
012import static org.hamcrest.MatcherAssert.assertThat;
013import static org.hamcrest.Matchers.*;
014
015public class AcademicTermDAOTest {
016
017  private Connection connection;
018  private AcademicTermDAO termDAO;
019
020  @BeforeEach
021  public void setUp() throws SQLException {
022    // Create an in-memory H2 database
023    connection = H2DatabaseHelper.createInMemoryConnection("test");
024
025    // Drop and create the academic_terms table
026    AcademicTermDAOImpl.dropTable(connection);
027    AcademicTermDAOImpl.createTable(connection);
028
029    // Initialize the DAO with the connection
030    termDAO = new AcademicTermDAOImpl(connection);
031  }
032
033  @AfterEach
034  public void tearDown() throws SQLException {
035    if (connection != null && !connection.isClosed()) {
036      AcademicTermDAOImpl.dropTable(connection);
037      connection.close();
038    }
039  }
040
041  @Test
042  public void testPersistAndFetchAcademicTerm() throws SQLException {
043    // Create an academic term
044    String termName = "Fall 2024";
045    LocalDate startDate = LocalDate.of(2024, 9, 1);
046    LocalDate endDate = LocalDate.of(2024, 12, 15);
047    AcademicTerm term = new AcademicTerm(termName, startDate, endDate);
048
049    // Persist the term
050    termDAO.save(term);
051
052    // Verify that an ID was auto-generated
053    int generatedId = term.getId();
054    assertThat(generatedId, is(greaterThan(0)));
055
056    // Fetch the term by ID
057    AcademicTerm fetchedTerm = termDAO.findById(generatedId);
058
059    // Validate the fetched term using Hamcrest assertions
060    assertThat(fetchedTerm, is(notNullValue()));
061    assertThat(fetchedTerm.getId(), is(equalTo(generatedId)));
062    assertThat(fetchedTerm.getName(), is(equalTo(termName)));
063    assertThat(fetchedTerm.getStartDate(), is(equalTo(startDate)));
064    assertThat(fetchedTerm.getEndDate(), is(equalTo(endDate)));
065  }
066
067  @Test
068  public void testFindByName() throws SQLException {
069    // Create and persist an academic term
070    String termName = "Spring 2025";
071    LocalDate startDate = LocalDate.of(2025, 1, 15);
072    LocalDate endDate = LocalDate.of(2025, 5, 30);
073    AcademicTerm term = new AcademicTerm(termName, startDate, endDate);
074    termDAO.save(term);
075
076    // Fetch the term by name
077    AcademicTerm fetchedTerm = termDAO.findByName(termName);
078
079    // Validate the fetched term
080    assertThat(fetchedTerm, is(notNullValue()));
081    assertThat(fetchedTerm.getName(), is(equalTo(termName)));
082    assertThat(fetchedTerm.getStartDate(), is(equalTo(startDate)));
083    assertThat(fetchedTerm.getEndDate(), is(equalTo(endDate)));
084  }
085
086  @Test
087  public void testFindNonExistentTerm() throws SQLException {
088    // Try to fetch a term that doesn't exist
089    AcademicTerm fetchedTerm = termDAO.findById(999);
090    assertThat(fetchedTerm, is(nullValue()));
091
092    AcademicTerm fetchedByName = termDAO.findByName("Nonexistent Term");
093    assertThat(fetchedByName, is(nullValue()));
094  }
095
096  @Test
097  public void testFindAllTerms() throws SQLException {
098    // Create and persist multiple academic terms
099    AcademicTerm fall2024 = new AcademicTerm("Fall 2024",
100        LocalDate.of(2024, 9, 1), LocalDate.of(2024, 12, 15));
101    AcademicTerm spring2025 = new AcademicTerm("Spring 2025",
102        LocalDate.of(2025, 1, 15), LocalDate.of(2025, 5, 30));
103    AcademicTerm summer2025 = new AcademicTerm("Summer 2025",
104        LocalDate.of(2025, 6, 15), LocalDate.of(2025, 8, 30));
105
106    termDAO.save(fall2024);
107    termDAO.save(spring2025);
108    termDAO.save(summer2025);
109
110    // Fetch all terms
111    List<AcademicTerm> allTerms = termDAO.findAll();
112
113    // Validate using Hamcrest matchers
114    assertThat(allTerms, hasSize(3));
115    assertThat(allTerms, hasItem(hasProperty("name", is("Fall 2024"))));
116    assertThat(allTerms, hasItem(hasProperty("name", is("Spring 2025"))));
117    assertThat(allTerms, hasItem(hasProperty("name", is("Summer 2025"))));
118
119    // Verify terms are ordered by start date
120    assertThat(allTerms.get(0).getName(), is(equalTo("Fall 2024")));
121    assertThat(allTerms.get(1).getName(), is(equalTo("Spring 2025")));
122    assertThat(allTerms.get(2).getName(), is(equalTo("Summer 2025")));
123  }
124
125  @Test
126  public void testUpdateAcademicTerm() throws SQLException {
127    // Create and persist an academic term
128    AcademicTerm term = new AcademicTerm("Fall 2024",
129        LocalDate.of(2024, 9, 1), LocalDate.of(2024, 12, 15));
130    termDAO.save(term);
131    int termId = term.getId();
132
133    // Update the term
134    term.setName("Fall 2024 (Extended)");
135    term.setEndDate(LocalDate.of(2024, 12, 20));
136    termDAO.update(term);
137
138    // Fetch the updated term
139    AcademicTerm updatedTerm = termDAO.findById(termId);
140
141    // Validate the update
142    assertThat(updatedTerm, is(notNullValue()));
143    assertThat(updatedTerm.getId(), is(equalTo(termId)));
144    assertThat(updatedTerm.getName(), is(equalTo("Fall 2024 (Extended)")));
145    assertThat(updatedTerm.getEndDate(), is(equalTo(LocalDate.of(2024, 12, 20))));
146  }
147
148  @Test
149  public void testDeleteAcademicTerm() throws SQLException {
150    // Create and persist an academic term
151    AcademicTerm term = new AcademicTerm("Fall 2024",
152        LocalDate.of(2024, 9, 1), LocalDate.of(2024, 12, 15));
153    termDAO.save(term);
154    int termId = term.getId();
155
156    // Verify the term exists
157    assertThat(termDAO.findById(termId), is(notNullValue()));
158
159    // Delete the term
160    termDAO.delete(termId);
161
162    // Verify the term no longer exists
163    assertThat(termDAO.findById(termId), is(nullValue()));
164  }
165
166  @Test
167  public void testDatesArePersisted() throws SQLException {
168    // Create terms with different dates
169    AcademicTerm term1 = new AcademicTerm("Term 1",
170        LocalDate.of(2024, 1, 1), LocalDate.of(2024, 3, 31));
171    AcademicTerm term2 = new AcademicTerm("Term 2",
172        LocalDate.of(2024, 6, 1), LocalDate.of(2024, 8, 31));
173
174    termDAO.save(term1);
175    termDAO.save(term2);
176
177    // Fetch and verify dates
178    AcademicTerm fetched1 = termDAO.findByName("Term 1");
179    AcademicTerm fetched2 = termDAO.findByName("Term 2");
180
181    assertThat(fetched1.getStartDate(), is(equalTo(LocalDate.of(2024, 1, 1))));
182    assertThat(fetched1.getEndDate(), is(equalTo(LocalDate.of(2024, 3, 31))));
183    assertThat(fetched2.getStartDate(), is(equalTo(LocalDate.of(2024, 6, 1))));
184    assertThat(fetched2.getEndDate(), is(equalTo(LocalDate.of(2024, 8, 31))));
185  }
186}
187