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>
343 lines
8.8 KiB
Go
343 lines
8.8 KiB
Go
package session
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestSessionHasPermission(t *testing.T) {
|
|
session := &Session{
|
|
SessionID: "test-session-id",
|
|
UserID: "test-user-id",
|
|
Email: "test@example.com",
|
|
UserType: UserTypeEmployee,
|
|
Permissions: []string{"grades:read", "grades:write", "attendance:read"},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
permission string
|
|
expected bool
|
|
}{
|
|
{"has grades:read", "grades:read", true},
|
|
{"has grades:write", "grades:write", true},
|
|
{"missing users:manage", "users:manage", false},
|
|
{"empty permission", "", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := session.HasPermission(tt.permission)
|
|
if result != tt.expected {
|
|
t.Errorf("HasPermission(%q) = %v, want %v", tt.permission, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSessionHasAnyPermission(t *testing.T) {
|
|
session := &Session{
|
|
SessionID: "test-session-id",
|
|
UserID: "test-user-id",
|
|
Email: "test@example.com",
|
|
UserType: UserTypeEmployee,
|
|
Permissions: []string{"grades:read"},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
permissions []string
|
|
expected bool
|
|
}{
|
|
{"has one of the permissions", []string{"grades:read", "grades:write"}, true},
|
|
{"missing all permissions", []string{"users:manage", "audit:read"}, false},
|
|
{"empty list", []string{}, false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := session.HasAnyPermission(tt.permissions)
|
|
if result != tt.expected {
|
|
t.Errorf("HasAnyPermission(%v) = %v, want %v", tt.permissions, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSessionHasAllPermissions(t *testing.T) {
|
|
session := &Session{
|
|
SessionID: "test-session-id",
|
|
UserID: "test-user-id",
|
|
Email: "test@example.com",
|
|
UserType: UserTypeEmployee,
|
|
Permissions: []string{"grades:read", "grades:write", "attendance:read"},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
permissions []string
|
|
expected bool
|
|
}{
|
|
{"has all permissions", []string{"grades:read", "grades:write"}, true},
|
|
{"missing one permission", []string{"grades:read", "users:manage"}, false},
|
|
{"empty list", []string{}, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := session.HasAllPermissions(tt.permissions)
|
|
if result != tt.expected {
|
|
t.Errorf("HasAllPermissions(%v) = %v, want %v", tt.permissions, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSessionHasRole(t *testing.T) {
|
|
session := &Session{
|
|
SessionID: "test-session-id",
|
|
UserID: "test-user-id",
|
|
Email: "test@example.com",
|
|
UserType: UserTypeEmployee,
|
|
Roles: []string{"teacher", "klassenlehrer"},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
role string
|
|
expected bool
|
|
}{
|
|
{"has teacher role", "teacher", true},
|
|
{"has klassenlehrer role", "klassenlehrer", true},
|
|
{"missing admin role", "admin", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := session.HasRole(tt.role)
|
|
if result != tt.expected {
|
|
t.Errorf("HasRole(%q) = %v, want %v", tt.role, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSessionIsEmployee(t *testing.T) {
|
|
employeeSession := &Session{
|
|
SessionID: "test",
|
|
UserID: "test",
|
|
Email: "test@test.com",
|
|
UserType: UserTypeEmployee,
|
|
}
|
|
|
|
customerSession := &Session{
|
|
SessionID: "test",
|
|
UserID: "test",
|
|
Email: "test@test.com",
|
|
UserType: UserTypeCustomer,
|
|
}
|
|
|
|
if !employeeSession.IsEmployee() {
|
|
t.Error("Employee session should return true for IsEmployee()")
|
|
}
|
|
if employeeSession.IsCustomer() {
|
|
t.Error("Employee session should return false for IsCustomer()")
|
|
}
|
|
if !customerSession.IsCustomer() {
|
|
t.Error("Customer session should return true for IsCustomer()")
|
|
}
|
|
if customerSession.IsEmployee() {
|
|
t.Error("Customer session should return false for IsEmployee()")
|
|
}
|
|
}
|
|
|
|
func TestDetermineUserType(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
roles []string
|
|
expected UserType
|
|
}{
|
|
{"teacher is employee", []string{"teacher"}, UserTypeEmployee},
|
|
{"admin is employee", []string{"admin"}, UserTypeEmployee},
|
|
{"klassenlehrer is employee", []string{"klassenlehrer"}, UserTypeEmployee},
|
|
{"parent is customer", []string{"parent"}, UserTypeCustomer},
|
|
{"student is customer", []string{"student"}, UserTypeCustomer},
|
|
{"employee takes precedence", []string{"teacher", "parent"}, UserTypeEmployee},
|
|
{"unknown role defaults to customer", []string{"unknown_role"}, UserTypeCustomer},
|
|
{"empty roles defaults to customer", []string{}, UserTypeCustomer},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := DetermineUserType(tt.roles)
|
|
if result != tt.expected {
|
|
t.Errorf("DetermineUserType(%v) = %v, want %v", tt.roles, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetPermissionsForRoles(t *testing.T) {
|
|
t.Run("employee gets employee permissions", func(t *testing.T) {
|
|
permissions := GetPermissionsForRoles([]string{"teacher"}, UserTypeEmployee)
|
|
|
|
hasGradesRead := false
|
|
for _, p := range permissions {
|
|
if p == "grades:read" {
|
|
hasGradesRead = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !hasGradesRead {
|
|
t.Error("Employee should have grades:read permission")
|
|
}
|
|
})
|
|
|
|
t.Run("customer gets customer permissions", func(t *testing.T) {
|
|
permissions := GetPermissionsForRoles([]string{"parent"}, UserTypeCustomer)
|
|
|
|
hasChildrenRead := false
|
|
for _, p := range permissions {
|
|
if p == "children:read" {
|
|
hasChildrenRead = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !hasChildrenRead {
|
|
t.Error("Customer should have children:read permission")
|
|
}
|
|
})
|
|
|
|
t.Run("admin gets admin permissions", func(t *testing.T) {
|
|
permissions := GetPermissionsForRoles([]string{"admin"}, UserTypeEmployee)
|
|
|
|
hasUsersManage := false
|
|
for _, p := range permissions {
|
|
if p == "users:manage" {
|
|
hasUsersManage = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !hasUsersManage {
|
|
t.Error("Admin should have users:manage permission")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestCheckResourceOwnership(t *testing.T) {
|
|
userID := "user-123"
|
|
adminSession := &Session{
|
|
SessionID: "test",
|
|
UserID: "admin-456",
|
|
Email: "admin@test.com",
|
|
UserType: UserTypeEmployee,
|
|
Roles: []string{"admin"},
|
|
}
|
|
regularSession := &Session{
|
|
SessionID: "test",
|
|
UserID: userID,
|
|
Email: "user@test.com",
|
|
UserType: UserTypeEmployee,
|
|
Roles: []string{"teacher"},
|
|
}
|
|
otherSession := &Session{
|
|
SessionID: "test",
|
|
UserID: "other-789",
|
|
Email: "other@test.com",
|
|
UserType: UserTypeEmployee,
|
|
Roles: []string{"teacher"},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
session *Session
|
|
resourceUID string
|
|
allowAdmin bool
|
|
expected bool
|
|
}{
|
|
{"owner can access", regularSession, userID, true, true},
|
|
{"admin can access with allowAdmin", adminSession, userID, true, true},
|
|
{"admin cannot access without allowAdmin", adminSession, userID, false, false},
|
|
{"other user cannot access", otherSession, userID, true, false},
|
|
{"nil session returns false", nil, userID, true, false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := CheckResourceOwnership(tt.session, tt.resourceUID, tt.allowAdmin)
|
|
if result != tt.expected {
|
|
t.Errorf("CheckResourceOwnership() = %v, want %v", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEmployeeRolesMap(t *testing.T) {
|
|
expectedRoles := []string{
|
|
"admin", "schul_admin", "teacher", "klassenlehrer",
|
|
"fachlehrer", "sekretariat", "data_protection_officer",
|
|
}
|
|
|
|
for _, role := range expectedRoles {
|
|
if !EmployeeRoles[role] {
|
|
t.Errorf("Expected employee role %q not found in EmployeeRoles map", role)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCustomerRolesMap(t *testing.T) {
|
|
expectedRoles := []string{"parent", "student", "user"}
|
|
|
|
for _, role := range expectedRoles {
|
|
if !CustomerRoles[role] {
|
|
t.Errorf("Expected customer role %q not found in CustomerRoles map", role)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPermissionSlicesNotEmpty(t *testing.T) {
|
|
if len(EmployeePermissions) == 0 {
|
|
t.Error("EmployeePermissions should not be empty")
|
|
}
|
|
if len(CustomerPermissions) == 0 {
|
|
t.Error("CustomerPermissions should not be empty")
|
|
}
|
|
if len(AdminPermissions) == 0 {
|
|
t.Error("AdminPermissions should not be empty")
|
|
}
|
|
}
|
|
|
|
func TestSessionTimestamps(t *testing.T) {
|
|
now := time.Now().UTC()
|
|
session := &Session{
|
|
SessionID: "test",
|
|
UserID: "test",
|
|
Email: "test@test.com",
|
|
UserType: UserTypeEmployee,
|
|
CreatedAt: now,
|
|
LastActivityAt: now,
|
|
}
|
|
|
|
if session.CreatedAt.IsZero() {
|
|
t.Error("CreatedAt should not be zero")
|
|
}
|
|
if session.LastActivityAt.IsZero() {
|
|
t.Error("LastActivityAt should not be zero")
|
|
}
|
|
if session.CreatedAt.After(time.Now().UTC()) {
|
|
t.Error("CreatedAt should not be in the future")
|
|
}
|
|
}
|
|
|
|
func TestUserTypeConstants(t *testing.T) {
|
|
if UserTypeEmployee != "employee" {
|
|
t.Errorf("UserTypeEmployee = %q, want %q", UserTypeEmployee, "employee")
|
|
}
|
|
if UserTypeCustomer != "customer" {
|
|
t.Errorf("UserTypeCustomer = %q, want %q", UserTypeCustomer, "customer")
|
|
}
|
|
}
|