/ opencodehub / tests / unit / pat-scopes.test.ts
Swadhin Biswas Feature/ai code reviewer (#79) · 8/16/2026
cfd400d
54 lines · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { describe, expect, it } from "vitest";
import {
  hasPatScope,
  hasRepoWriteScope,
  PAT_SCOPES,
} from "@/lib/permissions";

describe("fine-grained PAT scope enforcement", () => {
  it("legacy tokens (no scopes) keep full access", () => {
    expect(hasPatScope(undefined, "repo:write")).toBe(true);
    expect(hasPatScope([], "admin")).toBe(true);
  });

  it("allows when the required scope is present", () => {
    expect(hasPatScope(["repo:write"], "repo:write")).toBe(true);
    expect(hasPatScope(["repo:read", "notifications"], "notifications")).toBe(
      true,
    );
  });

  it("blocks when the required scope is absent", () => {
    expect(hasPatScope(["repo:read"], "repo:write")).toBe(false);
    expect(hasPatScope(["repo:read"], "admin")).toBe(false);
    expect(hasPatScope(["notifications"], "repo:read")).toBe(false);
  });

  it("admin scope implies all other scopes", () => {
    expect(hasPatScope(["admin"], "repo:write")).toBe(true);
    expect(hasPatScope(["admin"], "notifications")).toBe(true);
    expect(hasPatScope(["admin"], ["repo:read", "repo:write"])).toBe(true);
  });

  it("requires ALL scopes when an array is given", () => {
    expect(
      hasPatScope(["repo:read", "repo:write"], ["repo:read", "repo:write"]),
    ).toBe(true);
    expect(hasPatScope(["repo:read"], ["repo:read", "repo:write"])).toBe(false);
  });

  it("hasRepoWriteScope blocks read-only tokens from writes", () => {
    expect(hasRepoWriteScope(undefined)).toBe(true);
    expect(hasRepoWriteScope(["repo:write"])).toBe(true);
    expect(hasRepoWriteScope(["repo:read"])).toBe(false);
    expect(hasRepoWriteScope(["notifications"])).toBe(false);
  });

  it("exposes a stable scope vocabulary", () => {
    expect(PAT_SCOPES).toContain("repo:read");
    expect(PAT_SCOPES).toContain("repo:write");
    expect(PAT_SCOPES).toContain("admin");
    expect(PAT_SCOPES).toContain("notifications");
  });
});