Lehrling, and a field that stops being named after its values
worker_type had two values because the field was named after them: "Angestellte:r / Arbeiter:in". Lehrlinge are the third social-insurance category in Austria; until now they were filed as one of the other two, which they are not -- and which skewed every report grouped by this column by exactly those people. Adding the value is one line. The label was the work: the field was called after its two values in six places, and each of them becomes wrong with a third. They now read "Beschaeftigtengruppe", the name the import has used all along. One label deliberately keeps the old wording: app_feld_karte() in the database. That string is not a caption there but a key -- stored rows in employee_history and pending_changes carry it, and the map is how reverting or correcting a history entry finds the field again. Renaming it without rewriting those rows would make every older entry for this field unrevertable, and nobody would notice until they tried. The migration's assertion reads pg_enum rather than comparing against 'Lehrling'::worker_type: migrations run inside a transaction, and Postgres refuses to use a freshly added enum value in the transaction that added it. This has not been run against a live database here -- the CI migration job is the first real execution. Three hand-kept lists of the same enum (reports, import, the form) now have a test holding them to one another, each mutation-checked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -144,7 +144,7 @@ function employeeExportColumns(
|
|||||||
{ header: "Arbeitstage", get: (e) => [...e.work_days].sort((a, b) => WEEKDAY_ORDER.indexOf(a as Weekday) - WEEKDAY_ORDER.indexOf(b as Weekday)).join(", ") },
|
{ header: "Arbeitstage", get: (e) => [...e.work_days].sort((a, b) => WEEKDAY_ORDER.indexOf(a as Weekday) - WEEKDAY_ORDER.indexOf(b as Weekday)).join(", ") },
|
||||||
{ header: "Vertragsart", get: (e) => e.contract_type },
|
{ header: "Vertragsart", get: (e) => e.contract_type },
|
||||||
{ header: "Befristet bis", get: (e) => e.contract_end_date, kind: "date" },
|
{ header: "Befristet bis", get: (e) => e.contract_end_date, kind: "date" },
|
||||||
{ header: "Angestellte:r / Arbeiter:in", get: (e) => e.worker_type },
|
{ header: "Beschäftigtengruppe", get: (e) => e.worker_type },
|
||||||
{ header: "Kollektivvertrag", get: (e) => e.collective_agreement },
|
{ header: "Kollektivvertrag", get: (e) => e.collective_agreement },
|
||||||
{ header: "Betriebsrat", get: (e) => e.is_betriebsrat },
|
{ header: "Betriebsrat", get: (e) => e.is_betriebsrat },
|
||||||
{ header: "Dienstwagen", get: (e) => e.has_dienstwagen },
|
{ header: "Dienstwagen", get: (e) => e.has_dienstwagen },
|
||||||
|
|||||||
@@ -42,14 +42,18 @@ export function RoleEmploymentFields({ value, onChange }: { value: RoleEmploymen
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||||
|
{/* „Beschäftigtengruppe" statt „Angestellte:r / Arbeiter:in": ein
|
||||||
|
Feld, das nach seinen Werten heisst, wird falsch, sobald ein
|
||||||
|
dritter dazukommt. Den Namen führt der Import schon länger. */}
|
||||||
<SelectField
|
<SelectField
|
||||||
label="Angestellte:r / Arbeiter:in"
|
label="Beschäftigtengruppe"
|
||||||
dense
|
dense
|
||||||
value={value.workerType}
|
value={value.workerType}
|
||||||
onChange={(v) => onChange({ workerType: v as WorkerType })}
|
onChange={(v) => onChange({ workerType: v as WorkerType })}
|
||||||
options={[
|
options={[
|
||||||
{ value: "Angestellte:r", label: "Angestellte:r" },
|
{ value: "Angestellte:r", label: "Angestellte:r" },
|
||||||
{ value: "Arbeiter:in", label: "Arbeiter:in" },
|
{ value: "Arbeiter:in", label: "Arbeiter:in" },
|
||||||
|
{ value: "Lehrling", label: "Lehrling" },
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<SelectField
|
<SelectField
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export function VertragTab({ employee }: { employee: EmployeeRow }) {
|
|||||||
["Wochenstunden", `${employee.weekly_hours} h`],
|
["Wochenstunden", `${employee.weekly_hours} h`],
|
||||||
["Urlaubsanspruch", "25 Tage"],
|
["Urlaubsanspruch", "25 Tage"],
|
||||||
["Paygrade", PAYGRADE_LABELS[employee.paygrade] ?? employee.paygrade],
|
["Paygrade", PAYGRADE_LABELS[employee.paygrade] ?? employee.paygrade],
|
||||||
["Angestellte:r / Arbeiter:in", employee.worker_type ?? "–"],
|
["Beschäftigtengruppe", employee.worker_type ?? "–"],
|
||||||
["Arbeitstage", employee.work_days?.join(", ") || "–"],
|
["Arbeitstage", employee.work_days?.join(", ") || "–"],
|
||||||
// Beim Dienstwagen steht die Antriebsart statt eines blossen „Ja" — das
|
// Beim Dienstwagen steht die Antriebsart statt eines blossen „Ja" — das
|
||||||
// war die Frage dahinter, seit E-Fahrzeuge getrennt zu führen sind.
|
// war die Frage dahinter, seit E-Fahrzeuge getrennt zu führen sind.
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function StepSummary({ draft, selectedPosition, locations }: StepSummaryP
|
|||||||
["Vertragsart", draft.contractType === "befristet" ? `befristet bis ${fmtDate(draft.contractEndDate)}` : "unbefristet"],
|
["Vertragsart", draft.contractType === "befristet" ? `befristet bis ${fmtDate(draft.contractEndDate)}` : "unbefristet"],
|
||||||
["Beschäftigungsausmaß", `${draft.employmentType} (${draft.weeklyHours} h)`],
|
["Beschäftigungsausmaß", `${draft.employmentType} (${draft.weeklyHours} h)`],
|
||||||
["Paygrade", PAYGRADE_LABELS[draft.paygrade]],
|
["Paygrade", PAYGRADE_LABELS[draft.paygrade]],
|
||||||
["Angestellte:r / Arbeiter:in", draft.workerType],
|
["Beschäftigtengruppe", draft.workerType],
|
||||||
["Kollektivvertrag", draft.collectiveAgreement],
|
["Kollektivvertrag", draft.collectiveAgreement],
|
||||||
["Arbeitstage", draft.workDays.join(", ") || "–"],
|
["Arbeitstage", draft.workDays.join(", ") || "–"],
|
||||||
["Merkmale", flags.length > 0 ? flags.join(", ") : "–"],
|
["Merkmale", flags.length > 0 ? flags.join(", ") : "–"],
|
||||||
|
|||||||
65
db/migrations/20260910140000_lehrling.sql
Normal file
65
db/migrations/20260910140000_lehrling.sql
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
-- Lehrling als dritte Beschäftigtengruppe.
|
||||||
|
--
|
||||||
|
-- worker_type kannte bisher zwei Werte, weil das Feld nach ihnen benannt war:
|
||||||
|
-- „Angestellte:r / Arbeiter:in". Lehrlinge sind in Österreich die dritte
|
||||||
|
-- sozialversicherungsrechtliche Gruppe daneben — bislang wurden sie als
|
||||||
|
-- Angestellte:r oder Arbeiter:in geführt, was sie nicht sind.
|
||||||
|
--
|
||||||
|
-- ═══ Warum das hier allein steht ═══════════════════════════════════
|
||||||
|
--
|
||||||
|
-- Ein Enum-Wert lässt sich nicht wieder entfernen. Ein Rückbau hiesse: neuen
|
||||||
|
-- Typ anlegen, die Spalte umhängen, den alten wegwerfen — bei Zeilen, die
|
||||||
|
-- daran hängen, ein eigener Vorgang. Deshalb steht hier nichts weiter drin,
|
||||||
|
-- was man gleichzeitig zurücknehmen wollen könnte.
|
||||||
|
--
|
||||||
|
-- ═══ Warum der Prüfblock über den Katalog geht ═════════════════════
|
||||||
|
--
|
||||||
|
-- scripts/migrate.mjs fährt jede Migration in einer Transaktion. Seit
|
||||||
|
-- PostgreSQL 12 darf `add value` darin stehen — **benutzen** lässt sich der
|
||||||
|
-- neue Wert in derselben Transaktion aber nicht: ein Vergleich gegen
|
||||||
|
-- 'Lehrling'::worker_type scheitert mit „unsafe use of new value". Die
|
||||||
|
-- Gegenprobe fragt deshalb pg_enum, wo die Beschriftung schlichter Text ist.
|
||||||
|
--
|
||||||
|
-- ═══ Was hier bewusst NICHT steht ══════════════════════════════════
|
||||||
|
--
|
||||||
|
-- Die Beschriftung in app_feld_karte() heisst weiter
|
||||||
|
-- 'Angestellte:r/Arbeiter:in', obwohl die Oberfläche das Feld ab jetzt
|
||||||
|
-- „Beschäftigtengruppe" nennt. Diese Zeichenkette ist dort kein Etikett,
|
||||||
|
-- sondern ein Schlüssel: employee_history.changes und pending_changes tragen
|
||||||
|
-- sie in bereits gespeicherten Zeilen, und app_feld_karte() ist die Karte,
|
||||||
|
-- über die das Zurücksetzen und Korrigieren eines Historieneintrags das Feld
|
||||||
|
-- wiederfindet. Wer sie umbenennt, ohne die gespeicherten Zeilen mitzuziehen,
|
||||||
|
-- macht jeden alten Eintrag zu diesem Feld unumkehrbar — ein stiller Verlust,
|
||||||
|
-- der erst auffällt, wenn jemand eine Änderung zurücknehmen will.
|
||||||
|
|
||||||
|
alter type worker_type add value if not exists 'Lehrling';
|
||||||
|
|
||||||
|
-- ═══ Gegenprobe ═══════════════════════════════════════════════════
|
||||||
|
do $$
|
||||||
|
declare
|
||||||
|
anzahl int;
|
||||||
|
begin
|
||||||
|
if not exists (
|
||||||
|
select 1
|
||||||
|
from pg_enum e
|
||||||
|
join pg_type t on t.oid = e.enumtypid
|
||||||
|
where t.typname = 'worker_type' and e.enumlabel = 'Lehrling'
|
||||||
|
) then
|
||||||
|
raise exception 'worker_type kennt Lehrling nicht.';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Die beiden alten Werte müssen stehen bleiben: ein Enum, das statt drei
|
||||||
|
-- Werten nur noch einen neuen trägt, hätte die Spalte unbrauchbar gemacht.
|
||||||
|
select count(*) into anzahl
|
||||||
|
from pg_enum e
|
||||||
|
join pg_type t on t.oid = e.enumtypid
|
||||||
|
where t.typname = 'worker_type';
|
||||||
|
if anzahl <> 3 then
|
||||||
|
raise exception 'worker_type hat % Werte, erwartet werden 3.', anzahl;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Die Beschriftung in der Feldkarte bleibt, wie sie war — siehe oben.
|
||||||
|
if not (app_feld_karte() ? 'Angestellte:r/Arbeiter:in') then
|
||||||
|
raise exception 'Die Feldkarte kennt worker_type nicht mehr unter der gespeicherten Beschriftung.';
|
||||||
|
end if;
|
||||||
|
end $$;
|
||||||
@@ -302,7 +302,7 @@ eigenen Zeilen sind ohnehin immer dabei. Die Tabelle hiess bis September 2026
|
|||||||
| `employment_status` | Aktiv, Karenz, Geplant, Ausgetreten |
|
| `employment_status` | Aktiv, Karenz, Geplant, Ausgetreten |
|
||||||
| `employment_type` | Vollzeit, Teilzeit |
|
| `employment_type` | Vollzeit, Teilzeit |
|
||||||
| `contract_type` | unbefristet, befristet |
|
| `contract_type` | unbefristet, befristet |
|
||||||
| `worker_type` | Angestellte:r, Arbeiter:in |
|
| `worker_type` | Angestellte:r, Arbeiter:in, Lehrling |
|
||||||
| `collective_agreement` | Handel, Süßwaren |
|
| `collective_agreement` | Handel, Süßwaren |
|
||||||
| `paygrade_type` | A, B, C, D, E, F |
|
| `paygrade_type` | A, B, C, D, E, F |
|
||||||
| `source_type` | Intern, Extern |
|
| `source_type` | Intern, Extern |
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ export const BLATT_PERSONEN: BlattSchema = {
|
|||||||
name: "Beschäftigtengruppe",
|
name: "Beschäftigtengruppe",
|
||||||
ziel: "worker_type",
|
ziel: "worker_type",
|
||||||
pflicht: false,
|
pflicht: false,
|
||||||
typ: { art: "auswahl", werte: ["Angestellte:r", "Arbeiter:in"] },
|
typ: { art: "auswahl", werte: ["Angestellte:r", "Arbeiter:in", "Lehrling"] },
|
||||||
hinweis: "Leer = Angestellte:r.",
|
hinweis: "Leer = Angestellte:r.",
|
||||||
beispiel: "Angestellte:r",
|
beispiel: "Angestellte:r",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function werte(...w: string[]): { wert: string; label: string }[] {
|
|||||||
export const AUSWAHL_KRITERIEN: readonly AuswahlKriterium[] = [
|
export const AUSWAHL_KRITERIEN: readonly AuswahlKriterium[] = [
|
||||||
{ key: "employment", label: "Beschäftigungsart", alle: "Alle Beschäftigungsarten", optionen: werte("Vollzeit", "Teilzeit") },
|
{ key: "employment", label: "Beschäftigungsart", alle: "Alle Beschäftigungsarten", optionen: werte("Vollzeit", "Teilzeit") },
|
||||||
{ key: "contract", label: "Vertragsart", alle: "Alle Vertragsarten", optionen: werte("unbefristet", "befristet") },
|
{ key: "contract", label: "Vertragsart", alle: "Alle Vertragsarten", optionen: werte("unbefristet", "befristet") },
|
||||||
{ key: "worker", label: "Angestellte:r / Arbeiter:in", alle: "Alle", optionen: werte("Angestellte:r", "Arbeiter:in") },
|
{ key: "worker", label: "Beschäftigtengruppe", alle: "Alle", optionen: werte("Angestellte:r", "Arbeiter:in", "Lehrling") },
|
||||||
{ key: "kv", label: "Kollektivvertrag", alle: "Alle Kollektivverträge", optionen: werte("Handel", "Süßwaren") },
|
{ key: "kv", label: "Kollektivvertrag", alle: "Alle Kollektivverträge", optionen: werte("Handel", "Süßwaren") },
|
||||||
{ key: "paygrade", label: "Paygrade", alle: "Alle Paygrades", optionen: werte("A", "B", "C", "D", "E", "F") },
|
{ key: "paygrade", label: "Paygrade", alle: "Alle Paygrades", optionen: werte("A", "B", "C", "D", "E", "F") },
|
||||||
{ key: "source", label: "Intern/Extern", alle: "Alle", optionen: werte("Intern", "Extern") },
|
{ key: "source", label: "Intern/Extern", alle: "Alle", optionen: werte("Intern", "Extern") },
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export const GROUP_LABELS: Record<GroupDimension, string> = {
|
|||||||
entry_year: "Eintrittsjahr",
|
entry_year: "Eintrittsjahr",
|
||||||
source: "Intern/Extern",
|
source: "Intern/Extern",
|
||||||
paygrade: "Paygrade",
|
paygrade: "Paygrade",
|
||||||
worker_type: "Angestellte:r / Arbeiter:in",
|
worker_type: "Beschäftigtengruppe",
|
||||||
collective_agreement: "Kollektivvertrag",
|
collective_agreement: "Kollektivvertrag",
|
||||||
betriebsrat: "Betriebsrat",
|
betriebsrat: "Betriebsrat",
|
||||||
dienstwagen: "Dienstwagen",
|
dienstwagen: "Dienstwagen",
|
||||||
|
|||||||
10
lib/types.ts
10
lib/types.ts
@@ -9,7 +9,15 @@ export type ContractType = "unbefristet" | "befristet";
|
|||||||
export type PaygradeType = "A" | "B" | "C" | "D" | "E" | "F";
|
export type PaygradeType = "A" | "B" | "C" | "D" | "E" | "F";
|
||||||
export type SourceType = "Intern" | "Extern";
|
export type SourceType = "Intern" | "Extern";
|
||||||
export type GenderType = "m" | "w";
|
export type GenderType = "m" | "w";
|
||||||
export type WorkerType = "Angestellte:r" | "Arbeiter:in";
|
/**
|
||||||
|
* Die sozialversicherungsrechtliche Beschäftigtengruppe.
|
||||||
|
*
|
||||||
|
* Lehrling steht seit September 2026 daneben (Migration 20260910140000).
|
||||||
|
* Bis dahin wurden Lehrlinge als Angestellte:r oder Arbeiter:in geführt,
|
||||||
|
* was sie nicht sind — und was jede Auswertung nach dieser Spalte um
|
||||||
|
* genau diese Personen verfälschte.
|
||||||
|
*/
|
||||||
|
export type WorkerType = "Angestellte:r" | "Arbeiter:in" | "Lehrling";
|
||||||
export type CollectiveAgreement = "Handel" | "Süßwaren";
|
export type CollectiveAgreement = "Handel" | "Süßwaren";
|
||||||
export type Weekday = "Mo" | "Di" | "Mi" | "Do" | "Fr" | "Sa" | "So";
|
export type Weekday = "Mo" | "Di" | "Mi" | "Do" | "Fr" | "Sa" | "So";
|
||||||
|
|
||||||
|
|||||||
47
tests/components/RoleEmploymentFields.test.tsx
Normal file
47
tests/components/RoleEmploymentFields.test.tsx
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { render, screen, within } from "@testing-library/react";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { RoleEmploymentFields, type RoleEmploymentValue } from "@/components/employees/RoleEmploymentFields";
|
||||||
|
|
||||||
|
// Das Auswahlfeld ist die vierte Liste der Beschäftigtengruppen (neben dem
|
||||||
|
// Enum, den Auswertungen und dem Import — tests/unit/beschaeftigtengruppe).
|
||||||
|
// Fehlt ein Wert hier, ist er schlicht nicht einzugeben, und niemand merkt
|
||||||
|
// es: das Feld sieht vollständig aus.
|
||||||
|
|
||||||
|
const WERT: RoleEmploymentValue = {
|
||||||
|
workerType: "Angestellte:r",
|
||||||
|
collectiveAgreement: "Handel",
|
||||||
|
workDays: ["Mo", "Di", "Mi", "Do", "Fr"],
|
||||||
|
isBetriebsrat: false,
|
||||||
|
hasDienstwagen: false,
|
||||||
|
dienstwagenArt: "Verbrenner",
|
||||||
|
isLateraleFuehrung: false,
|
||||||
|
isCLevel: false,
|
||||||
|
hasKuendigungsschutz: false,
|
||||||
|
kuendigungsschutzBis: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
function feld(teil: Partial<RoleEmploymentValue> = {}) {
|
||||||
|
render(<RoleEmploymentFields value={{ ...WERT, ...teil }} onChange={() => {}} />);
|
||||||
|
return screen.getByLabelText("Beschäftigtengruppe");
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Beschäftigtengruppe im Formular", () => {
|
||||||
|
it("bietet alle drei Gruppen an", () => {
|
||||||
|
expect(within(feld()).getAllByRole("option").map((o) => o.textContent)).toEqual([
|
||||||
|
"Angestellte:r",
|
||||||
|
"Arbeiter:in",
|
||||||
|
"Lehrling",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("heisst Beschäftigtengruppe, nicht mehr nach zwei ihrer Werte", () => {
|
||||||
|
// „Angestellte:r / Arbeiter:in" war der Name bis September 2026 — er
|
||||||
|
// wurde falsch, sobald ein dritter Wert dazukam.
|
||||||
|
feld();
|
||||||
|
expect(screen.queryByLabelText(/Arbeiter:in/)).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("zeigt die gespeicherte Gruppe als gewählt", () => {
|
||||||
|
expect(feld({ workerType: "Lehrling" })).toHaveValue("Lehrling");
|
||||||
|
});
|
||||||
|
});
|
||||||
60
tests/unit/beschaeftigtengruppe.test.ts
Normal file
60
tests/unit/beschaeftigtengruppe.test.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { BLAETTER } from "@/lib/import/schema";
|
||||||
|
import { AUSWAHL_KRITERIEN, parseCriteria } from "@/lib/report-criteria";
|
||||||
|
import { GROUP_LABELS } from "@/lib/reports";
|
||||||
|
|
||||||
|
// Die Beschäftigtengruppe (worker_type) steht an vier Stellen als Liste:
|
||||||
|
// im Datenbank-Enum, in der Auswahl der Auswertungen, in der Prüfliste des
|
||||||
|
// Imports und im Auswahlfeld der Oberfläche. Sie werden von Hand gepflegt,
|
||||||
|
// und sie driften auseinander, ohne dass etwas rot wird — ein fehlender Wert
|
||||||
|
// heisst dort nicht „Fehler", sondern „gibt es nicht":
|
||||||
|
//
|
||||||
|
// * fehlt er in der Auswertung, lässt sich nach der Gruppe nicht filtern,
|
||||||
|
// * fehlt er im Import, wird die Zeile abgewiesen,
|
||||||
|
// * fehlt er im Auswahlfeld, ist der Wert nicht einzugeben.
|
||||||
|
//
|
||||||
|
// Deshalb steht die erwartete Liste hier einmal, und jede Stelle wird
|
||||||
|
// dagegen gehalten. Das Enum selbst prüft die Migration (20260910140000).
|
||||||
|
|
||||||
|
const GRUPPEN = ["Angestellte:r", "Arbeiter:in", "Lehrling"];
|
||||||
|
|
||||||
|
function importSpalte() {
|
||||||
|
for (const blatt of BLAETTER) {
|
||||||
|
const treffer = blatt.spalten.find((s) => s.ziel === "worker_type");
|
||||||
|
if (treffer) return treffer;
|
||||||
|
}
|
||||||
|
throw new Error("Keine Importspalte mit ziel worker_type gefunden");
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("Beschäftigtengruppe", () => {
|
||||||
|
it("bietet in den Auswertungen alle drei zur Auswahl", () => {
|
||||||
|
const kriterium = AUSWAHL_KRITERIEN.find((k) => k.key === "worker");
|
||||||
|
expect(kriterium?.optionen.map((o) => o.wert)).toEqual(GRUPPEN);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("lässt jede der drei durch die Prüfung der Adresszeile", () => {
|
||||||
|
// Was nicht in der Liste steht, verwirft parseCriteria stillschweigend —
|
||||||
|
// der Filter wirkte dann einfach nicht, ohne Meldung.
|
||||||
|
for (const gruppe of GRUPPEN) {
|
||||||
|
expect(parseCriteria((k) => (k === "worker" ? gruppe : undefined)).auswahl).toEqual({ worker: gruppe });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("verwirft weiterhin, was nicht dazugehört", () => {
|
||||||
|
// Die Werte landen in SQL-Vergleichen und im Dateinamen des Downloads.
|
||||||
|
expect(parseCriteria((k) => (k === "worker" ? "Lehrling'; drop table employees; --" : undefined)).auswahl).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("nimmt alle drei im Import an", () => {
|
||||||
|
const spalte = importSpalte();
|
||||||
|
expect(spalte.typ).toMatchObject({ art: "auswahl", werte: GRUPPEN });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("nennt das Feld überall Beschäftigtengruppe", () => {
|
||||||
|
// Bis September 2026 hiess es „Angestellte:r / Arbeiter:in" — ein Name
|
||||||
|
// aus seinen beiden Werten, der mit dem dritten falsch wurde.
|
||||||
|
expect(AUSWAHL_KRITERIEN.find((k) => k.key === "worker")?.label).toBe("Beschäftigtengruppe");
|
||||||
|
expect(GROUP_LABELS.worker_type).toBe("Beschäftigtengruppe");
|
||||||
|
expect(importSpalte().name).toBe("Beschäftigtengruppe");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user