boxons/components/useCases/timer/business/__tests__/useNotification.test.ts

163 lines
5.0 KiB
TypeScript
Raw Permalink Normal View History

2025-04-08 21:29:14 +00:00
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<typeof PushNotification> & {
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);
});
});