Schließt den zweiten Punkt der geplanten Onboarding-Reihenfolge. Admin lädt eine CSV mit Spalten email (Pflicht) und role (optional, Standard mitarbeiter) unter GET /verwaltung/nutzer/import hoch. Wie beim einzelnen Nutzer-Anlegen gibt es keine Einladungsmail — pro Zeile wird ein Einmalpasswort erzeugt und nur auf der Ergebnisseite direkt nach dem Import angezeigt, danach nirgendwo mehr abrufbar. Kein Alles-oder-nichts-Import: eine ungültige Zeile blockiert nicht die übrigen, jede Zeile bekommt ihr eigenes Ergebnis. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
65 lines
2.0 KiB
Go
65 lines
2.0 KiB
Go
package web
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseCSVMitarbeiterMitRolle(t *testing.T) {
|
|
csv := "email,role\nlisa@example.com,verantwortlicher\ntom@example.com,\n"
|
|
zeilen, err := parseCSVMitarbeiter(strings.NewReader(csv))
|
|
if err != nil {
|
|
t.Fatalf("parseCSVMitarbeiter: %v", err)
|
|
}
|
|
if len(zeilen) != 2 {
|
|
t.Fatalf("zeilen = %+v, want 2", zeilen)
|
|
}
|
|
if zeilen[0].Email != "lisa@example.com" || zeilen[0].Role != "verantwortlicher" {
|
|
t.Errorf("zeilen[0] = %+v, unerwartet", zeilen[0])
|
|
}
|
|
if zeilen[1].Email != "tom@example.com" || zeilen[1].Role != "mitarbeiter" {
|
|
t.Errorf("zeilen[1] = %+v, want default role mitarbeiter", zeilen[1])
|
|
}
|
|
}
|
|
|
|
func TestParseCSVMitarbeiterOhneRollenspalte(t *testing.T) {
|
|
csv := "email\nlisa@example.com\n"
|
|
zeilen, err := parseCSVMitarbeiter(strings.NewReader(csv))
|
|
if err != nil {
|
|
t.Fatalf("parseCSVMitarbeiter: %v", err)
|
|
}
|
|
if len(zeilen) != 1 || zeilen[0].Role != "mitarbeiter" {
|
|
t.Fatalf("zeilen = %+v, unerwartet", zeilen)
|
|
}
|
|
}
|
|
|
|
func TestParseCSVMitarbeiterUeberspringtLeereEmail(t *testing.T) {
|
|
csv := "email,role\n,mitarbeiter\nlisa@example.com,mitarbeiter\n"
|
|
zeilen, err := parseCSVMitarbeiter(strings.NewReader(csv))
|
|
if err != nil {
|
|
t.Fatalf("parseCSVMitarbeiter: %v", err)
|
|
}
|
|
if len(zeilen) != 1 || zeilen[0].Email != "lisa@example.com" {
|
|
t.Fatalf("zeilen = %+v, want exactly lisa@example.com", zeilen)
|
|
}
|
|
}
|
|
|
|
func TestParseCSVMitarbeiterOhneEmailSpalteSchlaegtFehl(t *testing.T) {
|
|
csv := "name,role\nLisa,mitarbeiter\n"
|
|
_, err := parseCSVMitarbeiter(strings.NewReader(csv))
|
|
if err == nil {
|
|
t.Fatal("expected an error when the header has no email column")
|
|
}
|
|
}
|
|
|
|
func TestParseCSVMitarbeiterZeilennummernZaehlenKopfzeileAlsEins(t *testing.T) {
|
|
csv := "email\nlisa@example.com\ntom@example.com\n"
|
|
zeilen, err := parseCSVMitarbeiter(strings.NewReader(csv))
|
|
if err != nil {
|
|
t.Fatalf("parseCSVMitarbeiter: %v", err)
|
|
}
|
|
if len(zeilen) != 2 || zeilen[0].Zeile != 2 || zeilen[1].Zeile != 3 {
|
|
t.Fatalf("zeilen = %+v, want Zeile 2 and 3", zeilen)
|
|
}
|
|
}
|