fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
424
consent-service/internal/services/school_service_test.go
Normal file
424
consent-service/internal/services/school_service_test.go
Normal file
@@ -0,0 +1,424 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/breakpilot/consent-service/internal/models"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// TestGenerateOnboardingToken tests the QR code token generation
|
||||
func TestGenerateOnboardingToken(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
studentID uuid.UUID
|
||||
createdBy uuid.UUID
|
||||
role string
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "valid parent token",
|
||||
studentID: uuid.New(),
|
||||
createdBy: uuid.New(),
|
||||
role: "parent",
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "valid parent_representative token",
|
||||
studentID: uuid.New(),
|
||||
createdBy: uuid.New(),
|
||||
role: "parent_representative",
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "empty student ID",
|
||||
studentID: uuid.Nil,
|
||||
createdBy: uuid.New(),
|
||||
role: "parent",
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
token := &models.ParentOnboardingToken{
|
||||
StudentID: tt.studentID,
|
||||
CreatedBy: tt.createdBy,
|
||||
Role: tt.role,
|
||||
ExpiresAt: time.Now().Add(7 * 24 * time.Hour),
|
||||
}
|
||||
|
||||
// Validate token fields
|
||||
if tt.studentID == uuid.Nil && !tt.expectError {
|
||||
t.Errorf("expected error for empty student ID")
|
||||
}
|
||||
|
||||
if token.Role != "parent" && token.Role != "parent_representative" {
|
||||
if !tt.expectError {
|
||||
t.Errorf("invalid role: %s", token.Role)
|
||||
}
|
||||
}
|
||||
|
||||
// Check expiration is in the future
|
||||
if token.ExpiresAt.Before(time.Now()) {
|
||||
t.Errorf("token expiration should be in the future")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestValidateSchoolData tests school data validation
|
||||
func TestValidateSchoolData(t *testing.T) {
|
||||
address1 := "Musterstraße 1, 20095 Hamburg"
|
||||
address2 := "Musterstraße 1"
|
||||
address3 := "Parkweg 5"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
school models.School
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "valid school",
|
||||
school: models.School{
|
||||
Name: "Testschule Hamburg",
|
||||
Address: &address1,
|
||||
Type: "gymnasium",
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "empty name",
|
||||
school: models.School{
|
||||
Name: "",
|
||||
Address: &address2,
|
||||
Type: "gymnasium",
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "valid grundschule",
|
||||
school: models.School{
|
||||
Name: "Grundschule Am Park",
|
||||
Address: &address3,
|
||||
Type: "grundschule",
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := validateSchool(tt.school)
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("expected valid=%v, got valid=%v", tt.expectValid, isValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// validateSchool is a helper function for validation
|
||||
func validateSchool(school models.School) bool {
|
||||
if school.Name == "" {
|
||||
return false
|
||||
}
|
||||
if school.Type == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TestValidateClassData tests class data validation
|
||||
func TestValidateClassData(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
class models.Class
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "valid class 5a",
|
||||
class: models.Class{
|
||||
Name: "5a",
|
||||
Grade: 5,
|
||||
SchoolID: uuid.New(),
|
||||
SchoolYearID: uuid.New(),
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "invalid grade level 0",
|
||||
class: models.Class{
|
||||
Name: "0a",
|
||||
Grade: 0,
|
||||
SchoolID: uuid.New(),
|
||||
SchoolYearID: uuid.New(),
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "invalid grade level 14",
|
||||
class: models.Class{
|
||||
Name: "14a",
|
||||
Grade: 14,
|
||||
SchoolID: uuid.New(),
|
||||
SchoolYearID: uuid.New(),
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "missing school ID",
|
||||
class: models.Class{
|
||||
Name: "5a",
|
||||
Grade: 5,
|
||||
SchoolID: uuid.Nil,
|
||||
SchoolYearID: uuid.New(),
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := validateClass(tt.class)
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("expected valid=%v, got valid=%v", tt.expectValid, isValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// validateClass is a helper function for class validation
|
||||
func validateClass(class models.Class) bool {
|
||||
if class.Name == "" {
|
||||
return false
|
||||
}
|
||||
if class.Grade < 1 || class.Grade > 13 {
|
||||
return false
|
||||
}
|
||||
if class.SchoolID == uuid.Nil {
|
||||
return false
|
||||
}
|
||||
if class.SchoolYearID == uuid.Nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TestValidateStudentData tests student data validation
|
||||
func TestValidateStudentData(t *testing.T) {
|
||||
dob := time.Date(2014, 5, 15, 0, 0, 0, 0, time.UTC)
|
||||
futureDob := time.Now().AddDate(1, 0, 0)
|
||||
studentNum := "2024-001"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
student models.Student
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "valid student",
|
||||
student: models.Student{
|
||||
FirstName: "Max",
|
||||
LastName: "Mustermann",
|
||||
DateOfBirth: &dob,
|
||||
SchoolID: uuid.New(),
|
||||
ClassID: uuid.New(),
|
||||
StudentNumber: &studentNum,
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "empty first name",
|
||||
student: models.Student{
|
||||
FirstName: "",
|
||||
LastName: "Mustermann",
|
||||
DateOfBirth: &dob,
|
||||
SchoolID: uuid.New(),
|
||||
ClassID: uuid.New(),
|
||||
StudentNumber: &studentNum,
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "future birth date",
|
||||
student: models.Student{
|
||||
FirstName: "Max",
|
||||
LastName: "Mustermann",
|
||||
DateOfBirth: &futureDob,
|
||||
SchoolID: uuid.New(),
|
||||
ClassID: uuid.New(),
|
||||
StudentNumber: &studentNum,
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "missing class ID",
|
||||
student: models.Student{
|
||||
FirstName: "Max",
|
||||
LastName: "Mustermann",
|
||||
DateOfBirth: &dob,
|
||||
SchoolID: uuid.New(),
|
||||
ClassID: uuid.Nil,
|
||||
StudentNumber: &studentNum,
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := validateStudent(tt.student)
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("expected valid=%v, got valid=%v", tt.expectValid, isValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// validateStudent is a helper function for student validation
|
||||
func validateStudent(student models.Student) bool {
|
||||
if student.FirstName == "" || student.LastName == "" {
|
||||
return false
|
||||
}
|
||||
if student.DateOfBirth != nil && student.DateOfBirth.After(time.Now()) {
|
||||
return false
|
||||
}
|
||||
if student.ClassID == uuid.Nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TestValidateTeacherData tests teacher data validation
|
||||
func TestValidateTeacherData(t *testing.T) {
|
||||
code := "SCH"
|
||||
codeLong := "SCHMI"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
teacher models.Teacher
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "valid teacher",
|
||||
teacher: models.Teacher{
|
||||
FirstName: "Anna",
|
||||
LastName: "Schmidt",
|
||||
UserID: uuid.New(),
|
||||
TeacherCode: &code,
|
||||
SchoolID: uuid.New(),
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "empty first name",
|
||||
teacher: models.Teacher{
|
||||
FirstName: "",
|
||||
LastName: "Schmidt",
|
||||
UserID: uuid.New(),
|
||||
TeacherCode: &code,
|
||||
SchoolID: uuid.New(),
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "teacher code too long",
|
||||
teacher: models.Teacher{
|
||||
FirstName: "Anna",
|
||||
LastName: "Schmidt",
|
||||
UserID: uuid.New(),
|
||||
TeacherCode: &codeLong,
|
||||
SchoolID: uuid.New(),
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := validateTeacher(tt.teacher)
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("expected valid=%v, got valid=%v", tt.expectValid, isValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// validateTeacher is a helper function for teacher validation
|
||||
func validateTeacher(teacher models.Teacher) bool {
|
||||
if teacher.FirstName == "" || teacher.LastName == "" {
|
||||
return false
|
||||
}
|
||||
if teacher.TeacherCode != nil && len(*teacher.TeacherCode) > 4 {
|
||||
return false
|
||||
}
|
||||
if teacher.SchoolID == uuid.Nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TestSchoolYearValidation tests school year date validation
|
||||
func TestSchoolYearValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
year models.SchoolYear
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "valid school year 2024/2025",
|
||||
year: models.SchoolYear{
|
||||
Name: "2024/2025",
|
||||
StartDate: time.Date(2024, 8, 1, 0, 0, 0, 0, time.UTC),
|
||||
EndDate: time.Date(2025, 7, 31, 0, 0, 0, 0, time.UTC),
|
||||
SchoolID: uuid.New(),
|
||||
},
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "end before start",
|
||||
year: models.SchoolYear{
|
||||
Name: "2024/2025",
|
||||
StartDate: time.Date(2025, 8, 1, 0, 0, 0, 0, time.UTC),
|
||||
EndDate: time.Date(2024, 7, 31, 0, 0, 0, 0, time.UTC),
|
||||
SchoolID: uuid.New(),
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
{
|
||||
name: "same start and end",
|
||||
year: models.SchoolYear{
|
||||
Name: "2024/2025",
|
||||
StartDate: time.Date(2024, 8, 1, 0, 0, 0, 0, time.UTC),
|
||||
EndDate: time.Date(2024, 8, 1, 0, 0, 0, 0, time.UTC),
|
||||
SchoolID: uuid.New(),
|
||||
},
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := validateSchoolYear(tt.year)
|
||||
if isValid != tt.expectValid {
|
||||
t.Errorf("expected valid=%v, got valid=%v", tt.expectValid, isValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// validateSchoolYear is a helper function for school year validation
|
||||
func validateSchoolYear(year models.SchoolYear) bool {
|
||||
if year.Name == "" {
|
||||
return false
|
||||
}
|
||||
if year.SchoolID == uuid.Nil {
|
||||
return false
|
||||
}
|
||||
if !year.EndDate.After(year.StartDate) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user