mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 08:35:57 +00:00
feat: vendor permission system source
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { MergedScopes } from "#src/scope-merge";
|
||||
import { mergeScopesWithOrigins } from "#src/scope-merge";
|
||||
|
||||
describe("mergeScopesWithOrigins", () => {
|
||||
it("returns empty result for empty scopes array", () => {
|
||||
const result: MergedScopes = mergeScopesWithOrigins([]);
|
||||
expect(result.mergedPermission).toEqual({});
|
||||
expect(result.origins.size).toBe(0);
|
||||
});
|
||||
|
||||
it("attributes a string surface value to the contributing scope via the '*' pattern", () => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
["global", { permission: { bash: "allow" } }],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({ bash: "allow" });
|
||||
expect(result.origins.get("bash")?.get("*")).toBe("global");
|
||||
});
|
||||
|
||||
it("attributes each pattern of an object surface value to the contributing scope", () => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
[
|
||||
"project",
|
||||
{ permission: { bash: { "git *": "allow", "npm *": "deny" } } },
|
||||
],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({
|
||||
bash: { "git *": "allow", "npm *": "deny" },
|
||||
});
|
||||
expect(result.origins.get("bash")?.get("git *")).toBe("project");
|
||||
expect(result.origins.get("bash")?.get("npm *")).toBe("project");
|
||||
});
|
||||
|
||||
it(
|
||||
"shallow-merge: patterns not redefined by the higher scope keep their lower-scope origin;" +
|
||||
" patterns the higher scope defines switch to the higher scope",
|
||||
() => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
[
|
||||
"global",
|
||||
{ permission: { bash: { "ls *": "allow", "git *": "allow" } } },
|
||||
],
|
||||
["project", { permission: { bash: { "git *": "deny" } } }],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({
|
||||
bash: { "ls *": "allow", "git *": "deny" },
|
||||
});
|
||||
// "ls *" was not touched by project — retains global attribution
|
||||
expect(result.origins.get("bash")?.get("ls *")).toBe("global");
|
||||
// "git *" was overridden by project — switches to project attribution
|
||||
expect(result.origins.get("bash")?.get("git *")).toBe("project");
|
||||
},
|
||||
);
|
||||
|
||||
it("full replacement (string over object): higher scope re-attributes the entire surface to its own origin", () => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
["global", { permission: { bash: { "ls *": "allow" } } }],
|
||||
["project", { permission: { bash: "deny" } }],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({ bash: "deny" });
|
||||
// The string value produces a single "*" pattern for the replacing scope
|
||||
expect(result.origins.get("bash")?.get("*")).toBe("project");
|
||||
// The former "ls *" pattern from global is gone — origins are replaced, not merged
|
||||
expect(result.origins.get("bash")?.has("ls *")).toBe(false);
|
||||
});
|
||||
|
||||
it("full replacement (object over string): higher scope re-attributes the entire surface to its own origin", () => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
["global", { permission: { bash: "ask" } }],
|
||||
["project", { permission: { bash: { "git *": "deny" } } }],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({ bash: { "git *": "deny" } });
|
||||
// The object value attributes each pattern to the replacing scope
|
||||
expect(result.origins.get("bash")?.get("git *")).toBe("project");
|
||||
// The former "*" attribution from global is gone
|
||||
expect(result.origins.get("bash")?.has("*")).toBe(false);
|
||||
});
|
||||
|
||||
it("applies four-scope precedence in lowest→highest order (global → project → agent → project-agent)", () => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
["global", { permission: { read: "ask" } }],
|
||||
["project", { permission: { write: "deny" } }],
|
||||
["agent", { permission: { bash: "deny" } }],
|
||||
["project-agent", { permission: { mcp: "allow" } }],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({
|
||||
read: "ask",
|
||||
write: "deny",
|
||||
bash: "deny",
|
||||
mcp: "allow",
|
||||
});
|
||||
expect(result.origins.get("read")?.get("*")).toBe("global");
|
||||
expect(result.origins.get("write")?.get("*")).toBe("project");
|
||||
expect(result.origins.get("bash")?.get("*")).toBe("agent");
|
||||
expect(result.origins.get("mcp")?.get("*")).toBe("project-agent");
|
||||
});
|
||||
|
||||
it("skips scopes with no permission key, contributing nothing to either map", () => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
["global", {}],
|
||||
["project", { permission: { bash: "allow" } }],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({ bash: "allow" });
|
||||
expect(result.origins.get("bash")?.get("*")).toBe("project");
|
||||
});
|
||||
|
||||
it("attributes the universal '*' surface like any other (downstream reads origins.get('*')?.get('*') for universalFallbackOrigin)", () => {
|
||||
const result = mergeScopesWithOrigins([
|
||||
["global", { permission: { "*": "deny" } }],
|
||||
["project", { permission: { "*": "allow" } }],
|
||||
]);
|
||||
expect(result.mergedPermission).toEqual({ "*": "allow" });
|
||||
// Both scopes write a string — each is a full replacement; project wins last
|
||||
expect(result.origins.get("*")?.get("*")).toBe("project");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user