1- import { render , screen , fireEvent } from "@testing-library/react" ;
1+ import { render , screen , fireEvent , act } from "@testing-library/react" ;
22import { describe , it , expect , jest } from "@jest/globals" ;
33import "@testing-library/jest-dom" ;
44import ToolsTab from "../ToolsTab" ;
@@ -43,7 +43,7 @@ describe("ToolsTab", () => {
4343 tools : mockTools ,
4444 listTools : jest . fn ( ) ,
4545 clearTools : jest . fn ( ) ,
46- callTool : jest . fn ( ) ,
46+ callTool : jest . fn ( async ( ) => { } ) ,
4747 selectedTool : null ,
4848 setSelectedTool : jest . fn ( ) ,
4949 toolResult : null ,
@@ -59,14 +59,16 @@ describe("ToolsTab", () => {
5959 ) ;
6060 } ;
6161
62- it ( "should reset input values when switching tools" , ( ) => {
62+ it ( "should reset input values when switching tools" , async ( ) => {
6363 const { rerender } = renderToolsTab ( {
6464 selectedTool : mockTools [ 0 ] ,
6565 } ) ;
6666
6767 // Enter a value in the first tool's input
6868 const input = screen . getByRole ( "spinbutton" ) as HTMLInputElement ;
69- fireEvent . change ( input , { target : { value : "42" } } ) ;
69+ await act ( async ( ) => {
70+ fireEvent . change ( input , { target : { value : "42" } } ) ;
71+ } ) ;
7072 expect ( input . value ) . toBe ( "42" ) ;
7173
7274 // Switch to second tool
@@ -80,7 +82,8 @@ describe("ToolsTab", () => {
8082 const newInput = screen . getByRole ( "spinbutton" ) as HTMLInputElement ;
8183 expect ( newInput . value ) . toBe ( "" ) ;
8284 } ) ;
83- it ( "should handle integer type inputs" , ( ) => {
85+
86+ it ( "should handle integer type inputs" , async ( ) => {
8487 renderToolsTab ( {
8588 selectedTool : mockTools [ 1 ] , // Use the tool with integer type
8689 } ) ;
@@ -93,10 +96,49 @@ describe("ToolsTab", () => {
9396 expect ( input . value ) . toBe ( "42" ) ;
9497
9598 const submitButton = screen . getByRole ( "button" , { name : / r u n t o o l / i } ) ;
96- fireEvent . click ( submitButton ) ;
99+ await act ( async ( ) => {
100+ fireEvent . click ( submitButton ) ;
101+ } ) ;
97102
98103 expect ( defaultProps . callTool ) . toHaveBeenCalledWith ( mockTools [ 1 ] . name , {
99104 count : 42 ,
100105 } ) ;
101106 } ) ;
107+
108+ it ( "should disable button and change text while tool is running" , async ( ) => {
109+ // Create a promise that we can resolve later
110+ let resolvePromise : ( ( value : unknown ) => void ) | undefined ;
111+ const mockPromise = new Promise ( ( resolve ) => {
112+ resolvePromise = resolve ;
113+ } ) ;
114+
115+ // Mock callTool to return our promise
116+ const mockCallTool = jest . fn ( ) . mockReturnValue ( mockPromise ) ;
117+
118+ renderToolsTab ( {
119+ selectedTool : mockTools [ 0 ] ,
120+ callTool : mockCallTool ,
121+ } ) ;
122+
123+ const submitButton = screen . getByRole ( "button" , { name : / r u n t o o l / i } ) ;
124+ expect ( submitButton . getAttribute ( "disabled" ) ) . toBeNull ( ) ;
125+
126+ // Click the button and verify immediate state changes
127+ await act ( async ( ) => {
128+ fireEvent . click ( submitButton ) ;
129+ } ) ;
130+
131+ // Verify button is disabled and text changed
132+ expect ( submitButton . getAttribute ( "disabled" ) ) . not . toBeNull ( ) ;
133+ expect ( submitButton . textContent ) . toBe ( "Running..." ) ;
134+
135+ // Resolve the promise to simulate tool completion
136+ await act ( async ( ) => {
137+ if ( resolvePromise ) {
138+ await resolvePromise ( { } ) ;
139+ }
140+ } ) ;
141+
142+ expect ( submitButton . getAttribute ( "disabled" ) ) . toBeNull ( ) ;
143+ } ) ;
102144} ) ;
0 commit comments