Files
alpenwerk-hr/tests/unit/lolyo.test.ts
Andrei Laas 38e35e2ff9
Some checks failed
CI / Migrationen auf leerer Datenbank (push) Has been cancelled
CI / Lint, Typen, Tests, Build (push) Has been cancelled
Kein Formelschutz in einer Datei, die eine Maschine einliest
Das vorangestellte Hochkomma schuetzt einen Menschen, der eine CSV in Excel
oeffnet: ein Wert mit fuehrendem =, +, - oder @ waere dort sonst eine Formel.
In einer Load-Datei ist es das Gegenteil von Schutz. Jede oesterreichische
Telefonnummer beginnt mit "+", und in LOLYO stuende danach in jedem Konto
'+4366... als Nummer -- ohne dass es beim Erzeugen jemandem auffiele.

toCsv bekommt dafuer formelschutz in der CsvForm, voreingestellt an. Nur LOLYO
schaltet es ab. Die Telefonspalten von Cornerstone sind bisher leer, deshalb
bleibt die Datei dort, wie sie ist.
2026-09-28 13:47:49 +02:00

134 lines
4.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { toCsv } from "@/lib/export";
import {
anrede,
baueLolyoZeile,
LOLYO_CSV,
LOLYO_EMAIL_BESTAETIGT,
LOLYO_GRUPPE,
LOLYO_SPALTEN,
LOLYO_SPRACHE,
lolyoSpalten,
type LolyoQuelle,
} from "@/lib/lolyo";
// Die Datei legt in LOLYO Konten an. Eine falsche Spalte fällt hier nicht auf,
// sondern dort — als Konto, das niemandem gehört, oder als Zeile, die der
// Import abweist.
// Die Kopfzeile aus der Vorlage des Anbieters, Zeichen für Zeichen.
const VORGABE = "Benutzer/Code;Email;Passwort;Titel prefix;Vorname;Nachname;Title Suffix;Position;Gruppen;Telefon;Anrede;Sprache;E-Mail bestätigt";
const UUID = "8f2b1c40-9d3e-4a77-b2c1-5e6f70a81234";
const PASSWORT = "Startpasswort1!";
function person(teil: Partial<LolyoQuelle> = {}): LolyoQuelle {
return {
id: UUID,
company_email: "max.alpentest@alpenwerk-firmentest.com",
title_prefix: ["Mag."],
title_suffix: ["MBA"],
first_name: "Max",
last_name: "Alpentest",
job_title: "HR-Manager",
phone: "+4366412345678",
gender: "m",
...teil,
};
}
const zeile = (teil: Partial<LolyoQuelle> = {}) => baueLolyoZeile(person(teil), PASSWORT);
describe("Spalten", () => {
it("stehen genau so und in genau der Reihenfolge wie in der Vorlage", () => {
expect(LOLYO_SPALTEN.join(";")).toBe(VORGABE);
});
it("sind 13", () => {
expect(LOLYO_SPALTEN).toHaveLength(13);
});
it("werden alle gefüllt — keine Spalte ohne Zuordnung", () => {
const z = zeile();
for (const spalte of LOLYO_SPALTEN) {
expect(z, `Spalte "${spalte}" fehlt in der Zeile`).toHaveProperty(spalte);
}
expect(Object.keys(z).sort()).toEqual([...LOLYO_SPALTEN].sort());
});
});
describe("Die Zuordnung", () => {
it("nimmt als Benutzercode die Alpenwerk-UUID", () => {
expect(zeile()["Benutzer/Code"]).toBe(UUID);
});
it("nimmt die Firmenadresse und nie die private", () => {
// Die Datei legt Konten bei einem fremden Anbieter an. Eine Privatadresse
// hat dort nichts verloren; ohne Firmenadresse bleibt die Zelle leer.
expect(zeile().Email).toBe("max.alpentest@alpenwerk-firmentest.com");
expect(zeile({ company_email: null }).Email).toBe("");
});
it("trägt das Passwort ein, das die Route hereinreicht", () => {
expect(zeile().Passwort).toBe(PASSWORT);
});
it("setzt Titel, Name und Position aus Alpenwerk", () => {
const z = zeile();
expect(z["Titel prefix"]).toBe("Mag.");
expect(z.Vorname).toBe("Max");
expect(z.Nachname).toBe("Alpentest");
expect(z["Title Suffix"]).toBe("MBA");
expect(z.Position).toBe("HR-Manager");
});
it("fügt mehrere Titel zusammen und lässt keine zu einer leeren Zelle werden", () => {
expect(zeile({ title_prefix: ["Dr.", "Mag."] })["Titel prefix"]).toBe("Dr. Mag.");
expect(zeile({ title_prefix: [], title_suffix: [] })["Titel prefix"]).toBe("");
});
it("setzt Gruppe, Sprache und Bestätigung fest", () => {
const z = zeile();
expect(z.Gruppen).toBe(LOLYO_GRUPPE);
expect(z.Sprache).toBe(LOLYO_SPRACHE);
expect(z["E-Mail bestätigt"]).toBe(LOLYO_EMAIL_BESTAETIGT);
});
it("leitet die Anrede aus dem Geschlecht ab", () => {
expect(anrede("m")).toBe("Herr");
expect(anrede("w")).toBe("Frau");
// Lieber leer als geraten: eine falsche Anrede steht in jeder Nachricht,
// die die App verschickt.
expect(anrede("")).toBe("");
});
it("lässt eine fehlende Telefonnummer leer", () => {
expect(zeile({ phone: null }).Telefon).toBe("");
});
});
describe("Die Datei", () => {
it("ist semikolongetrennt und ohne BOM", () => {
// Das BOM hinge unsichtbar am Namen der ersten Spalte, und
// „Benutzer/Code" käme beim Einlesen in keiner Zuordnung mehr vor.
const csv = toCsv([zeile()], lolyoSpalten(), LOLYO_CSV);
expect(csv.startsWith("Benutzer/Code;")).toBe(true);
expect(csv.charCodeAt(0)).not.toBe(0xfeff);
});
it("beginnt mit der Kopfzeile der Vorlage", () => {
const csv = toCsv([], lolyoSpalten(), LOLYO_CSV);
expect(csv.split("\r\n")[0]).toBe(VORGABE);
});
it("lässt die Telefonnummer unangetastet", () => {
// Der Formelschutz von toCsv stellt jedem Wert mit führendem „+" ein
// Hochkomma voran, damit Excel ihn nicht rechnet. Diese Datei liest eine
// Maschine: dort stünde danach in **jedem** Konto `'+4366…` als Nummer,
// weil jede österreichische Nummer mit „+" beginnt.
const csv = toCsv([zeile()], lolyoSpalten(), LOLYO_CSV);
expect(csv).toContain(";+4366412345678;");
expect(csv).not.toContain("'+43");
});
});