tests working

This commit is contained in:
Will Li 2025-07-09 16:33:04 -07:00
parent 24a8c10048
commit 303a9c8c1f

View file

@ -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()