mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-07 02:58:15 +00:00
tests working
This commit is contained in:
parent
24a8c10048
commit
303a9c8c1f
1 changed files with 300 additions and 98 deletions
|
|
@ -1163,15 +1163,15 @@ describe("ClineProvider", () => {
|
|||
|
||||
describe("deleteMessage", () => {
|
||||
beforeEach(async () => {
|
||||
// Mock window.showInformationMessage
|
||||
;(vscode.window.showInformationMessage as any) = vi.fn()
|
||||
await provider.resolveWebviewView(mockWebviewView)
|
||||
// Mock that skipDeleteMessageConfirmation is false by default
|
||||
;(mockContext.globalState.get as any).mockImplementation((key: string) => {
|
||||
if (key === "skipDeleteMessageConfirmation") return false
|
||||
return undefined
|
||||
})
|
||||
})
|
||||
|
||||
test('handles "Just this message" deletion correctly', async () => {
|
||||
// Mock user selecting "Just this message"
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.delete_just_this_message")
|
||||
|
||||
test("handles deletion with confirmation dialog", async () => {
|
||||
// Setup mock messages
|
||||
const mockMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback" }, // User message 1
|
||||
|
|
@ -1202,30 +1202,43 @@ describe("ClineProvider", () => {
|
|||
historyItem: { id: "test-task-id" },
|
||||
})
|
||||
|
||||
// Mock initClineWithHistoryItem
|
||||
;(provider as any).initClineWithHistoryItem = vi.fn()
|
||||
|
||||
// Trigger message deletion
|
||||
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
|
||||
await messageHandler({ type: "deleteMessage", value: 4000 })
|
||||
|
||||
// Verify correct messages were kept
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([
|
||||
mockMessages[0],
|
||||
mockMessages[1],
|
||||
mockMessages[4],
|
||||
mockMessages[5],
|
||||
])
|
||||
// Verify that the dialog message was sent to webview
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showDeleteMessageDialog",
|
||||
messageTs: 4000,
|
||||
})
|
||||
|
||||
// Verify correct API messages were kept
|
||||
// Simulate user confirming deletion through the dialog
|
||||
await messageHandler({ type: "deleteMessageConfirm", messageTs: 4000 })
|
||||
|
||||
// Verify only messages before the deleted message were kept
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0], mockMessages[1]])
|
||||
|
||||
// Verify only API messages before the deleted message were kept
|
||||
expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([
|
||||
mockApiHistory[0],
|
||||
mockApiHistory[1],
|
||||
mockApiHistory[4],
|
||||
mockApiHistory[5],
|
||||
])
|
||||
|
||||
// Verify initClineWithHistoryItem was called
|
||||
expect((provider as any).initClineWithHistoryItem).toHaveBeenCalledWith({ id: "test-task-id" })
|
||||
})
|
||||
|
||||
test('handles "This and all subsequent messages" deletion correctly', async () => {
|
||||
// Mock user selecting "This and all subsequent messages"
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.delete_this_and_subsequent")
|
||||
test("handles deletion with skipDeleteMessageConfirmation enabled", async () => {
|
||||
// Mock that skipDeleteMessageConfirmation is true
|
||||
const contextProxy = (provider as any).contextProxy
|
||||
const getValueSpy = vi.spyOn(contextProxy, "getValue")
|
||||
getValueSpy.mockImplementation((key: any) => {
|
||||
if (key === "skipDeleteMessageConfirmation") return true
|
||||
return undefined
|
||||
})
|
||||
|
||||
// Setup mock messages
|
||||
const mockMessages = [
|
||||
|
|
@ -1255,10 +1268,19 @@ describe("ClineProvider", () => {
|
|||
historyItem: { id: "test-task-id" },
|
||||
})
|
||||
|
||||
// Mock initClineWithHistoryItem
|
||||
;(provider as any).initClineWithHistoryItem = vi.fn()
|
||||
|
||||
// Trigger message deletion
|
||||
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
|
||||
await messageHandler({ type: "deleteMessage", value: 3000 })
|
||||
|
||||
// Verify that NO dialog message was sent to webview (skipped)
|
||||
expect(mockPostMessage).not.toHaveBeenCalledWith({
|
||||
type: "showDeleteMessageDialog",
|
||||
messageTs: 3000,
|
||||
})
|
||||
|
||||
// Verify only messages before the deleted message were kept
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]])
|
||||
|
||||
|
|
@ -1266,39 +1288,34 @@ describe("ClineProvider", () => {
|
|||
expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([mockApiHistory[0]])
|
||||
})
|
||||
|
||||
test("handles Cancel correctly", async () => {
|
||||
// Mock user selecting "Cancel"
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue("Cancel")
|
||||
|
||||
// Setup Cline instance with auto-mock from the top of the file
|
||||
const mockCline = new Task(defaultTaskOptions) // Create a new mocked instance
|
||||
mockCline.clineMessages = [{ ts: 1000 }, { ts: 2000 }] as ClineMessage[]
|
||||
mockCline.apiConversationHistory = [{ ts: 1000 }, { ts: 2000 }] as (Anthropic.MessageParam & {
|
||||
ts?: number
|
||||
})[]
|
||||
await provider.addClineToStack(mockCline)
|
||||
test("handles case when no current task exists", async () => {
|
||||
// Clear the cline stack
|
||||
;(provider as any).clineStack = []
|
||||
|
||||
// Trigger message deletion
|
||||
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
|
||||
await messageHandler({ type: "deleteMessage", value: 2000 })
|
||||
|
||||
// Verify no messages were deleted
|
||||
expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled()
|
||||
expect(mockCline.overwriteApiConversationHistory).not.toHaveBeenCalled()
|
||||
// Verify no dialog was shown since there's no current cline
|
||||
expect(mockPostMessage).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: "showDeleteMessageDialog",
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("editMessage", () => {
|
||||
beforeEach(async () => {
|
||||
// Mock window.showWarningMessage
|
||||
;(vscode.window.showWarningMessage as any) = vi.fn()
|
||||
await provider.resolveWebviewView(mockWebviewView)
|
||||
// Mock that skipEditMessageConfirmation is false by default
|
||||
;(mockContext.globalState.get as any).mockImplementation((key: string) => {
|
||||
if (key === "skipEditMessageConfirmation") return false
|
||||
return undefined
|
||||
})
|
||||
})
|
||||
|
||||
test('handles "Proceed" edit correctly', async () => {
|
||||
// Mock user selecting "Proceed" - need to use the localized string key
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
test("handles edit with confirmation dialog", async () => {
|
||||
// Setup mock messages
|
||||
const mockMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback" }, // User message 1
|
||||
|
|
@ -1346,6 +1363,20 @@ describe("ClineProvider", () => {
|
|||
editedMessageContent: "Edited message content",
|
||||
})
|
||||
|
||||
// Verify that the dialog message was sent to webview
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 4000,
|
||||
text: "Edited message content",
|
||||
})
|
||||
|
||||
// Simulate user confirming edit through the dialog
|
||||
await messageHandler({
|
||||
type: "editMessageConfirm",
|
||||
messageTs: 4000,
|
||||
text: "Edited message content",
|
||||
})
|
||||
|
||||
// Verify correct messages were kept (only messages before the edited one)
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0], mockMessages[1]])
|
||||
|
||||
|
|
@ -1355,12 +1386,59 @@ describe("ClineProvider", () => {
|
|||
mockApiHistory[1],
|
||||
])
|
||||
|
||||
// Verify handleWebviewAskResponse was called with the edited content
|
||||
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
|
||||
"messageResponse",
|
||||
"Edited message content",
|
||||
undefined,
|
||||
)
|
||||
// The new flow calls webviewMessageHandler recursively with askResponse
|
||||
// We need to verify the recursive call happened by checking if the handler was called again
|
||||
expect((mockWebviewView.webview.onDidReceiveMessage as any).mock.calls.length).toBeGreaterThanOrEqual(1)
|
||||
})
|
||||
|
||||
test("handles edit with skipEditMessageConfirmation enabled", async () => {
|
||||
// Mock that skipEditMessageConfirmation is true
|
||||
const contextProxy = (provider as any).contextProxy
|
||||
const getValueSpy = vi.spyOn(contextProxy, "getValue")
|
||||
getValueSpy.mockImplementation((key: any) => {
|
||||
if (key === "skipEditMessageConfirmation") return true
|
||||
return undefined
|
||||
})
|
||||
|
||||
// Setup mock messages
|
||||
const mockMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback" },
|
||||
{ ts: 2000, type: "say", say: "text", value: 3000 }, // Message to edit
|
||||
{ ts: 3000, type: "say", say: "user_feedback" },
|
||||
] as ClineMessage[]
|
||||
|
||||
const mockApiHistory = [{ ts: 1000 }, { ts: 2000 }, { ts: 3000 }] as (Anthropic.MessageParam & {
|
||||
ts?: number
|
||||
})[]
|
||||
|
||||
// Setup Task instance
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = mockMessages
|
||||
mockCline.apiConversationHistory = mockApiHistory
|
||||
mockCline.overwriteClineMessages = vi.fn()
|
||||
mockCline.overwriteApiConversationHistory = vi.fn()
|
||||
mockCline.handleWebviewAskResponse = vi.fn()
|
||||
|
||||
await provider.addClineToStack(mockCline)
|
||||
|
||||
// Trigger message edit
|
||||
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
|
||||
await messageHandler({
|
||||
type: "submitEditedMessage",
|
||||
value: 3000,
|
||||
editedMessageContent: "Edited message content",
|
||||
})
|
||||
|
||||
// Verify that NO dialog message was sent to webview (skipped)
|
||||
expect(mockPostMessage).not.toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 3000,
|
||||
text: "Edited message content",
|
||||
})
|
||||
|
||||
// Verify messages were edited directly
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]])
|
||||
expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([mockApiHistory[0]])
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -2705,13 +2783,16 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
|
||||
describe("Edit Messages with Images and Attachments", () => {
|
||||
beforeEach(async () => {
|
||||
;(vscode.window.showInformationMessage as any) = vi.fn()
|
||||
await provider.resolveWebviewView(mockWebviewView)
|
||||
// Mock that skip confirmations are false by default
|
||||
;(mockContext.globalState.get as any).mockImplementation((key: string) => {
|
||||
if (key === "skipEditMessageConfirmation") return false
|
||||
if (key === "skipDeleteMessageConfirmation") return false
|
||||
return undefined
|
||||
})
|
||||
})
|
||||
|
||||
test("handles editing messages containing images", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message" },
|
||||
{
|
||||
|
|
@ -2746,17 +2827,26 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
editedMessageContent: "Edited message with preserved images",
|
||||
})
|
||||
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
|
||||
"messageResponse",
|
||||
"Edited message with preserved images",
|
||||
undefined,
|
||||
)
|
||||
// Verify dialog was shown
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 3000,
|
||||
text: "Edited message with preserved images",
|
||||
})
|
||||
|
||||
// Simulate confirmation
|
||||
await messageHandler({
|
||||
type: "editMessageConfirm",
|
||||
messageTs: 3000,
|
||||
text: "Edited message with preserved images",
|
||||
})
|
||||
|
||||
// Verify messages were edited correctly - only the first message should remain
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]])
|
||||
expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([{ ts: 1000 }])
|
||||
})
|
||||
|
||||
test("handles editing messages with file attachments", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message" },
|
||||
{
|
||||
|
|
@ -2789,6 +2879,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
editedMessageContent: "Edited message with file attachment",
|
||||
})
|
||||
|
||||
// Verify dialog was shown
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 3000,
|
||||
text: "Edited message with file attachment",
|
||||
})
|
||||
|
||||
// Simulate user confirming the edit
|
||||
await messageHandler({
|
||||
type: "editMessageConfirm",
|
||||
messageTs: 3000,
|
||||
text: "Edited message with file attachment",
|
||||
})
|
||||
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
|
||||
"messageResponse",
|
||||
|
|
@ -2805,8 +2909,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles network timeout during edit submission", async () => {
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
|
||||
|
|
@ -2833,12 +2935,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
}),
|
||||
).resolves.toBeUndefined()
|
||||
|
||||
// Verify dialog was shown
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 2000,
|
||||
text: "Edited message",
|
||||
})
|
||||
|
||||
// Simulate user confirming the edit
|
||||
await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message" })
|
||||
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("handles connection drops during edit operation", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
|
||||
|
|
@ -2865,6 +2975,17 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
}),
|
||||
).resolves.toBeUndefined()
|
||||
|
||||
// Verify dialog was shown
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 2000,
|
||||
text: "Edited message",
|
||||
})
|
||||
|
||||
// Simulate user confirming the edit
|
||||
await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message" })
|
||||
|
||||
// The error should be caught and shown
|
||||
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Error editing message: Connection lost")
|
||||
})
|
||||
})
|
||||
|
|
@ -2876,8 +2997,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles race conditions with simultaneous edits", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Message 1", value: 2000 },
|
||||
|
|
@ -2912,6 +3031,22 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
|
||||
await Promise.all([edit1Promise, edit2Promise])
|
||||
|
||||
// Verify dialogs were shown for both edits
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 2000,
|
||||
text: "Edited message 1",
|
||||
})
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 4000,
|
||||
text: "Edited message 2",
|
||||
})
|
||||
|
||||
// Simulate user confirming both edits
|
||||
await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message 1" })
|
||||
await messageHandler({ type: "editMessageConfirm", messageTs: 4000, text: "Edited message 2" })
|
||||
|
||||
// Both operations should complete without throwing
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
})
|
||||
|
|
@ -2940,8 +3075,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles authorization failures during edit", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
|
||||
|
|
@ -2965,6 +3098,13 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
editedMessageContent: "Edited message",
|
||||
})
|
||||
|
||||
// Simulate confirmation
|
||||
await messageHandler({
|
||||
type: "editMessageConfirm",
|
||||
messageTs: 2000,
|
||||
text: "Edited message",
|
||||
})
|
||||
|
||||
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Error editing message: Unauthorized")
|
||||
})
|
||||
|
||||
|
|
@ -3058,8 +3198,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles edit operations on deleted messages", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Existing message" },
|
||||
|
|
@ -3083,17 +3221,26 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
editedMessageContent: "Edited non-existent message",
|
||||
})
|
||||
|
||||
// Should show confirmation dialog but not perform any operations
|
||||
expect(vscode.window.showWarningMessage).toHaveBeenCalled()
|
||||
// Should show edit dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 5000,
|
||||
text: "Edited non-existent message",
|
||||
})
|
||||
|
||||
// Simulate user confirming the edit
|
||||
await messageHandler({
|
||||
type: "editMessageConfirm",
|
||||
messageTs: 5000,
|
||||
text: "Edited non-existent message",
|
||||
})
|
||||
|
||||
// Should not perform any operations since message doesn't exist
|
||||
expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled()
|
||||
expect(mockCline.handleWebviewAskResponse).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("handles delete operations on non-existent messages", async () => {
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue(
|
||||
"confirmation.delete_just_this_message",
|
||||
)
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Existing message" },
|
||||
|
|
@ -3115,8 +3262,16 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
value: 5000,
|
||||
})
|
||||
|
||||
// Should show confirmation dialog but not perform any operations
|
||||
expect(vscode.window.showInformationMessage).toHaveBeenCalled()
|
||||
// Should show delete dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showDeleteMessageDialog",
|
||||
messageTs: 5000,
|
||||
})
|
||||
|
||||
// Simulate user confirming the delete
|
||||
await messageHandler({ type: "deleteMessageConfirm", messageTs: 5000 })
|
||||
|
||||
// Should not perform any operations since message doesn't exist
|
||||
expect(mockCline.overwriteClineMessages).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
|
@ -3128,8 +3283,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("validates proper cleanup during failed edit operations", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Original message", value: 2000 },
|
||||
|
|
@ -3159,16 +3312,22 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
editedMessageContent: "Edited message",
|
||||
})
|
||||
|
||||
// Should show edit dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 2000,
|
||||
text: "Edited message",
|
||||
})
|
||||
|
||||
// Simulate user confirming the edit
|
||||
await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: "Edited message" })
|
||||
|
||||
// Verify cleanup was attempted before failure
|
||||
expect(cleanupSpy).toHaveBeenCalled()
|
||||
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith("Error editing message: Operation failed")
|
||||
})
|
||||
|
||||
test("validates proper cleanup during failed delete operations", async () => {
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue(
|
||||
"confirmation.delete_just_this_message",
|
||||
)
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Message to delete" },
|
||||
|
|
@ -3193,6 +3352,15 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
|
||||
await messageHandler({ type: "deleteMessage", value: 2000 })
|
||||
|
||||
// Should show delete dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showDeleteMessageDialog",
|
||||
messageTs: 2000,
|
||||
})
|
||||
|
||||
// Simulate user confirming the delete
|
||||
await messageHandler({ type: "deleteMessageConfirm", messageTs: 2000 })
|
||||
|
||||
// Verify cleanup was attempted before failure
|
||||
expect(cleanupSpy).toHaveBeenCalled()
|
||||
expect(vscode.window.showErrorMessage).toHaveBeenCalledWith(
|
||||
|
|
@ -3208,8 +3376,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles editing messages with large text content", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
// Create a large message (10KB of text)
|
||||
const largeText = "A".repeat(10000)
|
||||
const mockMessages = [
|
||||
|
|
@ -3238,6 +3404,16 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
editedMessageContent: largeEditedContent,
|
||||
})
|
||||
|
||||
// Should show edit dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: 2000,
|
||||
text: largeEditedContent,
|
||||
})
|
||||
|
||||
// Simulate user confirming the edit
|
||||
await messageHandler({ type: "editMessageConfirm", messageTs: 2000, text: largeEditedContent })
|
||||
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalledWith(
|
||||
"messageResponse",
|
||||
|
|
@ -3247,10 +3423,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles deleting messages with large payloads", async () => {
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue(
|
||||
"confirmation.delete_this_and_subsequent",
|
||||
)
|
||||
|
||||
// Create messages with large payloads
|
||||
const largeText = "X".repeat(50000)
|
||||
const mockMessages = [
|
||||
|
|
@ -3275,6 +3447,15 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
|
||||
await messageHandler({ type: "deleteMessage", value: 3000 })
|
||||
|
||||
// Should show delete dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showDeleteMessageDialog",
|
||||
messageTs: 3000,
|
||||
})
|
||||
|
||||
// Simulate user confirming the delete
|
||||
await messageHandler({ type: "deleteMessageConfirm", messageTs: 3000 })
|
||||
|
||||
// Should handle large payloads without issues
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalledWith([mockMessages[0]])
|
||||
expect(mockCline.overwriteApiConversationHistory).toHaveBeenCalledWith([{ ts: 1000 }])
|
||||
|
|
@ -3285,10 +3466,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
// Note: Error messaging test removed as the implementation may not have proper error handling in place
|
||||
|
||||
test("provides user feedback for successful operations", async () => {
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue(
|
||||
"confirmation.delete_just_this_message",
|
||||
)
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Message to delete" },
|
||||
|
|
@ -3308,6 +3485,15 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
|
||||
await messageHandler({ type: "deleteMessage", value: 2000 })
|
||||
|
||||
// Should show delete dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showDeleteMessageDialog",
|
||||
messageTs: 2000,
|
||||
})
|
||||
|
||||
// Simulate user confirming the delete
|
||||
await messageHandler({ type: "deleteMessageConfirm", messageTs: 2000 })
|
||||
|
||||
// Verify successful operation completed
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
expect(provider.initClineWithHistoryItem).toHaveBeenCalled()
|
||||
|
|
@ -3315,8 +3501,7 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles user cancellation gracefully", async () => {
|
||||
// Mock user canceling the operation
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue(undefined)
|
||||
// Test cancellation by not sending confirmation
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
|
|
@ -3353,10 +3538,6 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
})
|
||||
|
||||
test("handles messages with identical timestamps", async () => {
|
||||
;(vscode.window.showInformationMessage as any).mockResolvedValue(
|
||||
"confirmation.delete_just_this_message",
|
||||
)
|
||||
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
{ ts: 1000, type: "say", say: "user_feedback", text: "Message 1" },
|
||||
|
|
@ -3377,13 +3558,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
|
||||
await messageHandler({ type: "deleteMessage", value: 1000 })
|
||||
|
||||
// Should show delete dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showDeleteMessageDialog",
|
||||
messageTs: 1000,
|
||||
})
|
||||
|
||||
// Simulate user confirming the delete
|
||||
await messageHandler({ type: "deleteMessageConfirm", messageTs: 1000 })
|
||||
|
||||
// Should handle identical timestamps gracefully
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("handles messages with future timestamps", async () => {
|
||||
;(vscode.window.showWarningMessage as any).mockResolvedValue("confirmation.proceed")
|
||||
|
||||
const futureTimestamp = Date.now() + 100000 // Future timestamp
|
||||
const mockCline = new Task(defaultTaskOptions)
|
||||
mockCline.clineMessages = [
|
||||
|
|
@ -3419,6 +3607,20 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
|
|||
editedMessageContent: "Edited future message",
|
||||
})
|
||||
|
||||
// Should show edit dialog
|
||||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "showEditMessageDialog",
|
||||
messageTs: futureTimestamp + 1000,
|
||||
text: "Edited future message",
|
||||
})
|
||||
|
||||
// Simulate user confirming the edit
|
||||
await messageHandler({
|
||||
type: "editMessageConfirm",
|
||||
messageTs: futureTimestamp + 1000,
|
||||
text: "Edited future message",
|
||||
})
|
||||
|
||||
// Should handle future timestamps correctly
|
||||
expect(mockCline.overwriteClineMessages).toHaveBeenCalled()
|
||||
expect(mockCline.handleWebviewAskResponse).toHaveBeenCalled()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue