Add the Workshops page and keep each sign-up on the site.
The form is built once to the settled field set, and a valid send is saved before anyone is emailed. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
974a5ace4c
commit
c0ba3a3798
50 files changed
+2773
-1
No files matched your search
@@ -0,0 +1,101 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildWorkshopConfirmationMail, buildWorkshopInboxMail } from "../../lib/workshopSignupMail";
|
||||
import {
|
||||
EMPTY_WORKSHOP_FORM_VALUES,
|
||||
suggestWorkshopRoute,
|
||||
type WorkshopFormValues,
|
||||
} from "../../lib/workshopSignup";
|
||||
import { parseWorkshopSignupPayload } from "../../lib/server/validation/workshopSignupSchemas";
|
||||
|
||||
const values: WorkshopFormValues = {
|
||||
...EMPTY_WORKSHOP_FORM_VALUES,
|
||||
challenges: ["big-change"],
|
||||
organizationName: "Northside Credit Union",
|
||||
organizationKind: "credit-union",
|
||||
memberCount: "1000-10000",
|
||||
contactName: "Ada Lovelace",
|
||||
email: "ada@example.com",
|
||||
sourcePage: "/workshops",
|
||||
sourceUrl: "https://communityrule.com/workshops",
|
||||
};
|
||||
|
||||
describe("suggestWorkshopRoute", () => {
|
||||
it("sends volunteer-run groups to the kit", () => {
|
||||
expect(
|
||||
suggestWorkshopRoute({ organizationKind: "volunteer", memberCount: "10000-100000" }),
|
||||
).toEqual({
|
||||
largeOrganization: false,
|
||||
note: "Volunteer-run group: send the kit and office hours.",
|
||||
});
|
||||
});
|
||||
|
||||
it("flags 1,000 or more members as a large organization and names no price", () => {
|
||||
const route = suggestWorkshopRoute({
|
||||
organizationKind: "credit-union",
|
||||
memberCount: "1000-10000",
|
||||
});
|
||||
expect(route.largeOrganization).toBe(true);
|
||||
expect(route.note).toBe("Large organization: call with the facilitator lead.");
|
||||
expect(route.note.toLowerCase()).not.toMatch(/price|fee|\$|£|€/);
|
||||
});
|
||||
|
||||
it("sends smaller leagues to a partnership call", () => {
|
||||
expect(
|
||||
suggestWorkshopRoute({ organizationKind: "league", memberCount: "under-1000" }).note,
|
||||
).toBe("League, association or co-op developer: partnership call.");
|
||||
});
|
||||
|
||||
it("sends everyone else the one-page brief", () => {
|
||||
expect(
|
||||
suggestWorkshopRoute({ organizationKind: "housing-coop", memberCount: "not-sure" }).note,
|
||||
).toBe("Send the one-page brief, then offer a call.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("workshop signup mail", () => {
|
||||
it("keeps a price out of the inbox note and the confirmation", () => {
|
||||
const inbox = buildWorkshopInboxMail({
|
||||
values,
|
||||
routeNote: "Large organization: call with the facilitator lead.",
|
||||
largeOrganization: true,
|
||||
requestId: "req-1",
|
||||
schedulingUrl: "https://calendar.example/workshop",
|
||||
});
|
||||
const confirmation = buildWorkshopConfirmationMail({
|
||||
largeOrganization: true,
|
||||
schedulingUrl: "https://calendar.example/workshop",
|
||||
});
|
||||
const combined = `${inbox.text}\n${confirmation.text}`.toLowerCase();
|
||||
expect(combined).not.toMatch(/price|fee|\$|£|€/);
|
||||
expect(confirmation.text).toContain("two working days");
|
||||
expect(confirmation.text).toContain("Choose a time");
|
||||
expect(inbox.text).toContain("Northside Credit Union");
|
||||
expect(inbox.text).toContain("https://communityrule.com/workshops");
|
||||
});
|
||||
});
|
||||
|
||||
describe("parseWorkshopSignupPayload", () => {
|
||||
it("keeps answers and reports each missing required field", () => {
|
||||
const parsed = parseWorkshopSignupPayload({
|
||||
unspokenQuestion: "How do we grow?",
|
||||
organizationName: "Northside",
|
||||
email: "not-an-email",
|
||||
});
|
||||
expect(parsed.values.unspokenQuestion).toBe("How do we grow?");
|
||||
expect(parsed.values.organizationName).toBe("Northside");
|
||||
expect(parsed.fieldErrors.challenges).toBe("required");
|
||||
expect(parsed.fieldErrors.organizationKind).toBe("required");
|
||||
expect(parsed.fieldErrors.memberCount).toBe("required");
|
||||
expect(parsed.fieldErrors.contactName).toBe("required");
|
||||
expect(parsed.fieldErrors.email).toBe("invalid");
|
||||
});
|
||||
|
||||
it("accepts the full field set", () => {
|
||||
const parsed = parseWorkshopSignupPayload({
|
||||
...values,
|
||||
startedAt: Date.now() - 10_000,
|
||||
});
|
||||
expect(parsed.fieldErrors).toEqual({});
|
||||
expect(parsed.values.email).toBe("ada@example.com");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user