Skip to content

g1t/apps/web/app/lib/rules.test.ts

85 lines4,116 bytesCodeBlame
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import {
5 ALL,
6 DEFAULT_BRANCH,
7 RULES,
8 describeAppliesTo,
9 describeBypassActor,
10 exportRuleset,
11 importRuleset,
12 newRule,
13 newRuleset,
14 ruleInfo,
15 targetSummary,
16} from "./rules.ts";
17
18test("a new ruleset protects the default branch, and a workspace's holds everywhere", () => {
19 const repo = newRuleset("repository");
20 assert.deepEqual(repo.conditions.ref_name.include, [DEFAULT_BRANCH]);
21 assert.equal(repo.conditions.repository, undefined);
22 assert.equal(repo.enforcement, "active");
23 const workspace = newRuleset("workspace");
24 assert.deepEqual(workspace.conditions.repository?.include, [ALL]);
25});
26
27test("every rule type has a label, a group and its defaults", () => {
28 const types = new Set(RULES.map((rule) => rule.type));
29 assert.equal(types.size, RULES.length, "each type once");
30 assert.equal(RULES.length, 26);
31 for (const rule of RULES) {
32 assert.ok(rule.label && rule.about && rule.targets.length > 0, rule.type);
33 }
34 const pull = newRule("pull_request", "agents");
35 assert.equal(pull.applies_to, "agents");
36 assert.equal(pull.type === "pull_request" && pull.parameters.required_approvals, 1);
37 // A new rule's parameters are its own, not the defaults themselves.
38 const a = newRule("file_path_restriction");
39 if (a.type === "file_path_restriction") a.parameters.restricted_file_paths.push("x");
40 const info = ruleInfo("file_path_restriction")!;
41 assert.deepEqual((info.defaults as { restricted_file_paths: string[] }).restricted_file_paths, []);
42 assert.equal(ruleInfo("no_such_rule"), undefined);
43});
44
45test("an export imports back as it was", () => {
46 const ruleset = {
47 ...newRuleset("repository"),
48 name: "Protect main",
49 rules: [newRule("deletion"), newRule("cost_cap", "agents")],
50 };
51 const text = JSON.stringify({ ...exportRuleset(ruleset), id: "rs_1", created_by: "ada" });
52 const back = importRuleset(text, "repository");
53 assert.deepEqual(back, exportRuleset(ruleset));
54});
55
56test("an import fills in what it leaves out and refuses what is not a ruleset", () => {
57 const spec = importRuleset(
58 JSON.stringify({ ruleset_name: "From the API", enforcement: "nonsense", rules: [{ type: "max_file_size", parameters: { max_file_size_mb: 5 } }] }),
59 "workspace",
60 );
61 assert.equal(spec.name, "From the API");
62 assert.equal(spec.enforcement, "active");
63 assert.equal(spec.rules[0]?.applies_to, "everyone");
64 assert.deepEqual(spec.conditions.repository?.include, [ALL]);
65 assert.equal(spec.rules[0]?.type === "max_file_size" && spec.rules[0].parameters.max_file_size_mb, 5);
66 assert.throws(() => importRuleset("{", "repository"), /not JSON/);
67 assert.throws(() => importRuleset("[]", "repository"), /one JSON object/);
68 assert.throws(() => importRuleset(JSON.stringify({ rules: [{ type: "teleport" }] }), "repository"), /teleport is not a rule type/);
69});
70
71test("who may bypass, and whose changes a rule holds for, read plainly", () => {
72 assert.equal(describeBypassActor({ kind: "role", value: "maintain", mode: "always" }), "Maintain role and up");
73 assert.equal(describeBypassActor({ kind: "role", value: "owner", mode: "always" }), "Workspace owners");
74 assert.equal(describeBypassActor({ kind: "team", value: "acme/release", mode: "pull_requests" }), "@acme/release");
75 assert.equal(describeBypassActor({ kind: "g1t", value: "", mode: "always" }), "g1t");
76 assert.equal(describeBypassActor({ kind: "token", value: "workspace", mode: "always" }), "The workspace's tokens");
77 assert.equal(describeAppliesTo("agents"), "Agents' changes");
78 assert.equal(describeAppliesTo("everyone"), "Everyone");
79});
80
81test("what a ruleset targets, in a few words", () => {
82 assert.equal(targetSummary({ conditions: { ref_name: { include: [DEFAULT_BRANCH, "release/*"], exclude: [] } } }), "Default branch, release/*");
83 assert.equal(targetSummary({ conditions: { ref_name: { include: [ALL], exclude: ["dependabot/**"] } } }), "All, except dependabot/**");
84 assert.equal(targetSummary({ conditions: { ref_name: { include: [], exclude: [] } } }), "Nothing yet");
85});