feat(verzeichnis): LDAP-Abgleich, Zeitplan, CSV-Import und Log (#30)
This commit was merged in pull request #30.
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { Betriebsmodus, Herkunft } from "@/generated/prisma/enums";
|
||||
import { abteilungAnlegen } from "@/server/services/abteilungen";
|
||||
import { ungepflegteAbteilungen } from "@/server/queries/abteilungen";
|
||||
import { datenbankLeeren, datenbankVerfuegbar, testPrisma } from "./helpers/db";
|
||||
|
||||
/**
|
||||
* Abteilungsvorschläge (#016).
|
||||
*
|
||||
* Die Liste, aus der ein Administrator mit einem Klick echte `Abteilung`-Einträge
|
||||
* macht. Jeder Eintrag ist damit ein Versprechen: der Klick muss gelingen.
|
||||
* Deshalb steht hier nichts, was `abteilungAnlegen` danach abweisen würde — keine
|
||||
* bereits (auch archiviert) gepflegte Abteilung und kein archivierter Kunde.
|
||||
*/
|
||||
|
||||
async function grundbestand(modus: Betriebsmodus = Betriebsmodus.INTERN) {
|
||||
const eigene = await testPrisma.kunde.create({
|
||||
data: { name: "Eigene Organisation", kuerzel: "EIGEN", istEigeneOrganisation: true },
|
||||
});
|
||||
await testPrisma.einstellung.create({ data: { id: "global", modus } });
|
||||
const benutzer = await testPrisma.benutzer.create({
|
||||
data: { email: "admin@firma.example", name: "Administrator", rolle: "ADMIN" },
|
||||
});
|
||||
return { eigene, admin: { id: benutzer.id, rolle: benutzer.rolle } };
|
||||
}
|
||||
|
||||
async function person(
|
||||
kundeId: string,
|
||||
abteilung: string,
|
||||
weiteres: { aktiv?: boolean; herkunft?: Herkunft } = {},
|
||||
) {
|
||||
const nummer = await testPrisma.mitarbeiter.count();
|
||||
return testPrisma.mitarbeiter.create({
|
||||
data: {
|
||||
kundeId,
|
||||
vorname: "Person",
|
||||
nachname: `Nummer ${nummer}`,
|
||||
anzeigename: `Person Nummer ${nummer}`,
|
||||
abteilung,
|
||||
...weiteres,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe.runIf(datenbankVerfuegbar)("Abteilungsvorschläge", () => {
|
||||
beforeEach(async () => {
|
||||
await datenbankLeeren();
|
||||
delete process.env["OIDC_CUSTOMER_GROUP_PREFIX"];
|
||||
});
|
||||
|
||||
it("zeigt nur Namen, zu denen es noch keine Abteilung gibt", async () => {
|
||||
const { admin, eigene } = await grundbestand();
|
||||
await abteilungAnlegen({ name: "Buchhaltung", zielOu: "OU=Buchhaltung" }, admin);
|
||||
await person(eigene.id, "Buchhaltung");
|
||||
await person(eigene.id, "Vertrieb", { herkunft: Herkunft.ABGLEICH });
|
||||
await person(eigene.id, "Vertrieb");
|
||||
|
||||
expect(await ungepflegteAbteilungen(admin)).toEqual([
|
||||
{ name: "Vertrieb", anzahl: 2, kundeId: eigene.id },
|
||||
]);
|
||||
});
|
||||
|
||||
it("zählt deaktivierte Personen nicht mit", async () => {
|
||||
// Eine Abteilung, in der nur noch Ausgeschiedene stehen, braucht keine
|
||||
// Ziel-OU mehr — und ein Vorschlag, den niemand mehr braucht, verdeckt die
|
||||
// übrigen.
|
||||
const { admin, eigene } = await grundbestand();
|
||||
await person(eigene.id, "Altlast", { aktiv: false });
|
||||
await person(eigene.id, "Vertrieb");
|
||||
|
||||
expect((await ungepflegteAbteilungen(admin)).map((eintrag) => eintrag.name)).toEqual(["Vertrieb"]);
|
||||
});
|
||||
|
||||
it("schlägt nicht vor, was es archiviert schon gibt", async () => {
|
||||
// Der Name ist je Kunde eindeutig: `abteilungAnlegen` würde diesen Klick mit
|
||||
// „gibt es schon“ abweisen. Ein Knopf, der das tut, ist keiner.
|
||||
const { admin, eigene } = await grundbestand();
|
||||
const abteilung = await abteilungAnlegen({ name: "Vertrieb" }, admin);
|
||||
await testPrisma.abteilung.update({ where: { id: abteilung.id }, data: { archiviert: true } });
|
||||
await person(eigene.id, "Vertrieb");
|
||||
|
||||
expect(await ungepflegteAbteilungen(admin)).toEqual([]);
|
||||
await expect(abteilungAnlegen({ name: "Vertrieb" }, admin)).rejects.toThrow(/gibt es schon/);
|
||||
});
|
||||
|
||||
it("übernimmt einen Vorschlag – und zwar nur den Namen", async () => {
|
||||
const { admin, eigene } = await grundbestand();
|
||||
await person(eigene.id, "Vertrieb");
|
||||
const offen = await ungepflegteAbteilungen(admin);
|
||||
expect(offen).toHaveLength(1);
|
||||
|
||||
const abteilung = await abteilungAnlegen({ name: offen[0]!.name, kundeId: offen[0]!.kundeId }, admin);
|
||||
expect(abteilung).toMatchObject({ name: "Vertrieb", zielOu: null, standardGruppen: [] });
|
||||
expect(await ungepflegteAbteilungen(admin)).toEqual([]);
|
||||
});
|
||||
|
||||
describe("Mandantengrenze", () => {
|
||||
async function zweiKunden() {
|
||||
const { admin, eigene } = await grundbestand(Betriebsmodus.DIENSTLEISTUNG);
|
||||
const meiner = await testPrisma.kunde.create({ data: { name: "Meiner", kuerzel: "MEIN" } });
|
||||
const fremder = await testPrisma.kunde.create({ data: { name: "Fremder", kuerzel: "FREMD" } });
|
||||
const techniker = await testPrisma.benutzer.create({
|
||||
data: { email: "t@firma.example", name: "Techniker", rolle: "TECHNIKER" },
|
||||
});
|
||||
await testPrisma.benutzerKunde.create({ data: { benutzerId: techniker.id, kundeId: meiner.id } });
|
||||
process.env["OIDC_CUSTOMER_GROUP_PREFIX"] = "lz-kunde-";
|
||||
return { admin, eigene, meiner, fremder, techniker: { id: techniker.id, rolle: techniker.rolle } };
|
||||
}
|
||||
|
||||
it("zeigt nur die Vorschläge der sichtbaren Kunden", async () => {
|
||||
const { meiner, fremder, techniker } = await zweiKunden();
|
||||
await person(meiner.id, "Vertrieb");
|
||||
await person(fremder.id, "Vertrieb");
|
||||
await person(fremder.id, "Technik");
|
||||
|
||||
expect(await ungepflegteAbteilungen(techniker)).toEqual([
|
||||
{ name: "Vertrieb", anzahl: 1, kundeId: meiner.id },
|
||||
]);
|
||||
});
|
||||
|
||||
it("hält Kunden auseinander, die denselben Namen benutzen", async () => {
|
||||
// „Vertrieb“ ist bei einem Kunden gepflegt und beim anderen nicht. Ohne die
|
||||
// Gruppierung nach Kunde und Name verschwände der offene Fall — genau das
|
||||
// stand hier, bis der Review von #011 es gefunden hat.
|
||||
const { admin, meiner, fremder } = await zweiKunden();
|
||||
await testPrisma.abteilung.create({ data: { kundeId: meiner.id, name: "Vertrieb" } });
|
||||
await person(meiner.id, "Vertrieb");
|
||||
await person(fremder.id, "Vertrieb");
|
||||
|
||||
expect(await ungepflegteAbteilungen(admin)).toEqual([
|
||||
{ name: "Vertrieb", anzahl: 1, kundeId: fremder.id },
|
||||
]);
|
||||
});
|
||||
|
||||
it("schlägt nichts für einen archivierten Kunden vor", async () => {
|
||||
// `kundeErmitteln` weist einen archivierten Kunden ab; der Klick auf den
|
||||
// Vorschlag ergäbe nur eine Fehlermeldung.
|
||||
const { admin, fremder } = await zweiKunden();
|
||||
await person(fremder.id, "Vertrieb");
|
||||
await testPrisma.kunde.update({ where: { id: fremder.id }, data: { archiviert: true } });
|
||||
|
||||
expect(await ungepflegteAbteilungen(admin)).toEqual([]);
|
||||
await expect(abteilungAnlegen({ name: "Vertrieb", kundeId: fremder.id }, admin)).rejects.toThrow(
|
||||
/archiviert/,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user