Files
breakpilot-lehrer/edu-search-service/internal/staff/staff_crawler_test.go
Benjamin Boenisch 414e0f5ec0
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 28s
CI / test-go-edu-search (push) Successful in 27s
CI / test-python-klausur (push) Successful in 1m45s
CI / test-python-agent-core (push) Successful in 16s
CI / test-nodejs-website (push) Successful in 21s
feat: edu-search-service migriert, voice-service/geo-service entfernt
- edu-search-service von breakpilot-pwa nach breakpilot-lehrer kopiert (ohne vendor)
- opensearch + edu-search-service in docker-compose.yml hinzugefuegt
- voice-service aus docker-compose.yml entfernt (jetzt in breakpilot-core)
- geo-service aus docker-compose.yml entfernt (nicht mehr benoetigt)
- CI/CD: edu-search-service zu Gitea Actions und Woodpecker hinzugefuegt
  (Go lint, test mit go mod download, build, SBOM)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:36:38 +01:00

349 lines
8.2 KiB
Go

package staff
import (
"testing"
"github.com/breakpilot/edu-search-service/internal/database"
)
func TestParseName_FullName_WithTitle(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
fullName string
expectedFirst string
expectedLast string
expectedTitle bool
}{
{
name: "Prof. Dr. with first and last name",
fullName: "Prof. Dr. Hans Müller",
expectedFirst: "Hans",
expectedLast: "Müller",
expectedTitle: true,
},
{
name: "Dr. with first and last name",
fullName: "Dr. Maria Schmidt",
expectedFirst: "Maria",
expectedLast: "Schmidt",
expectedTitle: true,
},
{
name: "Simple name without title",
fullName: "Thomas Weber",
expectedFirst: "Thomas",
expectedLast: "Weber",
expectedTitle: false,
},
{
name: "Multiple first names",
fullName: "Prof. Dr. Hans-Peter Meier",
expectedFirst: "Hans-Peter",
expectedLast: "Meier",
expectedTitle: true,
},
{
name: "Single name",
fullName: "Müller",
expectedFirst: "",
expectedLast: "Müller",
expectedTitle: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
person := &database.UniversityStaff{}
crawler.parseName(tt.fullName, person)
firstName := ""
if person.FirstName != nil {
firstName = *person.FirstName
}
if firstName != tt.expectedFirst {
t.Errorf("First name: expected %q, got %q", tt.expectedFirst, firstName)
}
if person.LastName != tt.expectedLast {
t.Errorf("Last name: expected %q, got %q", tt.expectedLast, person.LastName)
}
hasTitle := person.Title != nil && *person.Title != ""
if hasTitle != tt.expectedTitle {
t.Errorf("Has title: expected %v, got %v", tt.expectedTitle, hasTitle)
}
})
}
}
func TestClassifyPosition_Professor(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
expected string
}{
{"Full Professor", "Professor für Informatik", "professor"},
{"Prof abbreviation", "Prof. Dr. Müller", "professor"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.classifyPosition(tt.position)
if result == nil {
t.Errorf("Expected %q, got nil for position %q", tt.expected, tt.position)
return
}
if *result != tt.expected {
t.Errorf("Expected %q, got %q for position %q", tt.expected, *result, tt.position)
}
})
}
}
func TestClassifyPosition_Postdoc(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
expected string
}{
{"Postdoc", "Postdoc in Machine Learning", "postdoc"},
{"Post-Doc hyphenated", "Post-Doc", "postdoc"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.classifyPosition(tt.position)
if result == nil {
t.Errorf("Expected %q, got nil for position %q", tt.expected, tt.position)
return
}
if *result != tt.expected {
t.Errorf("Expected %q, got %q for position %q", tt.expected, *result, tt.position)
}
})
}
}
func TestClassifyPosition_PhDStudent(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
expected string
}{
{"Doktorand", "Doktorand", "phd_student"},
{"PhD Student", "PhD Student", "phd_student"},
{"Promovend", "Promovend", "phd_student"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.classifyPosition(tt.position)
if result == nil {
t.Errorf("Expected %q, got nil for position %q", tt.expected, tt.position)
return
}
if *result != tt.expected {
t.Errorf("Expected %q, got %q for position %q", tt.expected, *result, tt.position)
}
})
}
}
func TestClassifyPosition_Admin(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
expected string
}{
{"Sekretariat", "Sekretärin", "admin"},
{"Verwaltung", "Verwaltung", "admin"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.classifyPosition(tt.position)
if result == nil {
t.Errorf("Expected %q, got nil for position %q", tt.expected, tt.position)
return
}
if *result != tt.expected {
t.Errorf("Expected %q, got %q for position %q", tt.expected, *result, tt.position)
}
})
}
}
func TestClassifyPosition_Researcher(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
expected string
}{
{"Wissenschaftlicher Mitarbeiter", "Wissenschaftlicher Mitarbeiter", "researcher"},
{"Researcher", "Senior Researcher", "researcher"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.classifyPosition(tt.position)
if result == nil {
t.Errorf("Expected %q, got nil for position %q", tt.expected, tt.position)
return
}
if *result != tt.expected {
t.Errorf("Expected %q, got %q for position %q", tt.expected, *result, tt.position)
}
})
}
}
func TestClassifyPosition_Student(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
expected string
}{
{"Studentische Hilfskraft", "Studentische Hilfskraft", "student"},
{"HiWi", "Student (HiWi)", "student"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.classifyPosition(tt.position)
if result == nil {
t.Errorf("Expected %q, got nil for position %q", tt.expected, tt.position)
return
}
if *result != tt.expected {
t.Errorf("Expected %q, got %q for position %q", tt.expected, *result, tt.position)
}
})
}
}
func TestIsProfessor_True(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
}{
{"Professor keyword", "Professor für Mathematik"},
{"Prof. abbreviation", "Prof. Dr. Müller"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.isProfessor(tt.position)
if !result {
t.Errorf("Expected true for position=%q", tt.position)
}
})
}
}
func TestIsProfessor_False(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
position string
}{
{"Dr. only", "Dr. Wissenschaftlicher Mitarbeiter"},
{"Doktorand", "Doktorand"},
{"Technical staff", "Laboringenieur"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.isProfessor(tt.position)
if result {
t.Errorf("Expected false for position=%q", tt.position)
}
})
}
}
func TestLooksLikePosition_True(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
text string
}{
{"Professor", "Professor für Informatik"},
{"Wissenschaftlicher Mitarbeiter", "Wissenschaftlicher Mitarbeiter"},
{"Doktorand", "Doktorand"},
{"Sekretär", "Sekretärin"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.looksLikePosition(tt.text)
if !result {
t.Errorf("Expected true for text=%q", tt.text)
}
})
}
}
func TestLooksLikePosition_False(t *testing.T) {
crawler := &StaffCrawler{}
tests := []struct {
name string
text string
}{
{"Name", "Hans Müller"},
{"Email", "test@example.com"},
{"Random text", "Room 123"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := crawler.looksLikePosition(tt.text)
if result {
t.Errorf("Expected false for text=%q", tt.text)
}
})
}
}
func TestResolveURL(t *testing.T) {
tests := []struct {
name string
baseURL string
href string
expected string
}{
{"Absolute URL", "https://example.com", "https://other.com/page", "https://other.com/page"},
{"Relative path", "https://example.com/team", "/person/123", "https://example.com/person/123"},
{"Relative no slash", "https://example.com/team/", "member", "https://example.com/team/member"},
{"Empty href", "https://example.com", "", ""},
{"Root relative", "https://example.com/a/b/c", "/root", "https://example.com/root"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := resolveURL(tt.baseURL, tt.href)
if result != tt.expected {
t.Errorf("resolveURL(%q, %q) = %q, expected %q",
tt.baseURL, tt.href, result, tt.expected)
}
})
}
}