Skip to content

Commit 207f87e

Browse files
mikehquan19jpahm
authored andcommitted
Add unit tests for validator
1 parent 26ae762 commit 207f87e

File tree

4 files changed

+556
-65
lines changed

4 files changed

+556
-65
lines changed

.env.template

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
#Scrapers
1+
# Scrapers
22
LOGIN_NETID=
33
LOGIN_PASSWORD=
44
LOGIN_ASTRA_USERNAME=
55
LOGIN_ASTRA_PASSWORD=
66
#Login to https://east.mymazevo.com/main-home then go to https://east.mymazevo.com/api/tenantsettings/GetApiKey
77
MAZEVO_API_KEY=
88

9-
#Uploader
9+
# Uploader
1010
MONGODB_URI=

parser/validator.go

Lines changed: 94 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ package parser
22

33
import (
44
"log"
5+
"slices"
56

67
"github.com/UTDNebula/api-tools/utils"
8+
"github.com/UTDNebula/nebula-api/api/schema"
9+
"go.mongodb.org/mongo-driver/bson/primitive"
710
)
811

12+
// Main validation, putting everything together
913
func validate() {
1014
// Set up deferred handler for panics to display validation fails
1115
defer func() {
@@ -16,97 +20,126 @@ func validate() {
1620

1721
log.Printf("\nValidating courses...")
1822
courseKeys := utils.GetMapKeys(Courses)
19-
for i := 0; i < len(courseKeys)-1; i++ {
23+
for i := range len(courseKeys) {
2024
course1 := Courses[courseKeys[i]]
2125
// Check for duplicate courses by comparing course_number, subject_prefix, and catalog_year as a compound key
2226
for j := i + 1; j < len(courseKeys); j++ {
2327
course2 := Courses[courseKeys[j]]
24-
if course2.Catalog_year == course1.Catalog_year && course2.Course_number == course1.Course_number && course2.Subject_prefix == course1.Subject_prefix {
25-
log.Printf("Duplicate course found for %s%s!", course1.Subject_prefix, course1.Course_number)
26-
log.Printf("Course 1: %v\n\nCourse 2: %v", course1, course2)
27-
log.Panic("Courses failed to validate!")
28-
}
28+
valDuplicateCourses(course1, course2)
2929
}
3030
// Make sure course isn't referencing any nonexistent sections, and that course-section references are consistent both ways
31-
for _, sectionId := range course1.Sections {
32-
section, exists := Sections[sectionId]
33-
if !exists {
34-
log.Printf("Nonexistent section reference found for %s%s!", course1.Subject_prefix, course1.Course_number)
35-
log.Printf("Referenced section ID: %s\nCourse ID: %s", sectionId, course1.Id)
36-
log.Panic("Courses failed to validate!")
37-
}
38-
if section.Course_reference != course1.Id {
39-
log.Printf("Inconsistent section reference found for %s%s! The course references the section, but not vice-versa!", course1.Subject_prefix, course1.Course_number)
40-
log.Printf("Referenced section ID: %s\nCourse ID: %s\nSection course reference: %s", sectionId, course1.Id, section.Course_reference)
41-
log.Panic("Courses failed to validate!")
42-
}
43-
}
31+
valCourseReference(course1, Sections)
4432
}
4533
courseKeys = nil
4634
log.Print("No invalid courses!")
4735

4836
log.Print("Validating sections...")
4937
sectionKeys := utils.GetMapKeys(Sections)
50-
for i := 0; i < len(sectionKeys)-1; i++ {
38+
for i := range len(sectionKeys) {
5139
section1 := Sections[sectionKeys[i]]
5240
// Check for duplicate sections by comparing section_number, course_reference, and academic_session as a compound key
5341
for j := i + 1; j < len(sectionKeys); j++ {
5442
section2 := Sections[sectionKeys[j]]
55-
if section2.Section_number == section1.Section_number &&
56-
section2.Course_reference == section1.Course_reference &&
57-
section2.Academic_session == section1.Academic_session {
58-
log.Print("Duplicate section found!")
59-
log.Printf("Section 1: %v\n\nSection 2: %v", section1, section2)
60-
log.Panic("Sections failed to validate!")
61-
}
43+
valDuplicateSections(section1, section2)
6244
}
6345
// Make sure section isn't referencing any nonexistent professors, and that section-professor references are consistent both ways
64-
for _, profId := range section1.Professors {
65-
professorKey, exists := ProfessorIDMap[profId]
66-
if !exists {
67-
log.Printf("Nonexistent professor reference found for section ID %s!", section1.Id)
68-
log.Printf("Referenced professor ID: %s", profId)
69-
log.Panic("Sections failed to validate!")
70-
}
71-
profRefsSection := false
72-
for _, profSection := range Professors[professorKey].Sections {
73-
if profSection == section1.Id {
74-
profRefsSection = true
75-
break
76-
}
77-
}
78-
if !profRefsSection {
79-
log.Printf("Inconsistent professor reference found for section ID %s! The section references the professor, but not vice-versa!", section1.Id)
80-
log.Printf("Referenced professor ID: %s", profId)
81-
log.Panic("Sections failed to validate!")
82-
}
83-
}
46+
valSectionReferenceProf(section1, Professors, ProfessorIDMap)
47+
8448
// Make sure section isn't referencing a nonexistant course
85-
_, exists := CourseIDMap[section1.Course_reference]
86-
if !exists {
87-
log.Printf("Nonexistent course reference found for section ID %s!", section1.Id)
88-
log.Printf("Referenced course ID: %s", section1.Course_reference)
89-
log.Panic("Sections failed to validate!")
90-
}
49+
valSectionReferenceCourse(section1, CourseIDMap)
9150
}
9251
sectionKeys = nil
9352
log.Printf("No invalid sections!")
9453

9554
log.Printf("Validating professors...")
9655
profKeys := utils.GetMapKeys(Professors)
9756
// Check for duplicate professors by comparing first_name, last_name, and sections as a compound key
98-
for i := 0; i < len(profKeys)-1; i++ {
57+
for i := range len(profKeys) {
9958
prof1 := Professors[profKeys[i]]
10059
for j := i + 1; j < len(profKeys); j++ {
10160
prof2 := Professors[profKeys[j]]
102-
if prof2.First_name == prof1.First_name &&
103-
prof2.Last_name == prof1.Last_name &&
104-
prof2.Profile_uri == prof1.Profile_uri {
105-
log.Printf("Duplicate professor found!")
106-
log.Printf("Professor 1: %v\n\nProfessor 2: %v", prof1, prof2)
107-
log.Panic("Professors failed to validate!")
108-
}
61+
valDuplicateProfs(prof1, prof2)
10962
}
11063
}
11164
log.Printf("No invalid professors!")
11265
}
66+
67+
// Validate if the courses are duplicate
68+
func valDuplicateCourses(course1 *schema.Course, course2 *schema.Course) {
69+
if course1.Catalog_year == course2.Catalog_year && course1.Course_number == course2.Course_number &&
70+
course1.Subject_prefix == course2.Subject_prefix {
71+
log.Printf("Duplicate course found for %s%s!", course1.Subject_prefix, course1.Course_number)
72+
log.Printf("Course 1: %v\n\nCourse 2: %v", course1, course2)
73+
log.Panic("Courses failed to validate!")
74+
}
75+
}
76+
77+
// Validate course reference to sections
78+
func valCourseReference(course *schema.Course, sections map[primitive.ObjectID]*schema.Section) {
79+
for _, sectionID := range course.Sections {
80+
section, exists := sections[sectionID]
81+
// validate if course references to some section not in the parsed sections
82+
if !exists {
83+
log.Printf("Nonexistent section reference found for %s%s!", course.Subject_prefix, course.Course_number)
84+
log.Printf("Referenced section ID: %s\nCourse ID: %s", sectionID, course.Id)
85+
log.Panic("Courses failed to validate!")
86+
}
87+
88+
// validate if the ref sections references back to the course
89+
if section.Course_reference != course.Id {
90+
log.Printf("Inconsistent section reference found for %s%s! The course references the section, but not vice-versa!", course.Subject_prefix, course.Course_number)
91+
log.Printf("Referenced section ID: %s\nCourse ID: %s\nSection course reference: %s", sectionID, course.Id, section.Course_reference)
92+
log.Panic("Courses failed to validate!")
93+
}
94+
}
95+
}
96+
97+
// Validate if the sections are duplicate
98+
func valDuplicateSections(section1 *schema.Section, section2 *schema.Section) {
99+
if section1.Section_number == section2.Section_number && section1.Course_reference == section2.Course_reference &&
100+
section1.Academic_session == section2.Academic_session {
101+
log.Print("Duplicate section found!")
102+
log.Printf("Section 1: %v\n\nSection 2: %v", section1, section2)
103+
log.Panic("Sections failed to validate!")
104+
}
105+
}
106+
107+
// Validate section reference to professor
108+
func valSectionReferenceProf(section *schema.Section, profs map[string]*schema.Professor, profIDMap map[primitive.ObjectID]string) {
109+
for _, profID := range section.Professors {
110+
professorKey, exists := profIDMap[profID]
111+
// validate if the section references to some prof not in the parsed professors
112+
if !exists {
113+
log.Printf("Nonexistent professor reference found for section ID %s!", section.Id)
114+
log.Printf("Referenced professor ID: %s", profID)
115+
log.Panic("Sections failed to validate!")
116+
}
117+
118+
// validate if the referenced professor references back to section
119+
if !slices.Contains(profs[professorKey].Sections, section.Id) {
120+
log.Printf("Inconsistent professor reference found for section ID %s! The section references the professor, but not vice-versa!", section.Id)
121+
log.Printf("Referenced professor ID: %s", profID)
122+
log.Panic("Sections failed to validate!")
123+
}
124+
}
125+
}
126+
127+
// Validate section reference to course
128+
func valSectionReferenceCourse(section *schema.Section, courseIDMap map[primitive.ObjectID]string) {
129+
_, exists := courseIDMap[section.Course_reference]
130+
// validate if section reference some course not in parsed courses
131+
if !exists {
132+
log.Printf("Nonexistent course reference found for section ID %s!", section.Id)
133+
log.Printf("Referenced course ID: %s", section.Course_reference)
134+
log.Panic("Sections failed to validate!")
135+
}
136+
}
137+
138+
// Validate if the professors are duplicate
139+
func valDuplicateProfs(prof1 *schema.Professor, prof2 *schema.Professor) {
140+
if prof1.First_name == prof2.First_name && prof1.Last_name == prof2.Last_name && prof1.Profile_uri == prof2.Profile_uri {
141+
log.Printf("Duplicate professor found!")
142+
log.Printf("Professor 1: %v\n\nProfessor 2: %v", prof1, prof2)
143+
log.Panic("Professors failed to validate!")
144+
}
145+
}

0 commit comments

Comments
 (0)