Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
80 linesCodeBlameRaw
1import { test } from "node:test";
2import assert from "node:assert/strict";
3
4import type { User } from "@g1t/contracts";
5
6import { MAX_REQUEST_NOTE, mayAdmit, mayInviteGuests, mayJoin, mayRead, mayVisit, requestNote, visibilityOf } from "./access.ts";
7
8const person = (over: Partial<User> = {}): User => ({ id: "usr_1", username: "ana", verified: true, ...over });
9
10test("a channel is private, kept to the workspace, or public; a direct message is always private", () => {
11 assert.equal(visibilityOf({ kind: "channel", private: 1, public: 0 }), "private");
12 assert.equal(visibilityOf({ kind: "channel", private: 0, public: 0 }), "workspace");
13 assert.equal(visibilityOf({ kind: "channel", private: 0, public: 1 }), "public");
14 // Private wins: a private channel is never open to anyone.
15 assert.equal(visibilityOf({ kind: "channel", private: 1, public: 1 }), "private");
16 assert.equal(visibilityOf({ kind: "dm", private: 1, public: 1 }), "private");
17});
18
19test("who may read: anyone in it; members for a workspace channel; anyone for a public one", () => {
20 for (const role of ["owner", "member", null] as const) {
21 assert.equal(mayRead("private", role, true), true);
22 assert.equal(mayRead("private", role, false), false);
23 assert.equal(mayRead("public", role, false), true);
24 }
25 assert.equal(mayRead("workspace", "member", false), true);
26 assert.equal(mayRead("workspace", null, false), false);
27 // A guest asked into a workspace channel reads it.
28 assert.equal(mayRead("workspace", null, true), true);
29});
30
31test("someone outside the workspace taken out of a public channel can't join it again on their own", () => {
32 assert.equal(mayJoin("public", null, false, false), true);
33 assert.equal(mayJoin("public", null, true, false), false);
34 // Members are never kept out this way; leaving or being taken out is not a ban for them.
35 assert.equal(mayJoin("public", "member", true, false), true);
36 assert.equal(mayJoin("workspace", null, false, false), false);
37 assert.equal(mayJoin("private", "owner", false, false), false);
38 assert.equal(mayJoin("workspace", "member", false, true), false);
39});
40
41test("owners always invite guests; members while the workspace lets them", () => {
42 const owner = person({ workspaces: [{ slug: "flagon-io", role: "owner" }] });
43 assert.equal(mayInviteGuests(owner, "Flagon-IO"), true);
44 const member = (allowed?: boolean) =>
45 person({
46 workspaces: [
47 {
48 slug: "flagon-io",
49 role: "member",
50 ...(allowed === undefined ? {} : { privileges: { members_can_invite_outside_collaborators: allowed } as never }),
51 },
52 ],
53 });
54 assert.equal(mayInviteGuests(member(), "flagon-io"), true);
55 assert.equal(mayInviteGuests(member(true), "flagon-io"), true);
56 assert.equal(mayInviteGuests(member(false), "flagon-io"), false);
57 assert.equal(mayInviteGuests(person(), "flagon-io"), false);
58 assert.equal(mayInviteGuests(null, "flagon-io"), false);
59});
60
61test("only signed-in people with a confirmed address come in as guests", () => {
62 assert.equal(mayVisit(person()), null);
63 assert.match(mayVisit(null) ?? "", /Sign in/);
64 assert.match(mayVisit(person({ verified: false })) ?? "", /Confirm your email/);
65 assert.match(mayVisit(person({ kind: "workspace" })) ?? "", /Only people/);
66});
67
68test("letting someone in: anyone in the channel for a member; those who invite guests for anyone else", () => {
69 assert.equal(mayAdmit(true, true, false), true);
70 assert.equal(mayAdmit(false, true, false), false);
71 assert.equal(mayAdmit(false, true, true), true);
72 assert.equal(mayAdmit(true, false, true), false);
73});
74
75test("a request's note is trimmed, cut to length, and null when empty", () => {
76 assert.equal(requestNote(" hi "), "hi");
77 assert.equal(requestNote(" "), null);
78 assert.equal(requestNote(42), null);
79 assert.equal(requestNote("x".repeat(MAX_REQUEST_NOTE + 10))?.length, MAX_REQUEST_NOTE);
80});