@@ -419,3 +419,82 @@ describe('maxToolRoundtrips', () => {
419419 } ) ;
420420 } ) ;
421421} ) ;
422+
423+ describe ( 'form actions' , ( ) => {
424+ const TestComponent = ( ) => {
425+ const { messages, handleSubmit, handleInputChange, isLoading, input } =
426+ useChat ( ) ;
427+
428+ return (
429+ < div >
430+ < For each = { messages ( ) } >
431+ { ( m , idx ) => (
432+ < div data-testid = { `message-${ idx ( ) } ` } >
433+ { m . role === 'user' ? 'User: ' : 'AI: ' }
434+ { m . content }
435+ </ div >
436+ ) }
437+ </ For >
438+
439+ < form onSubmit = { handleSubmit } >
440+ < input
441+ value = { input ( ) }
442+ placeholder = "Send message..."
443+ onInput = { handleInputChange }
444+ disabled = { isLoading ( ) }
445+ data-testid = "do-input"
446+ />
447+ </ form >
448+ </ div >
449+ ) ;
450+ } ;
451+
452+ beforeEach ( ( ) => {
453+ render ( ( ) => < TestComponent /> ) ;
454+ } ) ;
455+
456+ afterEach ( ( ) => {
457+ vi . restoreAllMocks ( ) ;
458+ cleanup ( ) ;
459+ } ) ;
460+
461+ it ( 'should show streamed response using handleSubmit' , async ( ) => {
462+ mockFetchDataStream ( {
463+ url : 'https://example.com/api/chat' ,
464+ chunks : [ 'Hello' , ',' , ' world' , '.' ] . map ( token =>
465+ formatStreamPart ( 'text' , token ) ,
466+ ) ,
467+ } ) ;
468+
469+ const input = screen . getByTestId ( 'do-input' ) ;
470+ await userEvent . type ( input , 'hi' ) ;
471+ await userEvent . keyboard ( '{Enter}' ) ;
472+ expect ( input ) . toHaveValue ( '' ) ;
473+
474+ // Wait for the user message to appear
475+ await screen . findByTestId ( 'message-0' ) ;
476+ expect ( screen . getByTestId ( 'message-0' ) ) . toHaveTextContent ( 'User: hi' ) ;
477+
478+ // Wait for the AI response to complete
479+ await screen . findByTestId ( 'message-1' ) ;
480+ expect ( screen . getByTestId ( 'message-1' ) ) . toHaveTextContent (
481+ 'AI: Hello, world.' ,
482+ ) ;
483+
484+ mockFetchDataStream ( {
485+ url : 'https://example.com/api/chat' ,
486+ chunks : [ 'How' , ' can' , ' I' , ' help' , ' you' , '?' ] . map ( token =>
487+ formatStreamPart ( 'text' , token ) ,
488+ ) ,
489+ } ) ;
490+
491+ await userEvent . click ( input ) ;
492+ await userEvent . keyboard ( '{Enter}' ) ;
493+
494+ // Wait for the second AI response to complete
495+ await screen . findByTestId ( 'message-2' ) ;
496+ expect ( screen . getByTestId ( 'message-2' ) ) . toHaveTextContent (
497+ 'AI: How can I help you?' ,
498+ ) ;
499+ } ) ;
500+ } ) ;
0 commit comments