import { renderHook, act } from '@testing-library/react-native'; import { PermissionsAndroid, Platform } from 'react-native'; import PushNotification from 'react-native-push-notification'; import { useNotification } from '../useNotifications'; // Mock des modules natifs jest.mock('react-native', () => ({ Platform: { OS: 'android', Version: 33, }, PermissionsAndroid: { request: jest.fn().mockResolvedValue('granted'), PERMISSIONS: { POST_NOTIFICATIONS: 'android.permission.POST_NOTIFICATIONS', }, RESULTS: { GRANTED: 'granted', }, }, })); // Mock de react-native-push-notification jest.mock('react-native-push-notification', () => { return { configure: jest.fn(), createChannel: jest.fn((channel, callback) => callback(true)), localNotification: jest.fn(), cancelLocalNotification: jest.fn(), Importance: { HIGH: 4, }, }; }); // Typage des mocks pour TypeScript const mockPushNotification = PushNotification as jest.Mocked & { Importance: { HIGH: number }; }; // Mock de console.log pour éviter de polluer les logs de test console.log = jest.fn(); describe('useNotification hook', () => { const notificationId = '123'; const channelInformations = { channelId: 'testChannel', channelName: 'Test Channel', channelDescription: 'Channel for testing', }; // Réinitialiser les mocks après chaque test afterEach(() => { jest.clearAllMocks(); }); it('devrait demander les permissions de notification au montage sur Android >= 33', async () => { renderHook(() => useNotification(notificationId, channelInformations)); // Vérifier que la demande de permission a été appelée expect(PermissionsAndroid.request).toHaveBeenCalledWith( PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS ); }); it('ne devrait pas demander les permissions sur iOS', async () => { Platform.OS = 'ios'; renderHook(() => useNotification(notificationId, channelInformations)); expect(PermissionsAndroid.request).not.toHaveBeenCalled(); // Réinitialiser pour les tests suivants Platform.OS = 'android'; }); it('devrait configurer PushNotification au montage', () => { renderHook(() => useNotification(notificationId, channelInformations)); expect(mockPushNotification.configure).toHaveBeenCalled(); const configCall = (mockPushNotification.configure as jest.Mock).mock.calls[0][0]; // Vérifier que les fonctions de callback sont définies expect(typeof configCall.onRegister).toBe('function'); expect(typeof configCall.onNotification).toBe('function'); // Vérifier les permissions expect(configCall.permissions).toEqual({ alert: true, badge: true, sound: true, }); // Vérifier les autres paramètres expect(configCall.popInitialNotification).toBe(true); expect(configCall.requestPermissions).toBe(Platform.OS === 'ios'); }); it('devrait créer un canal de notification sur Android', () => { renderHook(() => useNotification(notificationId, channelInformations)); expect(mockPushNotification.createChannel).toHaveBeenCalledWith( { ...channelInformations, vibrate: true, importance: mockPushNotification.Importance.HIGH, }, expect.any(Function) ); }); it('ne devrait pas créer de canal sur iOS', () => { Platform.OS = 'ios'; renderHook(() => useNotification(notificationId, channelInformations)); expect(mockPushNotification.createChannel).not.toHaveBeenCalled(); // Réinitialiser pour les tests suivants Platform.OS = 'android'; }); it('devrait retourner les fonctions updateNotification et cancelNotification', () => { const { result } = renderHook(() => useNotification(notificationId, channelInformations)); expect(result.current).toHaveProperty('updateNotification'); expect(result.current).toHaveProperty('cancelNotification'); expect(typeof result.current.updateNotification).toBe('function'); expect(typeof result.current.cancelNotification).toBe('function'); }); it('updateNotification devrait appeler localNotification avec les bons paramètres', () => { const { result } = renderHook(() => useNotification(notificationId, channelInformations)); act(() => { result.current.updateNotification('Test Title', 'Test Message'); }); expect(mockPushNotification.localNotification).toHaveBeenCalledWith({ channelId: channelInformations.channelId, id: parseInt(notificationId), title: 'Test Title', message: 'Test Message', playSound: false, vibrate: false, ongoing: true, priority: 'high', importance: 'high', onlyAlertOnce: true, }); }); it('cancelNotification devrait appeler cancelLocalNotification avec le bon ID', () => { const { result } = renderHook(() => useNotification(notificationId, channelInformations)); act(() => { result.current.cancelNotification(); }); expect(mockPushNotification.cancelLocalNotification).toHaveBeenCalledWith(notificationId); }); });