Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 2m50s
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]>
71 lines
3.2 KiB
TypeScript
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");
|
|
});
|
|
});
|