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") } }