mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix(hooks): align tests and handler typing for update flow
- Update hooksSetAllEnabled tests to match global hooksEnabled toggle behavior\n- Add IHookManager.updateHook to test mocks after interface change\n- Narrow hooksUpdateHook events to HookEventType via schema validation
This commit is contained in:
parent
609ff88969
commit
469d7feedd
4 changed files with 31 additions and 59 deletions
|
|
@ -102,6 +102,7 @@ const createMockHookManager = (): IHookManager => ({
|
|||
totalDuration: 0,
|
||||
}),
|
||||
setHookEnabled: vi.fn().mockResolvedValue(undefined),
|
||||
updateHook: vi.fn().mockResolvedValue(undefined),
|
||||
getHookExecutionHistory: vi.fn().mockReturnValue([]),
|
||||
getConfigSnapshot: vi.fn().mockReturnValue({
|
||||
hooksByEvent: new Map(),
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ const createMockHookManager = (): IHookManager => ({
|
|||
totalDuration: 0,
|
||||
}),
|
||||
setHookEnabled: vi.fn().mockResolvedValue(undefined),
|
||||
updateHook: vi.fn().mockResolvedValue(undefined),
|
||||
getHookExecutionHistory: vi.fn().mockReturnValue([]),
|
||||
getConfigSnapshot: vi.fn().mockReturnValue({
|
||||
hooksByEvent: new Map(),
|
||||
|
|
@ -264,45 +265,15 @@ describe("webviewMessageHandler - hooks commands", () => {
|
|||
})
|
||||
|
||||
describe("hooksSetAllEnabled", () => {
|
||||
it("should call setHookEnabled for all hooks in snapshot and postStateToWebview", async () => {
|
||||
const hooksById = new Map<string, ResolvedHook>()
|
||||
hooksById.set("hook-1", {
|
||||
id: "hook-1",
|
||||
event: "PreToolUse" as any,
|
||||
matcher: ".*",
|
||||
command: "echo 1",
|
||||
enabled: true,
|
||||
source: "global" as any,
|
||||
timeout: 30,
|
||||
includeConversationHistory: false,
|
||||
} as any)
|
||||
hooksById.set("hook-2", {
|
||||
id: "hook-2",
|
||||
event: "PostToolUse" as any,
|
||||
matcher: ".*",
|
||||
command: "echo 2",
|
||||
enabled: true,
|
||||
source: "project" as any,
|
||||
timeout: 30,
|
||||
includeConversationHistory: false,
|
||||
} as any)
|
||||
|
||||
vi.mocked(mockHookManager.getConfigSnapshot).mockReturnValue({
|
||||
hooksByEvent: new Map(),
|
||||
hooksById,
|
||||
loadedAt: new Date(),
|
||||
disabledHookIds: new Set(),
|
||||
hasProjectHooks: false,
|
||||
} as HooksConfigSnapshot)
|
||||
|
||||
it("should update global hooksEnabled and postStateToWebview", async () => {
|
||||
await webviewMessageHandler(mockClineProvider, {
|
||||
type: "hooksSetAllEnabled",
|
||||
hooksEnabled: false,
|
||||
})
|
||||
|
||||
expect(mockHookManager.setHookEnabled).toHaveBeenCalledTimes(2)
|
||||
expect(mockHookManager.setHookEnabled).toHaveBeenCalledWith("hook-1", false)
|
||||
expect(mockHookManager.setHookEnabled).toHaveBeenCalledWith("hook-2", false)
|
||||
// hooksSetAllEnabled no longer iterates hooks; it toggles global state.
|
||||
expect(mockHookManager.setHookEnabled).not.toHaveBeenCalled()
|
||||
expect((mockClineProvider as any).contextProxy.setValue).toHaveBeenCalledWith("hooksEnabled", false)
|
||||
expect(mockClineProvider.postStateToWebview).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
|
|
@ -313,39 +284,22 @@ describe("webviewMessageHandler - hooks commands", () => {
|
|||
} as any)
|
||||
|
||||
expect(mockHookManager.setHookEnabled).not.toHaveBeenCalled()
|
||||
expect((mockClineProvider as any).contextProxy.setValue).not.toHaveBeenCalled()
|
||||
expect(mockClineProvider.postStateToWebview).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should show error message when bulk setHookEnabled fails", async () => {
|
||||
const hooksById = new Map<string, ResolvedHook>()
|
||||
hooksById.set("hook-1", {
|
||||
id: "hook-1",
|
||||
event: "PreToolUse" as any,
|
||||
matcher: ".*",
|
||||
command: "echo 1",
|
||||
enabled: true,
|
||||
source: "global" as any,
|
||||
timeout: 30,
|
||||
includeConversationHistory: false,
|
||||
} as any)
|
||||
|
||||
vi.mocked(mockHookManager.getConfigSnapshot).mockReturnValue({
|
||||
hooksByEvent: new Map(),
|
||||
hooksById,
|
||||
loadedAt: new Date(),
|
||||
disabledHookIds: new Set(),
|
||||
hasProjectHooks: false,
|
||||
} as HooksConfigSnapshot)
|
||||
|
||||
vi.mocked(mockHookManager.setHookEnabled).mockRejectedValueOnce(new Error("boom"))
|
||||
it("should show error message when updating hooksEnabled global state fails", async () => {
|
||||
vi.mocked((mockClineProvider as any).contextProxy.setValue).mockRejectedValueOnce(new Error("boom"))
|
||||
|
||||
await webviewMessageHandler(mockClineProvider, {
|
||||
type: "hooksSetAllEnabled",
|
||||
hooksEnabled: true,
|
||||
})
|
||||
|
||||
expect(mockClineProvider.log).toHaveBeenCalledWith("Failed to set all hooks enabled: boom")
|
||||
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Failed to enable all hooks")
|
||||
expect(mockHookManager.setHookEnabled).not.toHaveBeenCalled()
|
||||
expect(mockClineProvider.postStateToWebview).not.toHaveBeenCalled()
|
||||
expect(mockClineProvider.log).toHaveBeenCalledWith("Failed to set hooks enabled: boom")
|
||||
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Failed to enable hooks")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ import { safeWriteText } from "../../utils/safeWriteText"
|
|||
import * as path from "path"
|
||||
import * as os from "os"
|
||||
import * as fs from "fs/promises"
|
||||
import {
|
||||
HookEventType as HookEventTypeSchema,
|
||||
type HookEventType,
|
||||
type HookUpdateData,
|
||||
} from "../../services/hooks/types"
|
||||
import { getRooDirectoriesForCwd } from "../../services/roo-config/index.js"
|
||||
import pWaitFor from "p-wait-for"
|
||||
import * as vscode from "vscode"
|
||||
|
|
@ -3559,7 +3564,18 @@ export const webviewMessageHandler = async (
|
|||
}
|
||||
|
||||
try {
|
||||
await hookManager.updateHook(message.filePath, message.hookId, message.hookUpdates)
|
||||
const hookUpdates: HookUpdateData = {
|
||||
// Webview messages are not strongly typed, so validate and narrow.
|
||||
events: Array.isArray(message.hookUpdates.events)
|
||||
? message.hookUpdates.events.filter(
|
||||
(event): event is HookEventType => HookEventTypeSchema.safeParse(event).success,
|
||||
)
|
||||
: undefined,
|
||||
matcher: typeof message.hookUpdates.matcher === "string" ? message.hookUpdates.matcher : undefined,
|
||||
timeout: typeof message.hookUpdates.timeout === "number" ? message.hookUpdates.timeout : undefined,
|
||||
}
|
||||
|
||||
await hookManager.updateHook(message.filePath, message.hookId, hookUpdates)
|
||||
await hookManager.reloadHooksConfig()
|
||||
await provider.postStateToWebview()
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ describe("ToolExecutionHooks", () => {
|
|||
totalDuration: 100,
|
||||
} as HooksExecutionResult),
|
||||
setHookEnabled: vi.fn(),
|
||||
updateHook: vi.fn(),
|
||||
getEnabledHooks: vi.fn().mockReturnValue([]),
|
||||
getHookExecutionHistory: vi.fn().mockReturnValue([]),
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue