fix(tests): Update migrateSettings tests to match new function signature

- Update tests to pass raw context as first parameter
- Add tests for migration flag to prevent re-runs
- Fix error handling to catch all exceptions properly
- Remove obsolete context property from mockContextProxy
This commit is contained in:
Daniel Riccio 2025-07-02 13:03:27 -05:00
parent f706071c34
commit b4a8a45266
No known key found for this signature in database
GPG key ID: FFD5FD825F8E8209
2 changed files with 129 additions and 40 deletions

View file

@ -4,6 +4,7 @@ import type { ContextProxy } from "../../core/config/ContextProxy"
import type { HistoryItem } from "@roo-code/types"
describe("migrateTaskHistoryWithContextProxy", () => {
let mockContext: any
let mockContextProxy: any
let mockWorkspaceFolder: any
@ -19,7 +20,7 @@ describe("migrateTaskHistoryWithContextProxy", () => {
}
// Mock VSCode context
const mockContext = {
mockContext = {
globalState: {
get: vi.fn(),
update: vi.fn(),
@ -37,7 +38,6 @@ describe("migrateTaskHistoryWithContextProxy", () => {
updateWorkspaceState: vi.fn(),
getWorkspaceState: vi.fn(),
getWorkspaceSettings: vi.fn(),
context: mockContext,
} as any
})
@ -83,16 +83,19 @@ describe("migrateTaskHistoryWithContextProxy", () => {
]
// Mock context.globalState.get to return the raw state with taskHistory
vi.mocked(mockContextProxy.context.globalState.get).mockImplementation((key: string, defaultValue?: any) => {
vi.mocked(mockContext.globalState.get).mockImplementation((key: string, defaultValue?: any) => {
if (key === "globalSettings") {
return { taskHistory: mockTaskHistory }
}
if (key === "taskHistoryMigratedToWorkspace") {
return false
}
return defaultValue
})
vi.mocked(mockContextProxy.getWorkspaceSettings).mockReturnValue({})
// Act
await migrateTaskHistoryWithContextProxy(mockContextProxy, mockWorkspaceFolder)
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
// Should update workspace state with only tasks from current workspace
@ -102,45 +105,51 @@ describe("migrateTaskHistoryWithContextProxy", () => {
])
// Should update global state to keep only tasks from other workspaces
expect(mockContextProxy.context.globalState.update).toHaveBeenCalledWith("globalSettings", {
expect(mockContext.globalState.update).toHaveBeenCalledWith("globalSettings", {
taskHistory: [mockTaskHistory[2]],
})
})
it("should handle empty task history in global state", async () => {
// Arrange
vi.mocked(mockContextProxy.context.globalState.get).mockImplementation((key: string) => {
vi.mocked(mockContext.globalState.get).mockImplementation((key: string) => {
if (key === "globalSettings") {
return { taskHistory: [] }
}
if (key === "taskHistoryMigratedToWorkspace") {
return false
}
return undefined
})
vi.mocked(mockContextProxy.getWorkspaceSettings).mockReturnValue({})
// Act
await migrateTaskHistoryWithContextProxy(mockContextProxy, mockWorkspaceFolder)
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
expect(mockContextProxy.updateWorkspaceState).not.toHaveBeenCalled()
expect(mockContextProxy.context.globalState.update).not.toHaveBeenCalled()
expect(mockContext.globalState.update).not.toHaveBeenCalled()
})
it("should handle undefined task history in global state", async () => {
// Arrange
vi.mocked(mockContextProxy.context.globalState.get).mockImplementation((key: string) => {
vi.mocked(mockContext.globalState.get).mockImplementation((key: string) => {
if (key === "globalSettings") {
return {}
}
if (key === "taskHistoryMigratedToWorkspace") {
return false
}
return undefined
})
vi.mocked(mockContextProxy.getWorkspaceSettings).mockReturnValue({})
// Act
await migrateTaskHistoryWithContextProxy(mockContextProxy, mockWorkspaceFolder)
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
expect(mockContextProxy.updateWorkspaceState).not.toHaveBeenCalled()
expect(mockContextProxy.context.globalState.update).not.toHaveBeenCalled()
expect(mockContext.globalState.update).not.toHaveBeenCalled()
})
it("should merge with existing workspace task history", async () => {
@ -171,16 +180,19 @@ describe("migrateTaskHistoryWithContextProxy", () => {
workspace: "/test/workspace",
}
vi.mocked(mockContextProxy.context.globalState.get).mockImplementation((key: string) => {
vi.mocked(mockContext.globalState.get).mockImplementation((key: string) => {
if (key === "globalSettings") {
return { taskHistory: [globalTask] }
}
if (key === "taskHistoryMigratedToWorkspace") {
return false
}
return undefined
})
vi.mocked(mockContextProxy.getWorkspaceSettings).mockReturnValue({ taskHistory: [existingWorkspaceTask] })
// Act
await migrateTaskHistoryWithContextProxy(mockContextProxy, mockWorkspaceFolder)
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
// Should merge tasks, keeping both existing and migrated
@ -190,7 +202,7 @@ describe("migrateTaskHistoryWithContextProxy", () => {
])
// Should clear the migrated task from global state
expect(mockContextProxy.context.globalState.update).toHaveBeenCalledWith("globalSettings", {})
expect(mockContext.globalState.update).toHaveBeenCalledWith("globalSettings", {})
})
it("should handle tasks without workspacePath", async () => {
@ -208,29 +220,89 @@ describe("migrateTaskHistoryWithContextProxy", () => {
// No workspace property
} as HistoryItem
vi.mocked(mockContextProxy.context.globalState.get).mockImplementation((key: string) => {
vi.mocked(mockContext.globalState.get).mockImplementation((key: string) => {
if (key === "globalSettings") {
return { taskHistory: [taskWithoutPath] }
}
if (key === "taskHistoryMigratedToWorkspace") {
return false
}
return undefined
})
vi.mocked(mockContextProxy.getWorkspaceSettings).mockReturnValue({})
// Act
await migrateTaskHistoryWithContextProxy(mockContextProxy, mockWorkspaceFolder)
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
// Should not migrate tasks without workspace path
expect(mockContextProxy.updateWorkspaceState).not.toHaveBeenCalled()
// Should keep the task in global state
expect(mockContextProxy.context.globalState.update).toHaveBeenCalledWith("globalSettings", {
expect(mockContext.globalState.update).toHaveBeenCalledWith("globalSettings", {
taskHistory: [taskWithoutPath],
})
})
it("should handle no workspace folder", async () => {
// Arrange
vi.mocked(mockContextProxy.context.globalState.get).mockImplementation((key: string) => {
vi.mocked(mockContext.globalState.get).mockImplementation((key: string) => {
if (key === "globalSettings") {
return {
taskHistory: [
{
id: "task1",
number: 1,
ts: Date.now(),
task: "Test task",
tokensIn: 100,
tokensOut: 50,
cacheWrites: 0,
cacheReads: 0,
totalCost: 0.01,
workspace: "/test/workspace",
},
],
}
}
if (key === "taskHistoryMigratedToWorkspace") {
return false
}
return undefined
})
// Act
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, undefined)
// Assert
// Should not perform any migration without a workspace
expect(mockContextProxy.updateWorkspaceState).not.toHaveBeenCalled()
expect(mockContext.globalState.update).not.toHaveBeenCalled()
})
it("should handle errors gracefully", async () => {
// Arrange
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {})
vi.mocked(mockContext.globalState.get).mockImplementation(() => {
throw new Error("Failed to get global state")
})
// Act
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
expect(consoleSpy).toHaveBeenCalledWith("Failed to migrate task history to workspace:", expect.any(Error))
expect(mockContextProxy.updateWorkspaceState).not.toHaveBeenCalled()
expect(mockContext.globalState.update).not.toHaveBeenCalled()
consoleSpy.mockRestore()
})
it("should skip migration if already migrated", async () => {
// Arrange
vi.mocked(mockContext.globalState.get).mockImplementation((key: string) => {
if (key === "taskHistoryMigratedToWorkspace") {
return true // Already migrated
}
if (key === "globalSettings") {
return {
taskHistory: [
@ -253,29 +325,47 @@ describe("migrateTaskHistoryWithContextProxy", () => {
})
// Act
await migrateTaskHistoryWithContextProxy(mockContextProxy, undefined)
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
// Should not perform any migration without a workspace
// Should not perform any migration operations
expect(mockContextProxy.updateWorkspaceState).not.toHaveBeenCalled()
expect(mockContextProxy.context.globalState.update).not.toHaveBeenCalled()
expect(mockContext.globalState.update).not.toHaveBeenCalled()
})
it("should handle errors gracefully", async () => {
it("should set migration flag after successful migration", async () => {
// Arrange
const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {})
vi.mocked(mockContextProxy.context.globalState.get).mockImplementation(() => {
throw new Error("Failed to get global state")
const mockTaskHistory: HistoryItem[] = [
{
id: "task1",
number: 1,
ts: Date.now(),
task: "Test task",
tokensIn: 100,
tokensOut: 50,
cacheWrites: 0,
cacheReads: 0,
totalCost: 0.01,
workspace: "/test/workspace",
},
]
vi.mocked(mockContext.globalState.get).mockImplementation((key: string) => {
if (key === "globalSettings") {
return { taskHistory: mockTaskHistory }
}
if (key === "taskHistoryMigratedToWorkspace") {
return false
}
return undefined
})
vi.mocked(mockContextProxy.getWorkspaceSettings).mockReturnValue({})
// Act
await migrateTaskHistoryWithContextProxy(mockContextProxy, mockWorkspaceFolder)
await migrateTaskHistoryWithContextProxy(mockContext, mockContextProxy, mockWorkspaceFolder)
// Assert
expect(consoleSpy).toHaveBeenCalledWith("Failed to migrate task history to workspace:", expect.any(Error))
expect(mockContextProxy.updateWorkspaceState).not.toHaveBeenCalled()
expect(mockContextProxy.context.globalState.update).not.toHaveBeenCalled()
consoleSpy.mockRestore()
// Should set the migration flag
expect(mockContext.globalState.update).toHaveBeenCalledWith("taskHistoryMigratedToWorkspace", true)
})
})

View file

@ -134,16 +134,15 @@ export async function migrateTaskHistoryWithContextProxy(
contextProxy: ContextProxy,
workspaceFolder: vscode.WorkspaceFolder | undefined,
): Promise<void> {
const alreadyMigrated = context.globalState.get<boolean>(TASK_HISTORY_MIGRATION_KEY)
if (alreadyMigrated) {
return
}
if (!workspaceFolder) {
return
}
try {
const alreadyMigrated = context.globalState.get<boolean>(TASK_HISTORY_MIGRATION_KEY)
if (alreadyMigrated) {
return
}
if (!workspaceFolder) {
return
}
// Get the raw global state directly from context
const rawGlobalState = context.globalState.get<any>("globalSettings", {})
const taskHistory = rawGlobalState.taskHistory as HistoryItem[] | undefined