@@ -45,6 +45,10 @@ jest.mock('expo-file-system', () => ({
4545 getInfoAsync : jest . fn ( ) . mockResolvedValue ( { exists : true , size : 1024 * 1024 } ) , // 1MB mock
4646} ) ) ;
4747
48+ jest . mock ( 'expo-file-system/legacy' , ( ) => ( {
49+ getInfoAsync : jest . fn ( ) . mockResolvedValue ( { exists : true , size : 1024 * 1024 } ) ,
50+ } ) ) ;
51+
4852jest . mock ( 'expo-video' , ( ) => {
4953 const addListener = jest . fn ( ( ) => ( { remove : jest . fn ( ) } ) ) ;
5054 const React = jest . requireActual ( 'react' ) ;
@@ -1136,4 +1140,79 @@ describe('TweetComposer', () => {
11361140 } ) ;
11371141 } ) ;
11381142 } ) ;
1143+
1144+ it ( 'handles navigation to author profile' , ( ) => {
1145+ const onPressAuthor = jest . fn ( ) ;
1146+ const onClose = jest . fn ( ) ;
1147+
1148+ const mockReplyToTweet = {
1149+ author : { username : 'author' , displayName : 'Author' , avatarUrl : null } ,
1150+ createdAt : new Date ( ) . toISOString ( ) ,
1151+ content : 'Original tweet' ,
1152+ } ;
1153+
1154+ const { getByTestId } = renderWithProviders (
1155+ < TweetComposer
1156+ visible
1157+ onClose = { onClose }
1158+ onPressAuthor = { onPressAuthor }
1159+ replyToAuthor = { { username : 'author' , displayName : 'Author' } }
1160+ replyToTweet = { mockReplyToTweet }
1161+ />
1162+ ) ;
1163+
1164+ const authorLink = getByTestId ( 'replying-to-username' ) ;
1165+ fireEvent . press ( authorLink ) ;
1166+ expect ( onPressAuthor ) . toHaveBeenCalledWith ( 'author' ) ;
1167+ expect ( onClose ) . toHaveBeenCalled ( ) ;
1168+ } ) ;
1169+
1170+ it ( 'alerts when camera permission is denied' , async ( ) => {
1171+ const mockRequestPermission = ImagePicker . requestCameraPermissionsAsync as jest . Mock ;
1172+ mockRequestPermission . mockResolvedValueOnce ( { status : 'denied' } ) ;
1173+ const mockAlert = jest . spyOn ( Alert , 'alert' ) ;
1174+
1175+ const { getByTestId } = renderWithProviders ( < TweetComposer visible onClose = { ( ) => { } } /> ) ;
1176+ const cameraIcon = getByTestId ( 'camera-icon' ) ;
1177+
1178+ fireEvent . press ( cameraIcon ) ;
1179+
1180+ await waitFor ( ( ) => {
1181+ expect ( mockAlert ) . toHaveBeenCalledWith ( 'Permission needed' , expect . any ( String ) ) ;
1182+ } ) ;
1183+ mockAlert . mockRestore ( ) ;
1184+ } ) ;
1185+
1186+ it ( 'alerts when file is too large' , async ( ) => {
1187+ const mockLaunchImageLibrary = ImagePicker . launchImageLibraryAsync as jest . Mock ;
1188+ mockLaunchImageLibrary . mockResolvedValue ( {
1189+ canceled : false ,
1190+ assets : [
1191+ {
1192+ uri : 'file://large-image.jpg' ,
1193+ fileName : 'large-image.jpg' ,
1194+ width : 1000 ,
1195+ height : 1000 ,
1196+ } ,
1197+ ] ,
1198+ } ) ;
1199+
1200+ const mockGetInfo = require ( 'expo-file-system/legacy' ) . getInfoAsync ;
1201+ mockGetInfo . mockResolvedValue ( { exists : true , size : 10 * 1024 * 1024 } ) ; // 10MB > 5MB limit
1202+
1203+ const mockAlert = jest . spyOn ( Alert , 'alert' ) ;
1204+
1205+ const { getByTestId } = renderWithProviders ( < TweetComposer visible onClose = { ( ) => { } } /> ) ;
1206+ const pictureIcon = getByTestId ( 'media-icon' ) ;
1207+
1208+ fireEvent . press ( pictureIcon ) ;
1209+
1210+ await waitFor ( ( ) => {
1211+ expect ( mockAlert ) . toHaveBeenCalledWith (
1212+ 'File Too Large' ,
1213+ expect . stringContaining ( 'exceed size limits' )
1214+ ) ;
1215+ } ) ;
1216+ mockAlert . mockRestore ( ) ;
1217+ } ) ;
11391218} ) ;
0 commit comments