Das Einschraenken der Downstream-Exporte gab es schon: exportHref reicht die ganze Adresszeile weiter, und ladeExportMitarbeiter wendet dieselben Kriterien an wie der Bericht daneben -- Eintritt ab, Austritt bis, Wochenstunden, Beschaeftigungsart und die uebrigen. Nur sah man es den Karten nicht an. Dort stand ausschliesslich der Status; alles andere steckt eingeklappt in "Weitere Kriterien" weiter oben. Damit sah eine Datei mit 40 Personen genauso aus wie eine mit 785. Fuer einen Bericht ist das aergerlich, fuer ein Load-File in ein Zielsystem ist es ein Datenstand, den dort niemand mehr hinterfragt: es fehlen Personen, und es sieht nicht nach einem Filter aus. Die drei Karten im Bestandsmodus zeigen jetzt Stichtag, Status, Einheit, Standort, jedes gesetzte Kriterium und die Zeilenzahl. beschreibeKriterien steht neben anzahlKriterien in derselben Datei und liest dieselben Listen -- ein neues Kriterium erscheint damit von selbst auch auf den Karten. Ein Test haelt beide gegeneinander, damit die Zahl am Aufklapper und der Text auf der Karte nicht auseinanderlaufen.
147 lines
6.0 KiB
TypeScript
147 lines
6.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
anzahlKriterien,
|
|
AUSWAHL_KRITERIEN,
|
|
beschreibeKriterien,
|
|
JANEIN_KRITERIEN,
|
|
kriterienParameter,
|
|
LEERE_CRITERIA,
|
|
parseCriteria,
|
|
passtImSpeicher,
|
|
ZEITRAUM_KRITERIEN,
|
|
} from "@/lib/report-criteria";
|
|
|
|
function aus(params: Record<string, string>) {
|
|
return parseCriteria((k) => params[k]);
|
|
}
|
|
|
|
describe("parseCriteria", () => {
|
|
it("nimmt bekannte Werte an", () => {
|
|
const c = aus({ employment: "Teilzeit", paygrade: "HG13", gender: "w" });
|
|
expect(c.auswahl).toEqual({ employment: "Teilzeit", paygrade: "HG13", gender: "w" });
|
|
});
|
|
|
|
it("verwirft Werte, die nicht in der Liste stehen", () => {
|
|
// Die Werte landen in SQL-Vergleichen und im Dateinamen des Downloads,
|
|
// also in einem Content-Disposition-Header — was nicht in der Liste
|
|
// steht, darf nicht durchkommen.
|
|
const c = aus({ employment: "Vollzeit'; drop table employees; --", paygrade: "HG21", gender: "x" });
|
|
expect(c.auswahl).toEqual({});
|
|
});
|
|
|
|
it("nimmt ja/nein an und sonst nichts", () => {
|
|
const c = aus({ dienstwagen: "ja", betriebsrat: "vielleicht", clevel: "nein" });
|
|
expect(c.jaNein).toEqual({ dienstwagen: "ja", clevel: "nein" });
|
|
});
|
|
|
|
it("prüft Zeiträume auf echte Kalenderdaten", () => {
|
|
const c = aus({ entryFrom: "2024-01-01", entryTo: "2024-02-31", exitTo: "gestern" });
|
|
// Der 31. Februar ist kein Datum, auch wenn er wie eines aussieht.
|
|
expect(c.zeitraum.entry).toEqual({ von: "2024-01-01", bis: undefined });
|
|
expect(c.zeitraum.exit).toBeUndefined();
|
|
});
|
|
|
|
it("nimmt Stunden mit Komma und weist Unsinn ab", () => {
|
|
expect(aus({ hoursFrom: "20,5" }).stundenVon).toBe(20.5);
|
|
expect(aus({ hoursFrom: "-5" }).stundenVon).toBeUndefined();
|
|
expect(aus({ hoursTo: "500" }).stundenBis).toBeUndefined();
|
|
expect(aus({ hoursTo: "keine" }).stundenBis).toBeUndefined();
|
|
});
|
|
|
|
it("liefert ohne Parameter nichts Gesetztes", () => {
|
|
expect(anzahlKriterien(aus({}))).toBe(0);
|
|
expect(anzahlKriterien(LEERE_CRITERIA)).toBe(0);
|
|
});
|
|
|
|
it("zählt jedes gesetzte Kriterium einzeln", () => {
|
|
const c = aus({ employment: "Teilzeit", dienstwagen: "ja", entryFrom: "2024-01-01", entryTo: "2024-12-31", hoursTo: "30" });
|
|
expect(anzahlKriterien(c)).toBe(5);
|
|
});
|
|
});
|
|
|
|
describe("beschreibeKriterien", () => {
|
|
it("sagt nichts, wenn nichts eingeschränkt ist", () => {
|
|
expect(beschreibeKriterien(LEERE_CRITERIA)).toEqual([]);
|
|
});
|
|
|
|
it("nennt jedes gesetzte Kriterium beim Namen", () => {
|
|
const c = aus({ employment: "Teilzeit", dienstwagen: "ja", entryFrom: "2024-01-01", hoursTo: "30" });
|
|
expect(beschreibeKriterien(c)).toEqual([
|
|
"Beschäftigungsart: Teilzeit",
|
|
"Dienstwagen: ja",
|
|
"Eintritt ab 01.01.2024",
|
|
"Wochenstunden bis 30",
|
|
]);
|
|
});
|
|
|
|
it("unterscheidet ab, bis und den geschlossenen Zeitraum", () => {
|
|
expect(beschreibeKriterien(aus({ entryFrom: "2020-06-01" }))).toEqual(["Eintritt ab 01.06.2020"]);
|
|
expect(beschreibeKriterien(aus({ entryTo: "2020-06-01" }))).toEqual(["Eintritt bis 01.06.2020"]);
|
|
expect(beschreibeKriterien(aus({ entryFrom: "2020-01-01", entryTo: "2020-12-31" }))).toEqual([
|
|
"Eintritt 01.01.2020 bis 31.12.2020",
|
|
]);
|
|
});
|
|
|
|
it("zeigt die Beschriftung, nicht den gespeicherten Wert", () => {
|
|
// Bei der Austrittsart gehen die beiden auseinander; auf der Karte nützt
|
|
// nur das, was auch im Auswahlfeld steht.
|
|
const kriterium = AUSWAHL_KRITERIEN.find((k) => k.key === "austrittsart")!;
|
|
const option = kriterium.optionen[0];
|
|
expect(beschreibeKriterien(aus({ austrittsart: option.wert }))).toEqual([`${kriterium.label}: ${option.label}`]);
|
|
});
|
|
|
|
it("beschreibt so viele Kriterien, wie anzahlKriterien zählt", () => {
|
|
// Die Zahl am Aufklapper und der Text auf der Exportkarte dürfen nicht
|
|
// auseinanderlaufen: sonst meldet die eine Stelle eine Einschränkung, die
|
|
// die andere nicht benennt.
|
|
const alle = {
|
|
...Object.fromEntries(AUSWAHL_KRITERIEN.map((k) => [k.key, k.optionen[0].wert])),
|
|
...Object.fromEntries(JANEIN_KRITERIEN.map((k) => [k.key, "ja"])),
|
|
...Object.fromEntries(ZEITRAUM_KRITERIEN.map((k) => [`${k.key}From`, "2024-01-01"])),
|
|
hoursFrom: "10",
|
|
};
|
|
const c = aus(alle);
|
|
expect(beschreibeKriterien(c)).toHaveLength(anzahlKriterien(c));
|
|
});
|
|
});
|
|
|
|
describe("kriterienParameter", () => {
|
|
it("nennt jeden Parameter, den parseCriteria liest", () => {
|
|
// „Zurücksetzen" räumt anhand dieser Liste auf. Fehlt darin ein Name,
|
|
// bleibt ein unsichtbares Kriterium in der Adresszeile stehen und
|
|
// schränkt den Export weiter ein, ohne dass es jemand sieht.
|
|
const namen = kriterienParameter();
|
|
const alle = {
|
|
...Object.fromEntries(AUSWAHL_KRITERIEN.map((k) => [k.key, k.optionen[0].wert])),
|
|
...Object.fromEntries(JANEIN_KRITERIEN.map((k) => [k.key, "ja"])),
|
|
...Object.fromEntries(ZEITRAUM_KRITERIEN.flatMap((k) => [[`${k.key}From`, "2024-01-01"], [`${k.key}To`, "2024-12-31"]])),
|
|
hoursFrom: "10",
|
|
hoursTo: "38.5",
|
|
};
|
|
expect(anzahlKriterien(aus(alle))).toBeGreaterThan(0);
|
|
|
|
const uebrig = aus(Object.fromEntries(Object.entries(alle).filter(([k]) => !namen.includes(k))));
|
|
expect(anzahlKriterien(uebrig)).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe("passtImSpeicher", () => {
|
|
const zeile = { work_days: ["Mo", "Di", "Mi"], dependentsCount: 2 };
|
|
|
|
it("lässt ohne Kriterien alles durch", () => {
|
|
expect(passtImSpeicher(zeile, LEERE_CRITERIA)).toBe(true);
|
|
});
|
|
|
|
it("prüft den Wochentag gegen die Arbeitstage", () => {
|
|
expect(passtImSpeicher(zeile, aus({ weekday: "Di" }))).toBe(true);
|
|
expect(passtImSpeicher(zeile, aus({ weekday: "Fr" }))).toBe(false);
|
|
});
|
|
|
|
it("unterscheidet mit und ohne Angehörige", () => {
|
|
expect(passtImSpeicher(zeile, aus({ dependents: "ja" }))).toBe(true);
|
|
expect(passtImSpeicher(zeile, aus({ dependents: "nein" }))).toBe(false);
|
|
expect(passtImSpeicher({ ...zeile, dependentsCount: 0 }, aus({ dependents: "nein" }))).toBe(true);
|
|
expect(passtImSpeicher({ ...zeile, dependentsCount: 0 }, aus({ dependents: "ja" }))).toBe(false);
|
|
});
|
|
});
|