Files
Artista-Filmcamp/tests/contact.integration.test.ts
T
Nick SzaunigandClaude Opus 5.5 a47e91e9d5
Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 2m50s
feat: Telefonnummer im Kontaktformular ist Pflicht
Gleiche Prüfung wie bei der Buchung: mindestens 6 Zeichen, nur Ziffern, Leerzeichen und + ( ) / -.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-07 00:56:30 +02:00

71 lines
3.2 KiB
TypeScript

import { beforeEach, describe, expect, test } from "vitest";
import { contactRequestSchema, submitContactRequest } from "@/lib/contact";
import { resetEnvCache } from "@/lib/env";
import { db, resetDb, SECRET, setupCamp } from "./support/db";
const NOW = new Date("2026-11-15T10:00:00Z");
const ctx = { now: NOW, secret: SECRET };
function request(overrides: Record<string, unknown> = {}) {
return contactRequestSchema.parse({
name: "Lena Beispiel",
email: "[email protected]",
phone: "+49 170 1234567",
availability: "abends",
message: "Passt das Camp für Einsteigerinnen?",
privacy: true,
website: "",
...overrides,
});
}
beforeEach(async () => {
await resetDb();
await setupCamp({ organizerEmail: "[email protected]" });
delete process.env.ADMIN_NOTIFY_EMAIL;
resetEnvCache();
});
describe("Erstgespräch", () => {
test("Anfrage landet als Mail beim Veranstalter, mit allen Angaben", async () => {
expect(await submitContactRequest(db, request(), ctx)).toEqual({ ok: true, delivered: true });
const mails = await db.emailMessage.findMany();
expect(mails).toHaveLength(1);
expect(mails[0]!.toAddress).toBe("[email protected]");
expect(mails[0]!.subject).toContain("Lena Beispiel");
expect(mails[0]!.textBody).toContain("[email protected]");
expect(mails[0]!.textBody).toContain("Passt das Camp für Einsteigerinnen?");
expect(mails[0]!.htmlBody).toContain("mailto:lena%40example.org");
});
test("doppelt abgeschickt ergibt nur eine Mail", async () => {
await submitContactRequest(db, request(), ctx);
await submitContactRequest(db, request(), { ...ctx, now: new Date(NOW.getTime() + 10_000) });
expect(await db.emailMessage.count()).toBe(1);
});
test("Bot im Honeypot: Erfolg vortäuschen, nichts verschicken", async () => {
expect(await submitContactRequest(db, request({ website: "https://spam.example" }), ctx)).toEqual({ ok: true, delivered: false });
expect(await db.emailMessage.count()).toBe(0);
});
test("ohne Empfänger nicht verfügbar, mit ADMIN_NOTIFY_EMAIL als Ersatz", async () => {
await setupCamp({ organizerEmail: null });
expect(await submitContactRequest(db, request(), ctx)).toEqual({ ok: false, error: "NOT_CONFIGURED" });
process.env.ADMIN_NOTIFY_EMAIL = "[email protected]";
resetEnvCache();
await submitContactRequest(db, request(), ctx);
expect((await db.emailMessage.findFirstOrThrow()).toAddress).toBe("[email protected]");
});
test("Pflichtangaben und Einwilligung werden serverseitig geprüft", () => {
expect(contactRequestSchema.safeParse({ name: "L", email: "kein-mail", privacy: false }).success).toBe(false);
expect(contactRequestSchema.safeParse({ name: "Lena", email: "[email protected]", privacy: false }).success).toBe(false);
const base = { name: "Lena", email: "[email protected]", privacy: true };
expect(contactRequestSchema.safeParse(base).success).toBe(false);
expect(contactRequestSchema.safeParse({ ...base, phone: " " }).success).toBe(false);
expect(contactRequestSchema.safeParse({ ...base, phone: "abc123456" }).success).toBe(false);
expect(request({ phone: " +49 170 1234567 " }).phone).toBe("+49 170 1234567");
});
});