Skip to content
141 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { CONTACT } from "./legal.ts";
5import {
6 HAVE_AN_INVITE,
7 INVITES_CONTACT,
8 cleanCode,
9 inviteFor,
10 inviteLink,
11 inviteState,
12 landingFor,
13 looksAutomated,
14 moreInvitesMailto,
15 remainingLine,
16 sharedDomainsHint,
17 sharedInviteLine,
18 sharedInviteLink,
19 signUpCopy,
20 suggestUsername,
21 welcomeCookie,
22 clearWelcome,
23 welcomes,
24} from "./invites.ts";
25
26const CODE = "g1t-k7m2-q9xd-4hpw-abcd-0123-4567-89ef-ghjk";
27
28test("while invite-only, nobody is offered a plain sign-up", () => {
29 assert.deepEqual(signUpCopy(true), { primary: "Request access", secondary: "Have an invite?" });
30 assert.deepEqual(signUpCopy(false), { primary: "Sign up", secondary: null });
31 assert.equal(HAVE_AN_INVITE, "/register#invite");
32});
33
34test("asking for more invites goes to support with the [g1t Invites] subject", () => {
35 assert.equal(INVITES_CONTACT, CONTACT.support);
36 assert.equal(moreInvitesMailto(), "mailto:hey@flagon.io?subject=%5Bg1t%20Invites%5D%20More%20invites");
37 assert.equal(
38 moreInvitesMailto("acme"),
39 "mailto:hey@flagon.io?subject=%5Bg1t%20Invites%5D%20More%20invites%20for%20acme",
40 );
41});
42
43test("an invite link is on g1t.sh unless told otherwise", () => {
44 assert.equal(inviteLink(CODE), `https://g1t.sh/invite/${CODE}`);
45 assert.equal(inviteLink(CODE, "http://localhost:8787/"), `http://localhost:8787/invite/${CODE}`);
46});
47
48test("a pasted link or code is tidied to the code", () => {
49 assert.equal(cleanCode(CODE), CODE);
50 assert.equal(cleanCode(` ${CODE} `), CODE);
51 assert.equal(cleanCode(`https://g1t.sh/invite/${CODE}`), CODE);
52 assert.equal(cleanCode(`https://g1t.sh/register?invite=${CODE}&next=%2F`), CODE);
53 assert.equal(cleanCode("g1t-k7m2 q9xd"), "g1t-k7m2q9xd");
54 assert.equal(cleanCode(null), "");
55 assert.equal(cleanCode("x".repeat(500)).length, 80);
56});
57
58test("each invite says where it stands and whom it is for", () => {
59 const base = { redeemedBy: null, email: null, workspace: null };
60 assert.deepEqual(inviteState({ ...base, status: "pending" }), { label: "Pending", tone: "pending" });
61 assert.deepEqual(inviteState({ ...base, status: "redeemed", redeemedBy: "ada" }), { label: "Joined as @ada", tone: "done" });
62 assert.deepEqual(inviteState({ ...base, status: "awaiting_confirmation", redeemedBy: "ada" }), {
63 label: "@ada is confirming their email",
64 tone: "pending",
65 });
66 assert.deepEqual(inviteState({ ...base, status: "expired" }), { label: "Expired", tone: "dead" });
67 assert.deepEqual(inviteState({ ...base, status: "revoked" }), { label: "Revoked", tone: "dead" });
68 assert.equal(inviteFor({ ...base, status: "pending" }), "Anyone with the link");
69 assert.equal(inviteFor({ ...base, status: "pending", email: "ada@example.com", workspace: "acme" }), "ada@example.com · joins acme");
70});
71
72test("what is left reads plainly", () => {
73 assert.equal(remainingLine({ limit: 5, used: 2, remaining: 3 }), "3 of 5 invites left");
74 assert.equal(remainingLine({ limit: 1, used: 0, remaining: 1 }), "1 of 1 invite left");
75 assert.equal(remainingLine({ limit: 5, used: 5, remaining: 0 }), "You have used all 5 of your invites");
76 assert.equal(remainingLine({ limit: null, used: 40, remaining: null }), "No limit on your invites");
77});
78
79test("bots that fill the hidden field or answer instantly are turned away", () => {
80 const form = (fields: Record<string, string>) => ({ get: (name: string) => fields[name] ?? null });
81 const now = 1_000_000;
82 assert.equal(looksAutomated(form({ website: "http://spam.example" }), now), true);
83 assert.equal(looksAutomated(form({ started: String(now - 200) }), now), true);
84 assert.equal(looksAutomated(form({ started: String(now - 10_000) }), now), false);
85 assert.equal(looksAutomated(form({}), now), false);
86 assert.equal(looksAutomated(form({ website: " " }), now), false);
87});
88
89test("a username is suggested from the invited address", () => {
90 assert.equal(suggestUsername("ada.lovelace@example.com"), "ada-lovelace");
91 assert.equal(suggestUsername("Margaret_Hamilton+g1t@example.com"), "margaret-hamilton");
92 assert.equal(suggestUsername("--x--@example.com"), "x");
93 assert.equal(suggestUsername(`${"a".repeat(38)}.b@example.com`), "a".repeat(38));
94 assert.equal(suggestUsername("...@example.com"), "");
95 assert.equal(suggestUsername(null), "");
96});
97
98test("an invite lands in its workspace, else its repository", () => {
99 assert.equal(landingFor({ workspace: { slug: "Flagon-IO" }, repository: null }), "flagon-io");
100 assert.equal(landingFor({ workspace: null, repository: { name: "flagon-io/g1t" } }), "flagon-io/g1t");
101 assert.equal(landingFor({ workspace: null, repository: null }), null);
102});
103
104test("the welcome is for one place, and ends", () => {
105 const set = welcomeCookie("flagon-io/g1t", true);
106 assert.match(set, /^g1t_welcome=flagon-io%2Fg1t; Path=\/; Max-Age=300; HttpOnly; SameSite=Lax; Secure$/);
107 const header = `a=1; ${set.split(";")[0]}; b=2`;
108 assert.equal(welcomes(header, "flagon-io/g1t"), true);
109 assert.equal(welcomes(header, "flagon-io"), false);
110 assert.equal(welcomes("g1t_welcome=flagon-io", "Flagon-IO"), true);
111 assert.equal(welcomes("g1t_welcome=%E0%A4%A", "flagon-io"), false);
112 assert.equal(welcomes("g1t_welcome=..%2F..%2Fx", "../../x"), false);
113 assert.equal(welcomes(null, "flagon-io"), false);
114 assert.match(clearWelcome(false), /^g1t_welcome=; Path=\/; Max-Age=0; HttpOnly; SameSite=Lax$/);
115});
116
117test("a shared invite link names its group above the sign-up form", () => {
118 assert.equal(sharedInviteLine("Cloudflare judges"), "Invited as part of Cloudflare judges");
119 assert.equal(sharedInviteLine(" Hacker News readers "), "Invited as part of Hacker News readers");
120 // A one-person invite has no group, and says nothing of the kind.
121 assert.equal(sharedInviteLine(null), null);
122 assert.equal(sharedInviteLine(undefined), null);
123 assert.equal(sharedInviteLine(" "), null);
124});
125
126test("a shared invite link is sign-up with its code filled in", () => {
127 assert.equal(sharedInviteLink(CODE), `https://g1t.sh/register?invite=${CODE}`);
128 assert.equal(sharedInviteLink(CODE, "http://localhost:5173/"), `http://localhost:5173/register?invite=${CODE}`);
129 // The register page reads the code back out of its own link.
130 assert.equal(cleanCode(sharedInviteLink(CODE)), CODE);
131});
132
133test("a shared link limited to domains says which, on the email field", () => {
134 assert.equal(sharedDomainsHint([]), undefined);
135 assert.equal(sharedDomainsHint(null), undefined);
136 assert.equal(sharedDomainsHint(["cloudflare.com"]), "This invite is for addresses at cloudflare.com. Use yours there.");
137 assert.equal(
138 sharedDomainsHint(["a.com", "b.com", "c.com"]),
139 "This invite is for addresses at a.com, b.com or c.com. Use yours there.",
140 );
141});