From 3401af980999ca9b639534061a33ddb9cef41ace Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Wed, 30 Sep 2026 19:59:31 -0500 Subject: [PATCH 1/2] added tests for comet calendar room normalization and building precedence --- parser/cometCalendarParser_test.go | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/parser/cometCalendarParser_test.go b/parser/cometCalendarParser_test.go index 6757309..a85be06 100644 --- a/parser/cometCalendarParser_test.go +++ b/parser/cometCalendarParser_test.go @@ -394,3 +394,79 @@ func TestParseCometCalendar_UsesOtherForEmptyLocation(t *testing.T) { t.Fatalf("expected 1 event in Other/Other, got %d", len(roomEntry.Events)) } } + +// Test multiple Galaxy rooms +func TestNormalizeRoom_GalaxyMultipleRooms(t *testing.T) { + t.Parallel() + + got := normalizeRoom("", "Galaxy Rooms A, B & C") + want := "Galaxy Room (A, B, & C)" + + if got != want { + t.Fatalf("normalizeRoom() = %q, want %q", got, want) + } +} + +// Test the Student Union First Floor +func TestNormalizeRoom_SUFirstFloor(t *testing.T) { + t.Parallel() + + got := normalizeRoom("Student Union (SU)", "SU First Floor, Chess Plaza") + want := "First Floor" + + if got != want { + t.Fatalf("normalizeRoom() = %q, want %q", got, want) + } +} + +// Test that the room name and number does not mix up, "SU Mall Plinth, JSOM 12.110" -> "SU 12.110" +func TestParseCometCalendar_PrefersRightSideBuildingAndRoomOnSUCase(t *testing.T) { + t.Parallel() + + // Arrange: create isolated directories and known buildings. + inDir := t.TempDir() + outDir := t.TempDir() + + locations := []schema.MapBuilding{ + { + Name: strPtr("Student Union (SU)"), + Acronym: strPtr("SU"), + }, + { + Name: strPtr("Naveen Jindal School of Management (JSOM)"), + Acronym: strPtr("JSOM"), + }, + } + writeJSONFile(t, filepath.Join(inDir, "mapLocations.json"), locations) + + start := time.Date(2026, 3, 14, 9, 0, 0, 0, time.UTC) + events := []schema.Event{ + makeEvent("Right Side Location Event", "SU Mall Plinth, JSOM 12.110", start), + } + writeJSONFile(t, filepath.Join(inDir, "cometCalendarScraped.json"), events) + + // Act: parse the input files. + ParseCometCalendar(inDir, outDir) + + // Assert: the event should be grouped under JSOM / 12.110. + result := readJSONFile[[]schema.MultiBuildingEvents[schema.Event]]( + t, + filepath.Join(outDir, "cometCalendar.json"), + ) + + dateEntry := findDate(t, result, "2026-03-14") + if len(dateEntry.Buildings) != 1 { + t.Fatalf("expected 1 building, got %d", len(dateEntry.Buildings)) + } + + buildingEntry := findBuilding(t, dateEntry, "JSOM") + roomEntry := findRoom(t, buildingEntry, "12.110") + + if len(roomEntry.Events) != 1 { + t.Fatalf("expected 1 event in JSOM/12.110, got %d", len(roomEntry.Events)) + } + + if diff := cmp.Diff(events[0].Summary, roomEntry.Events[0].Summary); diff != "" { + t.Fatalf("unexpected event stored in room (-want +got);\n%s", diff) + } +} From a26eaca0dd76c81a9017a3eb6476327ee50586ce Mon Sep 17 00:00:00 2001 From: Quan Nguyen Date: Thu, 1 Oct 2026 12:15:45 -0500 Subject: [PATCH 2/2] fix: preserve Galaxy room Lists and match building-room pairs, added unit tests for the failing cases --- parser/cometCalendarParser.go | 20 +++++++++++++++++--- parser/cometCalendarParser_test.go | 4 ++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/parser/cometCalendarParser.go b/parser/cometCalendarParser.go index 70ca0ec..96f28c5 100644 --- a/parser/cometCalendarParser.go +++ b/parser/cometCalendarParser.go @@ -22,8 +22,9 @@ import ( // Regexp to match building abbreviations and room numbers var ( - buildingRegexp = regexp.MustCompile(`[A-Z]{2,4}`) - roomRegexp = regexp.MustCompile(`([0-9]{1,2}\.[0-9]{3})([A-Z])?`) + buildingRegexp = regexp.MustCompile(`[A-Z]{2,4}`) + roomRegexp = regexp.MustCompile(`([0-9]{1,2}\.[0-9]{3})([A-Z])?`) + buildingRoomRegexp = regexp.MustCompile(`\b([A-Z]{2,4})\s+([0-9]{1,2}\.[0-9]{3}[A-Z]?)\b`) ) // ParseCometCalendar reformats the comet calendar data into uploadable json in Mongo @@ -61,6 +62,16 @@ func ParseCometCalendar(inDir string, outDir string) { building := buildingRegexp.FindString(*location) room := roomRegexp.FindString(*location) + // prefer an explicity building-room pair if it exists, e.g., "SU Mall Plinth, JSOM 12.110" -> "JSOM 12.110" + matches := buildingRoomRegexp.FindAllStringSubmatch(*location, -1) + for _, match := range matches { + if slices.Contains(validAbbreviations, match[1]) { + building = match[1] + room = match[2] + break + } + } + // buildingRegexp might capture something that isn't a valid building abbreviation (e.g., UTD) isValidBuilding := slices.Contains(validAbbreviations, building) @@ -192,7 +203,10 @@ func normalizeRoom(building string, room string) string { } // Non-number room - room = strings.ToLower(strings.Split(room, ", ")[0]) + room = strings.ToLower(room) + if !strings.Contains(room, "galaxy") { + room = strings.Split(room, ", ")[0] + } tokens := strings.Split(room, " ") normalizedTokens := []string{} for _, token := range tokens { diff --git a/parser/cometCalendarParser_test.go b/parser/cometCalendarParser_test.go index a85be06..80eaa6e 100644 --- a/parser/cometCalendarParser_test.go +++ b/parser/cometCalendarParser_test.go @@ -400,7 +400,7 @@ func TestNormalizeRoom_GalaxyMultipleRooms(t *testing.T) { t.Parallel() got := normalizeRoom("", "Galaxy Rooms A, B & C") - want := "Galaxy Room (A, B, & C)" + want := "Galaxy Room (A, B, & C)" if got != want { t.Fatalf("normalizeRoom() = %q, want %q", got, want) @@ -420,7 +420,7 @@ func TestNormalizeRoom_SUFirstFloor(t *testing.T) { } // Test that the room name and number does not mix up, "SU Mall Plinth, JSOM 12.110" -> "SU 12.110" -func TestParseCometCalendar_PrefersRightSideBuildingAndRoomOnSUCase(t *testing.T) { +func TestParseCometCalendar_PrefersExplicitBuildingRoomPair(t *testing.T) { t.Parallel() // Arrange: create isolated directories and known buildings.