@@ -11,6 +11,7 @@ import * as ImagePicker from 'expo-image-picker';
1111import { formatBirthDate } from '@/components/utils/profile' ;
1212import { mockUsers } from '@/mocks/data/userMock' ;
1313import EditProfileScreen from '@/screens/profile/EditProfileScreen' ;
14+ import { updateUserProfile } from '@/services/user' ;
1415import { useUserStore } from '@/stores/userStore' ;
1516
1617jest . mock ( '@/hooks/useTheme' , ( ) => ( {
@@ -23,13 +24,15 @@ jest.mock('@react-navigation/elements', () => ({
2324
2425const mockSetOptions = jest . fn ( ) ;
2526
27+ const mockGoBack = jest . fn ( ) ;
28+
2629jest . mock ( '@react-navigation/native' , ( ) => {
2730 const actual = jest . requireActual ( '@react-navigation/native' ) ;
2831 return {
2932 ...actual ,
3033 useNavigation : ( ) => ( {
3134 navigate : jest . fn ( ) ,
32- goBack : jest . fn ( ) ,
35+ goBack : mockGoBack ,
3336 setOptions : mockSetOptions ,
3437 } ) ,
3538 } ;
@@ -319,4 +322,62 @@ describe('EditProfileScreen (adjusted)', () => {
319322 expect ( ImagePicker . launchImageLibraryAsync ) . toHaveBeenCalled ( ) ;
320323 } ) ;
321324 } ) ;
325+
326+ it ( 'calls handleFormSubmit when header button is pressed' , async ( ) => {
327+ ( updateUserProfile as jest . Mock ) . mockResolvedValueOnce ( { } ) ;
328+
329+ const { getByTestId } = render (
330+ < NavigationContainer >
331+ < QueryClientProvider client = { mockQueryClient } >
332+ < EditProfileScreen />
333+ </ QueryClientProvider >
334+ </ NavigationContainer >
335+ ) ;
336+
337+ // change something
338+ fireEvent . changeText ( getByTestId ( 'edit-bio-input' ) , 'New Bio' ) ;
339+
340+ // Extract the headerRight Button from setOptions
341+ expect ( mockSetOptions ) . toHaveBeenCalled ( ) ;
342+ const headerOptions = mockSetOptions . mock . calls [ 0 ] [ 0 ] ;
343+ const headerRightButton = headerOptions . headerRight ( ) ;
344+
345+ await act ( async ( ) => {
346+ headerRightButton . props . onPress ( ) ;
347+ } ) ;
348+ await act ( async ( ) => {
349+ expect ( mockGoBack ) . toHaveBeenCalled ( ) ;
350+ } ) ;
351+ } ) ;
352+
353+ it ( 'does not call handleFormSubmit when header button is pressed and form is invalid' , async ( ) => {
354+ ( updateUserProfile as jest . Mock ) . mockResolvedValueOnce ( { } ) ;
355+
356+ const { getByTestId } = render (
357+ < NavigationContainer >
358+ < QueryClientProvider client = { mockQueryClient } >
359+ < EditProfileScreen />
360+ </ QueryClientProvider >
361+ </ NavigationContainer >
362+ ) ;
363+
364+ // Set invalid website
365+ await act ( async ( ) => {
366+ fireEvent . changeText ( getByTestId ( 'edit-website-input' ) , 'invalid-url' ) ;
367+ } ) ;
368+
369+ // Extract the latest headerRight button
370+ const headerOptions = mockSetOptions . mock . calls [ mockSetOptions . mock . calls . length - 1 ] [ 0 ] ;
371+ const headerRightButton = headerOptions . headerRight ( ) ;
372+
373+ // The button should be disabled due to invalid form
374+ expect ( headerRightButton . props . disabled ) . toBe ( true ) ;
375+
376+ // Try pressing it (won't call handleFormSubmit because disabled)
377+ await act ( async ( ) => {
378+ headerRightButton . props . onPress ( ) ;
379+ } ) ;
380+
381+ expect ( mockGoBack ) . not . toHaveBeenCalled ( ) ;
382+ } ) ;
322383} ) ;
0 commit comments