@@ -8,6 +8,7 @@ import { Anthropic } from "@anthropic-ai/sdk"
88
99import {
1010 providerIdentifiers ,
11+ RooCodeEventName ,
1112 type GlobalState ,
1213 type ProviderSettings ,
1314 type ModelInfo ,
@@ -1694,6 +1695,65 @@ describe("Cline", () => {
16941695 expect ( mockProvider . postStateToWebviewWithoutTaskHistory ) . not . toHaveBeenCalled ( )
16951696 } )
16961697
1698+ it ( "waits for an unanswered ask flush before emitting the message" , async ( ) => {
1699+ const task = new Task ( {
1700+ provider : mockProvider ,
1701+ apiConfiguration : mockApiConfig ,
1702+ task : "test task" ,
1703+ startTask : false ,
1704+ } )
1705+ const taskAccess = getTaskTestAccess ( task )
1706+ vi . spyOn ( taskAccess , "saveClineMessages" ) . mockResolvedValue ( true )
1707+ let releaseFlush ! : ( ) => void
1708+ const pendingFlush = new Promise < void > ( ( resolve ) => {
1709+ releaseFlush = resolve
1710+ } )
1711+ const flushSpy = vi . mocked ( mockProvider . flushPostStateToWebviewThrottled ) . mockReturnValueOnce ( pendingFlush )
1712+ const messageListener = vi . fn ( )
1713+ task . on ( RooCodeEventName . Message , messageListener )
1714+ const message = {
1715+ ts : 1 ,
1716+ type : "ask" as const ,
1717+ ask : "resume_task" as const ,
1718+ }
1719+
1720+ const addPromise = taskAccess . addToClineMessages ( message )
1721+
1722+ await Promise . resolve ( )
1723+ expect ( mockProvider . postStateToWebviewThrottled ) . toHaveBeenCalledOnce ( )
1724+ expect ( mockProvider . postStateToWebviewThrottled ) . toHaveBeenCalledWith ( )
1725+ expect ( flushSpy ) . toHaveBeenCalledOnce ( )
1726+ expect ( flushSpy ) . toHaveBeenCalledWith ( )
1727+ expect ( messageListener ) . not . toHaveBeenCalled ( )
1728+
1729+ releaseFlush ( )
1730+ await addPromise
1731+
1732+ expect ( flushSpy . mock . invocationCallOrder [ 0 ] ) . toBeLessThan ( messageListener . mock . invocationCallOrder [ 0 ] )
1733+ expect ( messageListener ) . toHaveBeenCalledWith ( { action : "created" , message } )
1734+ } )
1735+
1736+ it ( "keeps an already answered ask on the throttled path" , async ( ) => {
1737+ const task = new Task ( {
1738+ provider : mockProvider ,
1739+ apiConfiguration : mockApiConfig ,
1740+ task : "test task" ,
1741+ startTask : false ,
1742+ } )
1743+ vi . spyOn ( getTaskTestAccess ( task ) , "saveClineMessages" ) . mockResolvedValue ( true )
1744+
1745+ await getTaskTestAccess ( task ) . addToClineMessages ( {
1746+ ts : 1 ,
1747+ type : "ask" ,
1748+ ask : "tool" ,
1749+ isAnswered : true ,
1750+ } )
1751+
1752+ expect ( mockProvider . postStateToWebviewThrottled ) . toHaveBeenCalledOnce ( )
1753+ expect ( mockProvider . postStateToWebviewThrottled ) . toHaveBeenCalledWith ( )
1754+ expect ( mockProvider . flushPostStateToWebviewThrottled ) . not . toHaveBeenCalled ( )
1755+ } )
1756+
16971757 it ( "waits for a new partial message flush before a following message update" , async ( ) => {
16981758 const task = new Task ( {
16991759 provider : mockProvider ,
0 commit comments