Send the invitation as a light letter that names the community, the inviter by email, and who can read the Rule.

This commit is contained in:
adilallo committed 2026-11-06 09:00:44 -07:00
1 parent 70ceb73104
commit 727a92a9ac
14 files changed
+534 -26

No files matched your search

@@ -0,0 +1,90 @@
import { describe, expect, it } from "vitest";
import {
RULE_STAKEHOLDER_INVITE_LOGO_PATH,
buildRuleStakeholderInviteMail,
ruleStakeholderInviteCopyUrl,
} from "../../lib/server/ruleStakeholderInviteMail";
const VERIFY_URL =
"https://communityrule.info/api/invites/rule-stakeholder/verify?token=abc";
describe("ruleStakeholderInviteCopyUrl", () => {
it("adds copy=1 to the invitation link", () => {
expect(ruleStakeholderInviteCopyUrl(VERIFY_URL)).toBe(
`${VERIFY_URL}&copy=1`,
);
});
});
describe("buildRuleStakeholderInviteMail", () => {
const mail = buildRuleStakeholderInviteMail({
to: "rosa@example.org",
verifyUrl: VERIFY_URL,
origin: "https://communityrule.info",
communityName: "Juniper Street Food Share",
inviterEmail: "maya@example.org",
summary:
"A food share that runs every Sunday on Juniper Street. Volunteers collect surplus from two grocers and a farm stand and share it with neighbors.",
document: {
sections: [
{
categoryName: "Values",
entries: [
{ title: "Care", body: "We care." },
{ title: "Share", body: "We share." },
{ title: "Listen", body: "We listen." },
],
},
{
categoryName: "Communication",
entries: Array.from({ length: 6 }, (_, i) => ({
title: `Card ${i + 1}`,
body: "Body",
})),
},
],
},
});
it("uses the launch subject, preview, and privacy line", () => {
expect(mail.subject).toBe(
"Juniper Street Food Share invited you to read their Rule",
);
expect(mail.previewText).toBe(
"It covers how they talk, who belongs, how they decide and what happens when they disagree.",
);
expect(mail.text).toContain(
"Every Rule starts private. Only the people Juniper Street Food Share invites can read it until the person who holds the pen turns on a link. A Rule is public and featured only when a community asks us in writing.",
);
expect(mail.html).toContain("Every Rule starts private.");
});
it("names the inviter by email and points replies at that address in copy", () => {
expect(mail.text).toContain("maya@example.org sent the invitation.");
expect(mail.text).toContain(
"how they talk, who belongs, how they decide and what happens when they disagree.",
);
expect(mail.html).not.toContain("Maya Ortiz");
});
it("includes read and copy links, footer, and the 2x mark", () => {
expect(mail.text).toContain(VERIFY_URL);
expect(mail.text).toContain(`${VERIFY_URL}&copy=1`);
expect(mail.html).toContain(`href="${VERIFY_URL}"`);
expect(mail.html).toContain(`href="${VERIFY_URL}&copy=1"`);
expect(mail.html).toContain("Read the Rule");
expect(mail.html).toContain("Make a copy");
expect(mail.html).toContain("3 VALUES AND 6 CARDS");
expect(mail.html).toContain("JS");
expect(mail.html).toContain("#e4e4e4");
expect(mail.html).toContain("font-size:14px;line-height:20px;color:#464646");
expect(mail.html).toContain(
`https://communityrule.info${RULE_STAKEHOLDER_INVITE_LOGO_PATH}`,
);
expect(mail.html).toContain("https://communityrule.info/privacy");
expect(mail.html).toContain("https://communityrule.info/about");
expect(mail.text).toContain(
"Juniper Street Food Share’s Rule on CommunityRule",
);
});
});