mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 16:45:22 +00:00
feat: vendor permission system source
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { ParentAuthorizer } from "#src/authority/approval-escalator";
|
||||
import { selectAuthorizer } from "#src/authority/authorizer";
|
||||
import { DenyingAuthorizer } from "#src/authority/denying-authorizer";
|
||||
import { LocalUserAuthorizer } from "#src/authority/local-user-authorizer";
|
||||
import {
|
||||
makeAuthorizerSelectionDeps as makeDeps,
|
||||
makeDetection,
|
||||
} from "#test/helpers/authorizer-fixtures";
|
||||
|
||||
// ── Helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
function makeCtx(hasUI: boolean): ExtensionContext {
|
||||
return {
|
||||
hasUI,
|
||||
mode: "tui",
|
||||
ui: { select: vi.fn(), input: vi.fn(), custom: vi.fn() },
|
||||
sessionManager: {
|
||||
getSessionId: vi.fn().mockReturnValue("session-1"),
|
||||
getSessionDir: vi.fn().mockReturnValue("/sessions/session-1"),
|
||||
getEntries: vi.fn().mockReturnValue([]),
|
||||
},
|
||||
} as unknown as ExtensionContext;
|
||||
}
|
||||
|
||||
// ── Tests ─────────────────────────────────────────────────────────────────
|
||||
|
||||
describe("selectAuthorizer", () => {
|
||||
describe("terminal dispatch", () => {
|
||||
it("selects LocalUserAuthorizer when the context has UI", () => {
|
||||
const authority = selectAuthorizer(makeCtx(true), makeDeps());
|
||||
expect(authority.terminal).toBeInstanceOf(LocalUserAuthorizer);
|
||||
});
|
||||
|
||||
it("selects LocalUserAuthorizer even when the context is also a subagent", () => {
|
||||
const authority = selectAuthorizer(
|
||||
makeCtx(true),
|
||||
makeDeps({ detection: makeDetection(true) }),
|
||||
);
|
||||
expect(authority.terminal).toBeInstanceOf(LocalUserAuthorizer);
|
||||
});
|
||||
|
||||
it("selects ParentAuthorizer when there is no UI but the context is a subagent", () => {
|
||||
const authority = selectAuthorizer(
|
||||
makeCtx(false),
|
||||
makeDeps({ detection: makeDetection(true) }),
|
||||
);
|
||||
expect(authority.terminal).toBeInstanceOf(ParentAuthorizer);
|
||||
});
|
||||
|
||||
it("selects DenyingAuthorizer when there is no UI and no subagent", () => {
|
||||
const authority = selectAuthorizer(
|
||||
makeCtx(false),
|
||||
makeDeps({ detection: makeDetection(false) }),
|
||||
);
|
||||
expect(authority.terminal).toBeInstanceOf(DenyingAuthorizer);
|
||||
});
|
||||
});
|
||||
|
||||
describe("chain role", () => {
|
||||
it("adjudicates locally when the terminal is the human", () => {
|
||||
const authority = selectAuthorizer(makeCtx(true), makeDeps());
|
||||
expect(authority.adjudicatesLocally).toBe(true);
|
||||
});
|
||||
|
||||
it("adjudicates locally when a subagent has its own UI", () => {
|
||||
const authority = selectAuthorizer(
|
||||
makeCtx(true),
|
||||
makeDeps({ detection: makeDetection(true) }),
|
||||
);
|
||||
expect(authority.adjudicatesLocally).toBe(true);
|
||||
});
|
||||
|
||||
it("relays instead of adjudicating when the terminal forwards to a serving node", () => {
|
||||
const authority = selectAuthorizer(
|
||||
makeCtx(false),
|
||||
makeDeps({ detection: makeDetection(true) }),
|
||||
);
|
||||
expect(authority.adjudicatesLocally).toBe(false);
|
||||
});
|
||||
|
||||
it("adjudicates locally when the terminal denies for want of authority", () => {
|
||||
const authority = selectAuthorizer(
|
||||
makeCtx(false),
|
||||
makeDeps({ detection: makeDetection(false) }),
|
||||
);
|
||||
expect(authority.adjudicatesLocally).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user