From 032f4de98d693e5c5d9c217b438c213eb8f7e9ef Mon Sep 17 00:00:00 2001 From: Hudson Hadley Date: Mon, 20 Apr 2026 20:16:35 -0400 Subject: [PATCH 1/6] Making courses have ids that relate to the database --- backend/src/main/java/edu/gcc/hallmonitor/Course.java | 1 + backend/src/main/java/edu/gcc/hallmonitor/Schedule.java | 1 + backend/src/main/java/edu/gcc/hallmonitor/Search.java | 1 + 3 files changed, 3 insertions(+) diff --git a/backend/src/main/java/edu/gcc/hallmonitor/Course.java b/backend/src/main/java/edu/gcc/hallmonitor/Course.java index 0b1c82a..cfaf157 100644 --- a/backend/src/main/java/edu/gcc/hallmonitor/Course.java +++ b/backend/src/main/java/edu/gcc/hallmonitor/Course.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; public record Course( + int id, String name, @JsonProperty("faculty") List professor, diff --git a/backend/src/main/java/edu/gcc/hallmonitor/Schedule.java b/backend/src/main/java/edu/gcc/hallmonitor/Schedule.java index e2d84f7..e84816e 100644 --- a/backend/src/main/java/edu/gcc/hallmonitor/Schedule.java +++ b/backend/src/main/java/edu/gcc/hallmonitor/Schedule.java @@ -148,6 +148,7 @@ public List getCourses() { } Course copyCourse = new Course( + c.id(), c.name(), new ArrayList<>(c.professor()), c.department(), diff --git a/backend/src/main/java/edu/gcc/hallmonitor/Search.java b/backend/src/main/java/edu/gcc/hallmonitor/Search.java index 89e52f8..d38c589 100644 --- a/backend/src/main/java/edu/gcc/hallmonitor/Search.java +++ b/backend/src/main/java/edu/gcc/hallmonitor/Search.java @@ -51,6 +51,7 @@ private static void loadCourses() { List courseTimes = mapper.readerForListOf(CourseTime.class).readValue(time_json); Course c = new Course( + rs.getInt("id"), rs.getString("name"), facultyList, rs.getString("subject"), From 4a863a314166d6fce1004fbecc5695d12a3dc810 Mon Sep 17 00:00:00 2001 From: Hudson Hadley Date: Mon, 20 Apr 2026 20:26:07 -0400 Subject: [PATCH 2/6] Adding arbitrary ids for testing purposes. Removing load and save tests that load/save from/to json --- .../edu/gcc/hallmonitor/ScheduleTest.java | 109 +++--------------- 1 file changed, 16 insertions(+), 93 deletions(-) diff --git a/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java b/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java index 97e2441..a656985 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java @@ -40,95 +40,18 @@ void assertSchedulesEqual(Schedule expected, Schedule actual) { } } - @Test - void loadSaveSchedule() { - Schedule expectedSchedule = new Schedule(List.of( - new Course( - "COMP PROGRAMMING I", - List.of("Wolfe, Britton D."), - "COMP", - 141, - 'A', - "Science Technology Engineering", - 3, - "2023_Fall", - List.of( - new CourseTime( - "M", - LocalTime.of(12, 0, 0), - LocalTime.of(12, 50, 0) - ), - new CourseTime( - "W", - LocalTime.of(12, 0, 0), - LocalTime.of(12, 50, 0) - ), - new CourseTime( - "F", - LocalTime.of(12, 0, 0), - LocalTime.of(12, 50, 0) - ) - ), - false, - false, - 0, - 32 - ), - new Course( - "INTRO TO COMPUTER SCIENCE", - List.of("Dickinson, Brian C"), - "COMP", - 155, - 'A', - "STEM 326", - 3, - "2023_Fall", - List.of( - new CourseTime( - "T", - LocalTime.of(11, 0, 0), - LocalTime.of(12, 15, 0) - ), - new CourseTime( - "R", - LocalTime.of(11, 0, 0), - LocalTime.of(12, 15, 0) - ) - ), - false, - false, - 0, - 32 - ) - )); - try { - expectedSchedule.saveSchedule("test.json"); - } catch (IOException ioe) { - fail("Failed to save schedule"); - } - - Schedule actualSchedule = null; - try { - actualSchedule = Schedule.loadSchedule("test.json"); - } catch (IOException ioe) { - fail("Unable to load schedule.json"); - } - - assertSchedulesEqual(expectedSchedule, actualSchedule); - } - @Test void checkForOverlap_noOverlap() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10, 0), LocalTime.of(11, 0))), false, false, 0, 30 ) )); Course newCourse = new Course( - "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", + 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(11, 0), LocalTime.of(12, 0))), false, false, 0, 30 ); @@ -140,14 +63,14 @@ void checkForOverlap_noOverlap() { void checkForOverlap_overlapSameDay() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10, 0), LocalTime.of(11, 0))), false, false, 0, 30 ) )); Course newCourse = new Course( - "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", + 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10, 30), LocalTime.of(11, 30))), false, false, 0, 30 ); @@ -158,14 +81,14 @@ void checkForOverlap_overlapSameDay() { void checkForOverlap_differentDays() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10,0), LocalTime.of(11,0))), false,false,0,30 ) )); Course newCourse = new Course( - "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", + 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("T", LocalTime.of(10,30), LocalTime.of(11,30))), false,false,0,30 ); @@ -176,14 +99,14 @@ void checkForOverlap_differentDays() { void checkForOverlap_touchingTimesNotOverlap() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10,0), LocalTime.of(11,0))), false,false,0,30 ) )); Course newCourse = new Course( - "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", + 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(11,0), LocalTime.of(12,0))), false,false,0,30 ); @@ -194,7 +117,7 @@ void checkForOverlap_touchingTimesNotOverlap() { void checkForOverlap_invalidTimeIgnored() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10,0), LocalTime.of(11,0))), false,false,0,30 ) @@ -202,7 +125,7 @@ void checkForOverlap_invalidTimeIgnored() { // end before start → ignored Course newCourse = new Course( - "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", + 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(12,0), LocalTime.of(11,0))), false,false,0,30 ); @@ -215,13 +138,13 @@ void checkForOverlap_invalidTimeIgnored() { void hasDifferentSection_trueWhenDifferentSection() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(), false,false,0,30 ) )); Course newCourse = new Course( - "Course1", List.of("Prof"), "COMP", 101, 'B', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'B', "Room", 3, "2023_Fall", List.of(), false,false,0,30 ); @@ -232,13 +155,13 @@ void hasDifferentSection_trueWhenDifferentSection() { void hasDifferentSection_falseSameSection() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(), false,false,0,30 ) )); Course newCourse = new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(), false,false,0,30 ); @@ -249,13 +172,13 @@ void hasDifferentSection_falseSameSection() { void hasDifferentSection_falseDifferentCourse() { Schedule schedule = new Schedule(List.of( new Course( - "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(), false,false,0,30 ) )); Course newCourse = new Course( - "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", + 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", List.of(), false,false,0,30 ); From 78cf27a8598edf8877e86f45e97d75838b4f596d Mon Sep 17 00:00:00 2001 From: Hudson Hadley Date: Mon, 20 Apr 2026 20:33:17 -0400 Subject: [PATCH 3/6] Fixing tests so that they all include arbitrary course ids when necessary --- backend/src/test/java/edu/gcc/hallmonitor/DaysTest.java | 1 + backend/src/test/java/edu/gcc/hallmonitor/DepartmentTest.java | 1 + backend/src/test/java/edu/gcc/hallmonitor/NumCreditsTest.java | 1 + backend/src/test/java/edu/gcc/hallmonitor/ProfNameTest.java | 1 + backend/src/test/java/edu/gcc/hallmonitor/TimeTest.java | 1 + 5 files changed, 5 insertions(+) diff --git a/backend/src/test/java/edu/gcc/hallmonitor/DaysTest.java b/backend/src/test/java/edu/gcc/hallmonitor/DaysTest.java index 2ae190d..78bd9f5 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/DaysTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/DaysTest.java @@ -36,6 +36,7 @@ public void testMatchSingleDay() { public Course emptyOnDays(List days) { return new Course( + 1, "", List.of(""), "", diff --git a/backend/src/test/java/edu/gcc/hallmonitor/DepartmentTest.java b/backend/src/test/java/edu/gcc/hallmonitor/DepartmentTest.java index 3d30374..b7e26e2 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/DepartmentTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/DepartmentTest.java @@ -20,6 +20,7 @@ public void testDepartmentFilter() { private static Course emptyWithDepartment(String department) { return new Course( + 1, "", List.of(""), department, diff --git a/backend/src/test/java/edu/gcc/hallmonitor/NumCreditsTest.java b/backend/src/test/java/edu/gcc/hallmonitor/NumCreditsTest.java index 99d50bc..2711105 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/NumCreditsTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/NumCreditsTest.java @@ -20,6 +20,7 @@ public void testNumCreditsFilter() { private static Course emptyWithCredits(int credits) { return new Course( + 1, "", List.of(""), "", diff --git a/backend/src/test/java/edu/gcc/hallmonitor/ProfNameTest.java b/backend/src/test/java/edu/gcc/hallmonitor/ProfNameTest.java index 6b640fa..819cecb 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/ProfNameTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/ProfNameTest.java @@ -20,6 +20,7 @@ public void testProfNameFilter() { private static Course emptyWithProf(String prof) { return new Course( + 1, "", List.of(prof), "", diff --git a/backend/src/test/java/edu/gcc/hallmonitor/TimeTest.java b/backend/src/test/java/edu/gcc/hallmonitor/TimeTest.java index 39786d1..a3d3b58 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/TimeTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/TimeTest.java @@ -21,6 +21,7 @@ public void testMatchTime() { private static Course emptyAtTimes(List times) { return new Course( + 1, "", List.of(""), "", From 66b365aa1921bab18fde99bf39c8595c0abf31f1 Mon Sep 17 00:00:00 2001 From: Hudson Hadley Date: Mon, 20 Apr 2026 20:42:57 -0400 Subject: [PATCH 4/6] Altering schedule test so that it saves a schedule with course ids --- .../edu/gcc/hallmonitor/ScheduleTest.java | 86 ++++++++++++++++++- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java b/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java index a656985..c5a4a29 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/ScheduleTest.java @@ -18,6 +18,7 @@ void assertSchedulesEqual(Schedule expected, Schedule actual) { Course expectedCourse = expectedCourses.get(i); Course actualCourse = actualCourses.get(i); + assertEquals(expectedCourse.id(), actualCourse.id()); assertEquals(expectedCourse.name(), actualCourse.name()); assertEquals(expectedCourse.professor().size(), actualCourse.professor().size()); for (int j = 0; j < actualCourse.professor().size(); j++) { @@ -40,18 +41,97 @@ void assertSchedulesEqual(Schedule expected, Schedule actual) { } } + @Test + void loadSaveSchedule() { + Schedule expectedSchedule = new Schedule(List.of( + new Course( + 1, + "COMP PROGRAMMING I", + List.of("Wolfe, Britton D."), + "COMP", + 141, + 'A', + "Science Technology Engineering", + 3, + "2023_Fall", + List.of( + new CourseTime( + "M", + LocalTime.of(12, 0, 0), + LocalTime.of(12, 50, 0) + ), + new CourseTime( + "W", + LocalTime.of(12, 0, 0), + LocalTime.of(12, 50, 0) + ), + new CourseTime( + "F", + LocalTime.of(12, 0, 0), + LocalTime.of(12, 50, 0) + ) + ), + false, + false, + 0, + 32 + ), + new Course( + 2, + "INTRO TO COMPUTER SCIENCE", + List.of("Dickinson, Brian C"), + "COMP", + 155, + 'A', + "STEM 326", + 3, + "2023_Fall", + List.of( + new CourseTime( + "T", + LocalTime.of(11, 0, 0), + LocalTime.of(12, 15, 0) + ), + new CourseTime( + "R", + LocalTime.of(11, 0, 0), + LocalTime.of(12, 15, 0) + ) + ), + false, + false, + 0, + 32 + ) + )); + try { + expectedSchedule.saveSchedule("test.json"); + } catch (IOException ioe) { + fail("Failed to save schedule"); + } + + Schedule actualSchedule = null; + try { + actualSchedule = Schedule.loadSchedule("test.json"); + } catch (IOException ioe) { + fail("Unable to load schedule.json"); + } + + assertSchedulesEqual(expectedSchedule, actualSchedule); + } + @Test void checkForOverlap_noOverlap() { Schedule schedule = new Schedule(List.of( new Course( - 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10, 0), LocalTime.of(11, 0))), false, false, 0, 30 ) )); Course newCourse = new Course( - 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", + 2, "Course2", List.of("Prof"), "COMP", 102, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(11, 0), LocalTime.of(12, 0))), false, false, 0, 30 ); @@ -63,7 +143,7 @@ void checkForOverlap_noOverlap() { void checkForOverlap_overlapSameDay() { Schedule schedule = new Schedule(List.of( new Course( - 1, "Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", + 1,"Course1", List.of("Prof"), "COMP", 101, 'A', "Room", 3, "2023_Fall", List.of(new CourseTime("M", LocalTime.of(10, 0), LocalTime.of(11, 0))), false, false, 0, 30 ) From 61b252a37daf6b4a3a3474c1a3337e36aef6c0f7 Mon Sep 17 00:00:00 2001 From: Hudson Hadley Date: Mon, 20 Apr 2026 20:43:35 -0400 Subject: [PATCH 5/6] Making the connection static so that each user doesn't create a new connection and max out the pool --- .../main/java/edu/gcc/hallmonitor/User.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/edu/gcc/hallmonitor/User.java b/backend/src/main/java/edu/gcc/hallmonitor/User.java index b7f2bc2..1832efe 100644 --- a/backend/src/main/java/edu/gcc/hallmonitor/User.java +++ b/backend/src/main/java/edu/gcc/hallmonitor/User.java @@ -13,7 +13,15 @@ public class User { private byte[] passwordHash; private int id; private int gradYear; - private Connection connection; + private static Connection CONNECTION; + + static { + try { + CONNECTION = Database.getConnection(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } /** * Basic constructor that sets the username and password hash. NOTE: YOU SHOULD USE THE login() or signUp() METHOD @@ -39,7 +47,6 @@ public User(String username, String password) throws IllegalArgumentException, S throw new IllegalArgumentException("sha256 not found"); } // won't fail since sha256 is hardcoded - connection = Database.getConnection(); } public String getUsername() { @@ -87,7 +94,7 @@ public static User signup(String username, String password) throws SQLException */ public boolean isUser() throws SQLException { // Get all the users that match the current user (should be at max 1) - PreparedStatement prepStatement = connection.prepareStatement( + PreparedStatement prepStatement = CONNECTION.prepareStatement( "SELECT * FROM public.\"users\"" + "WHERE username = ? AND password_hash = ?" ); @@ -100,7 +107,7 @@ public boolean isUser() throws SQLException { } public int getIdFromDatabase() throws SQLException { - PreparedStatement prepStatement = connection.prepareStatement( + PreparedStatement prepStatement = CONNECTION.prepareStatement( "SELECT id FROM public.\"users\"" + "WHERE username = ? AND password_hash = ?" ); @@ -118,7 +125,7 @@ public int getIdFromDatabase() throws SQLException { * @throws SQLException if the connection fails */ public boolean isUsernameTaken() throws SQLException { - PreparedStatement prepStatement = connection.prepareStatement( + PreparedStatement prepStatement = CONNECTION.prepareStatement( "SELECT * FROM public.\"users\"" + "WHERE username = ?" ); @@ -140,7 +147,7 @@ public boolean addUser() throws SQLException { return false; } - PreparedStatement prepStatement = connection.prepareStatement( + PreparedStatement prepStatement = CONNECTION.prepareStatement( "INSERT INTO public.\"users\" (username, password_hash, grad_year)" + "VALUES (?, ?, ?)" ); @@ -162,7 +169,7 @@ public boolean deleteUser() throws SQLException { if (!isUser()) { return false; } - PreparedStatement prepStatement = connection.prepareStatement( + PreparedStatement prepStatement = CONNECTION.prepareStatement( "DELETE FROM public.\"users\" WHERE username = ? AND password_hash = ?" ); prepStatement.setString(1, username); From 15b42870d0efb911b5b670eabb4eac00a74980d9 Mon Sep 17 00:00:00 2001 From: Hudson Hadley Date: Tue, 21 Apr 2026 10:32:48 -0400 Subject: [PATCH 6/6] Fixing semester test to comply with course ids --- backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java b/backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java index 48da53b..83ab15d 100644 --- a/backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java +++ b/backend/src/test/java/edu/gcc/hallmonitor/SemesterTest.java @@ -21,6 +21,7 @@ public void testSemesterFilter() { private static Course emptyWithSemester(String semester) { return new Course( + 1, "", List.of(""), "",