This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/consent-service/internal/services/school_service_test.go
Benjamin Admin 21a844cb8a 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>
2026-02-09 09:51:32 +01:00

425 lines
9.2 KiB
Go

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
}