144 lines
4.0 KiB
TypeScript
144 lines
4.0 KiB
TypeScript
import { strict as assert } from "node:assert";
|
|
import { test } from "node:test";
|
|
import {
|
|
AnnouncementAudience as A,
|
|
EventParticipationStatus as S,
|
|
RsvpMode,
|
|
TerminType,
|
|
UserRole,
|
|
} from "@prisma/client";
|
|
import {
|
|
announcementRecipientWhere,
|
|
visibleAnnouncementAudiences,
|
|
} from "../src/lib/announcement-access";
|
|
import {
|
|
hasMissingRsvp,
|
|
rsvpSubmissionSchema,
|
|
suggestedRsvpMode,
|
|
type RsvpEventDto,
|
|
} from "../src/lib/rsvp";
|
|
|
|
const family = {
|
|
eventId: "event",
|
|
mode: RsvpMode.FAMILY,
|
|
status: S.ATTENDING,
|
|
adultCount: 2,
|
|
};
|
|
|
|
test("Familienzusage braucht eine positive ganze Erwachsenenanzahl", () => {
|
|
assert.equal(rsvpSubmissionSchema.safeParse(family).success, true);
|
|
for (const adultCount of [0, -1, 1.5, 2147483648, NaN]) {
|
|
assert.equal(
|
|
rsvpSubmissionSchema.safeParse({ ...family, adultCount }).success,
|
|
false,
|
|
);
|
|
}
|
|
});
|
|
test("Familienabsage setzt Erwachsenenanzahl auf null", () => {
|
|
assert.equal(
|
|
rsvpSubmissionSchema.safeParse({
|
|
...family,
|
|
status: S.NOT_ATTENDING,
|
|
adultCount: 0,
|
|
}).success,
|
|
true,
|
|
);
|
|
assert.equal(
|
|
rsvpSubmissionSchema.safeParse({ ...family, status: S.NOT_ATTENDING })
|
|
.success,
|
|
false,
|
|
);
|
|
});
|
|
test("Kinderantworten dürfen verschiedene Zusagen enthalten, keine Duplikate oder leere Liste", () => {
|
|
const payload = {
|
|
eventId: "event",
|
|
mode: RsvpMode.CHILD,
|
|
responses: [
|
|
{ childId: "a", status: S.ATTENDING },
|
|
{ childId: "b", status: S.NOT_ATTENDING },
|
|
],
|
|
};
|
|
assert.equal(rsvpSubmissionSchema.safeParse(payload).success, true);
|
|
assert.equal(
|
|
rsvpSubmissionSchema.safeParse({ ...payload, responses: [] }).success,
|
|
false,
|
|
);
|
|
assert.equal(
|
|
rsvpSubmissionSchema.safeParse({
|
|
...payload,
|
|
responses: [payload.responses[0], payload.responses[0]],
|
|
}).success,
|
|
false,
|
|
);
|
|
});
|
|
test("Eltern sehen Elternmeldungen und gemeinsame Meldungen", () => {
|
|
assert.deepEqual(
|
|
visibleAnnouncementAudiences({ role: UserRole.ELTERN, familyId: "f" }),
|
|
[A.ALLE, A.ELTERN],
|
|
);
|
|
assert.deepEqual(
|
|
visibleAnnouncementAudiences({ role: UserRole.KOORDINATOR, familyId: "f" }),
|
|
[A.ALLE, A.ELTERN],
|
|
);
|
|
});
|
|
test("Erzieherkonto erhält auch mit Haushaltszuordnung keine Elternmeldungen", () => {
|
|
assert.deepEqual(
|
|
visibleAnnouncementAudiences({ role: UserRole.ERZIEHER, familyId: "f" }),
|
|
[A.ALLE, A.ERZIEHER],
|
|
);
|
|
});
|
|
test("Admin darf alle Meldungen verwalten", () => {
|
|
assert.deepEqual(
|
|
new Set(visibleAnnouncementAudiences({ role: UserRole.ADMIN })),
|
|
new Set(Object.values(A)),
|
|
);
|
|
});
|
|
test("E-Mail-Gruppen schließen Erzieher aus Elternempfängern aus", () => {
|
|
assert.deepEqual(announcementRecipientWhere(A.ERZIEHER), {
|
|
role: UserRole.ERZIEHER,
|
|
});
|
|
assert.deepEqual(announcementRecipientWhere(A.ELTERN), {
|
|
role: { not: UserRole.ERZIEHER },
|
|
OR: [{ familyId: { not: null } }, { role: UserRole.ELTERN }],
|
|
});
|
|
});
|
|
test("Die Rückmeldekarte verschwindet erst, wenn jedes Kind geantwortet hat", () => {
|
|
const event: RsvpEventDto = {
|
|
id: "e",
|
|
title: "Ausflug",
|
|
startDate: "2030-01-01",
|
|
rsvpDeadline: null,
|
|
mode: RsvpMode.CHILD,
|
|
canReply: true,
|
|
familyResponse: null,
|
|
children: [
|
|
{ id: "a", name: "A", status: S.ATTENDING },
|
|
{ id: "b", name: "B", status: null },
|
|
],
|
|
};
|
|
assert.equal(hasMissingRsvp(event), true);
|
|
assert.equal(
|
|
hasMissingRsvp({
|
|
...event,
|
|
children: event.children.map((child) => ({
|
|
...child,
|
|
status: S.NOT_ATTENDING,
|
|
})),
|
|
}),
|
|
false,
|
|
);
|
|
assert.equal(hasMissingRsvp({ ...event, mode: RsvpMode.FAMILY }), true);
|
|
assert.equal(
|
|
hasMissingRsvp({
|
|
...event,
|
|
mode: RsvpMode.FAMILY,
|
|
familyResponse: { status: S.NOT_ATTENDING, adultCount: 0 },
|
|
}),
|
|
false,
|
|
);
|
|
});
|
|
test("Antwortart wird passend zur Terminart vorgeschlagen", () => {
|
|
assert.equal(suggestedRsvpMode(TerminType.ELTERNABEND), RsvpMode.FAMILY);
|
|
assert.equal(suggestedRsvpMode(TerminType.SONSTIGES), RsvpMode.CHILD);
|
|
});
|