@@ -24,6 +24,7 @@ const mocks = vi.hoisted(() => ({
2424 useSessionAgent : vi . fn ( ) ,
2525 useAgents : vi . fn ( ) ,
2626 useSendPromptMutate : vi . fn ( ) ,
27+ sendPromptPending : vi . fn ( ( ) => false ) ,
2728 useUserBash : vi . fn ( ) ,
2829 useSessionAgentStore : vi . fn ( ) ,
2930 useSendErrorStore : vi . fn ( ) ,
@@ -40,9 +41,9 @@ vi.mock('@/hooks/useMobile', () => ({
4041} ) )
4142
4243vi . mock ( '@/hooks/useOpenCode' , ( ) => ( {
43- useSendPrompt : ( ) => ( { mutate : mocks . useSendPromptMutate } ) ,
44+ useSendPrompt : ( ) => ( { mutate : mocks . useSendPromptMutate , isPending : mocks . sendPromptPending ( ) } ) ,
4445 useAbortSession : ( ) => ( { mutate : vi . fn ( ) } ) ,
45- useSendShell : ( ) => ( { mutate : vi . fn ( ) } ) ,
46+ useSendShell : ( ) => ( { mutate : vi . fn ( ) , isPending : false } ) ,
4647 useOpenCodeClient : ( ) => ( { } ) ,
4748 useAgents : ( ) => ( { data : [ ] } ) ,
4849} ) )
@@ -162,6 +163,7 @@ describe('PromptInput STT Gesture Tests', () => {
162163 mocks . useSendPromptMutate . mockImplementation ( ( _variables , options ) => {
163164 options ?. onSuccess ?.( )
164165 } )
166+ mocks . sendPromptPending . mockReturnValue ( false )
165167
166168 mocks . useMobile . mockReturnValue ( true )
167169 mocks . useSTT . mockReturnValue ( {
@@ -274,6 +276,54 @@ describe('PromptInput STT Gesture Tests', () => {
274276 } )
275277 } )
276278
279+ it ( 'clears submitted text once the server confirms it is processing' , async ( ) => {
280+ mocks . useSendPromptMutate . mockImplementation ( ( ) => undefined )
281+ const queryClient = createTestQueryClient ( )
282+ const { rerender } = render (
283+ < QueryClientProvider client = { queryClient } >
284+ < PromptInput { ...defaultProps } />
285+ </ QueryClientProvider > ,
286+ )
287+
288+ const input = screen . getByPlaceholderText ( 'Send a message...' )
289+ fireEvent . change ( input , { target : { value : 'do the thing' } } )
290+ fireEvent . click ( screen . getByTitle ( 'Send' ) )
291+
292+ expect ( input ) . toHaveValue ( 'do the thing' )
293+
294+ rerender (
295+ < QueryClientProvider client = { queryClient } >
296+ < PromptInput { ...defaultProps } isStreamingResponse />
297+ </ QueryClientProvider > ,
298+ )
299+
300+ await waitFor ( ( ) => {
301+ expect ( input ) . toHaveValue ( '' )
302+ } )
303+ } )
304+
305+ it ( 'allows queuing a follow-up while a non-queued send is pending' , async ( ) => {
306+ mocks . sendPromptPending . mockReturnValue ( true )
307+ render (
308+ < QueryClientProvider client = { createTestQueryClient ( ) } >
309+ < PromptInput { ...defaultProps } isStreamingResponse />
310+ </ QueryClientProvider > ,
311+ )
312+
313+ const input = screen . getByPlaceholderText ( 'Send a message...' )
314+ fireEvent . change ( input , { target : { value : 'follow-up' } } )
315+
316+ const queueButton = screen . getByTitle ( 'Queue message' )
317+ expect ( queueButton ) . not . toBeDisabled ( )
318+
319+ fireEvent . click ( queueButton )
320+
321+ expect ( mocks . useSendPromptMutate ) . toHaveBeenCalledWith (
322+ expect . objectContaining ( { prompt : 'follow-up' , queued : true } ) ,
323+ expect . any ( Object ) ,
324+ )
325+ } )
326+
277327 it ( 'restores a failed queued prompt when the input is empty' , async ( ) => {
278328 const queryClient = createTestQueryClient ( )
279329 const { rerender } = render (
0 commit comments