Initial commit
This commit is contained in:
162
test/permissions.test.ts
Normal file
162
test/permissions.test.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import { describe, expect, test, spyOn, beforeEach, afterEach } from "bun:test";
|
||||
import * as core from "@actions/core";
|
||||
import { checkWritePermissions } from "../src/github/validation/permissions";
|
||||
import type { ParsedGitHubContext } from "../src/github/context";
|
||||
|
||||
describe("checkWritePermissions", () => {
|
||||
let coreInfoSpy: any;
|
||||
let coreWarningSpy: any;
|
||||
let coreErrorSpy: any;
|
||||
|
||||
beforeEach(() => {
|
||||
// Spy on core methods
|
||||
coreInfoSpy = spyOn(core, "info").mockImplementation(() => {});
|
||||
coreWarningSpy = spyOn(core, "warning").mockImplementation(() => {});
|
||||
coreErrorSpy = spyOn(core, "error").mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
coreInfoSpy.mockRestore();
|
||||
coreWarningSpy.mockRestore();
|
||||
coreErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
const createMockOctokit = (permission: string) => {
|
||||
return {
|
||||
repos: {
|
||||
getCollaboratorPermissionLevel: async () => ({
|
||||
data: { permission },
|
||||
}),
|
||||
},
|
||||
} as any;
|
||||
};
|
||||
|
||||
const createContext = (): ParsedGitHubContext => ({
|
||||
runId: "1234567890",
|
||||
eventName: "issue_comment",
|
||||
eventAction: "created",
|
||||
repository: {
|
||||
full_name: "test-owner/test-repo",
|
||||
owner: "test-owner",
|
||||
repo: "test-repo",
|
||||
},
|
||||
actor: "test-user",
|
||||
payload: {
|
||||
action: "created",
|
||||
issue: {
|
||||
number: 1,
|
||||
title: "Test Issue",
|
||||
body: "Test body",
|
||||
user: { login: "test-user" },
|
||||
},
|
||||
comment: {
|
||||
id: 123,
|
||||
body: "@claude test",
|
||||
user: { login: "test-user" },
|
||||
html_url:
|
||||
"https://github.com/test-owner/test-repo/issues/1#issuecomment-123",
|
||||
},
|
||||
} as any,
|
||||
entityNumber: 1,
|
||||
isPR: false,
|
||||
inputs: {
|
||||
triggerPhrase: "@claude",
|
||||
assigneeTrigger: "",
|
||||
allowedTools: "",
|
||||
disallowedTools: "",
|
||||
customInstructions: "",
|
||||
directPrompt: "",
|
||||
},
|
||||
});
|
||||
|
||||
test("should return true for admin permissions", async () => {
|
||||
const mockOctokit = createMockOctokit("admin");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(mockOctokit, context);
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(coreInfoSpy).toHaveBeenCalledWith(
|
||||
"Checking permissions for actor: test-user",
|
||||
);
|
||||
expect(coreInfoSpy).toHaveBeenCalledWith(
|
||||
"Permission level retrieved: admin",
|
||||
);
|
||||
expect(coreInfoSpy).toHaveBeenCalledWith("Actor has write access: admin");
|
||||
});
|
||||
|
||||
test("should return true for write permissions", async () => {
|
||||
const mockOctokit = createMockOctokit("write");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(mockOctokit, context);
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(coreInfoSpy).toHaveBeenCalledWith("Actor has write access: write");
|
||||
});
|
||||
|
||||
test("should return false for read permissions", async () => {
|
||||
const mockOctokit = createMockOctokit("read");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(mockOctokit, context);
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"Actor has insufficient permissions: read",
|
||||
);
|
||||
});
|
||||
|
||||
test("should return false for none permissions", async () => {
|
||||
const mockOctokit = createMockOctokit("none");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(mockOctokit, context);
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"Actor has insufficient permissions: none",
|
||||
);
|
||||
});
|
||||
|
||||
test("should throw error when permission check fails", async () => {
|
||||
const error = new Error("API error");
|
||||
const mockOctokit = {
|
||||
repos: {
|
||||
getCollaboratorPermissionLevel: async () => {
|
||||
throw error;
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const context = createContext();
|
||||
|
||||
await expect(checkWritePermissions(mockOctokit, context)).rejects.toThrow(
|
||||
"Failed to check permissions for test-user: Error: API error",
|
||||
);
|
||||
|
||||
expect(coreErrorSpy).toHaveBeenCalledWith(
|
||||
"Failed to check permissions: Error: API error",
|
||||
);
|
||||
});
|
||||
|
||||
test("should call API with correct parameters", async () => {
|
||||
let capturedParams: any;
|
||||
const mockOctokit = {
|
||||
repos: {
|
||||
getCollaboratorPermissionLevel: async (params: any) => {
|
||||
capturedParams = params;
|
||||
return { data: { permission: "write" } };
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const context = createContext();
|
||||
|
||||
await checkWritePermissions(mockOctokit, context);
|
||||
|
||||
expect(capturedParams).toEqual({
|
||||
owner: "test-owner",
|
||||
repo: "test-repo",
|
||||
username: "test-user",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user