Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / components / hooks / docs / useDocsNotificationsSettings.test.tsx
blob58ffed18f3005ca62d58af8c4ad4f19b78e224c7
1 import { act, renderHook } from '@testing-library/react-hooks';
2 import { c } from 'ttag';
4 import { useDocsNotificationsSettings } from './useDocsNotificationsSettings';
6 jest.mock('../useApi', () => ({
7     __esModule: true,
8     default: jest.fn(),
9 }));
11 jest.mock('../useNotifications', () => ({
12     __esModule: true,
13     default: jest.fn(() => ({
14         createNotification: jest.fn(),
15     })),
16 }));
18 describe('useDocsNotificationsSettings', () => {
19     const mockApi = jest.fn();
20     const mockCreateNotification = jest.fn();
22     beforeEach(() => {
23         jest.resetAllMocks();
24         require('../useApi').default.mockReturnValue(mockApi);
25         require('../useNotifications').default.mockReturnValue({
26             createNotification: mockCreateNotification,
27         });
28         mockApi.mockImplementation(() =>
29             Promise.resolve({
30                 UserSettings: {
31                     DocsCommentsNotificationsEnabled: false,
32                     DocsCommentsNotificationsIncludeDocumentName: false,
33                 },
34             })
35         );
36     });
38     it('should initialize with null values and not ready state', () => {
39         const { result } = renderHook(() => useDocsNotificationsSettings());
41         expect(result.current.emailNotificationsEnabled).toBe(null);
42         expect(result.current.emailTitleEnabled).toBe(null);
43         expect(result.current.isReady).toBe(false);
44         expect(result.current.isSubmitting).toBe(false);
45         expect(result.current.isLoading).toBe(true);
46     });
48     it('should fetch settings on mount', async () => {
49         const mockSettings = {
50             UserSettings: {
51                 DocsCommentsNotificationsEnabled: true,
52                 DocsCommentsNotificationsIncludeDocumentName: false,
53             },
54         };
56         mockApi.mockResolvedValueOnce(mockSettings);
58         const { result, waitForNextUpdate } = renderHook(() => useDocsNotificationsSettings());
60         expect(result.current.isLoading).toBe(true);
62         await waitForNextUpdate();
64         expect(result.current.emailNotificationsEnabled).toBe(true);
65         expect(result.current.emailTitleEnabled).toBe(false);
66         expect(result.current.isReady).toBe(true);
67         expect(result.current.isLoading).toBe(false);
68     });
70     it('should update notification settings successfully', async () => {
71         mockApi.mockResolvedValueOnce({
72             UserSettings: {
73                 DocsCommentsNotificationsEnabled: true,
74                 DocsCommentsNotificationsIncludeDocumentName: true,
75             },
76         });
78         const { result, waitForNextUpdate } = renderHook(() => useDocsNotificationsSettings());
79         await waitForNextUpdate();
81         mockApi.mockResolvedValueOnce({});
83         await act(async () => {
84             await result.current.updateNotificationSettings({
85                 notificationsEnabled: false,
86                 includeTitleEnabled: false,
87             });
88         });
90         expect(mockCreateNotification).toHaveBeenCalledWith({
91             text: c('Info').t`Settings updated`,
92         });
94         expect(result.current.emailNotificationsEnabled).toBe(false);
95         expect(result.current.emailTitleEnabled).toBe(false);
96     });
98     it('should handle update failure', async () => {
99         mockApi.mockResolvedValueOnce({
100             UserSettings: {
101                 DocsCommentsNotificationsEnabled: true,
102                 DocsCommentsNotificationsIncludeDocumentName: true,
103             },
104         });
106         const { result, waitForNextUpdate } = renderHook(() => useDocsNotificationsSettings());
107         await waitForNextUpdate();
109         const error = new Error('Update failed');
110         mockApi.mockRejectedValueOnce(error);
112         await act(async () => {
113             await result.current.updateNotificationSettings({
114                 notificationsEnabled: false,
115                 includeTitleEnabled: false,
116             });
117         });
119         expect(mockCreateNotification).toHaveBeenCalledWith({
120             type: 'error',
121             text: c('Info').t`Settings update failed`,
122         });
124         // Values should remain unchanged after failed update
125         expect(result.current.emailNotificationsEnabled).toBe(true);
126         expect(result.current.emailTitleEnabled).toBe(true);
127     });
129     it('should handle email notifications toggle', async () => {
130         mockApi.mockResolvedValueOnce({
131             UserSettings: {
132                 DocsCommentsNotificationsEnabled: false,
133                 DocsCommentsNotificationsIncludeDocumentName: true,
134             },
135         });
137         const { result, waitForNextUpdate } = renderHook(() => useDocsNotificationsSettings());
138         await waitForNextUpdate();
140         mockApi.mockResolvedValueOnce({});
142         await act(async () => {
143             await result.current.changeEmailNotificationsEnabledValue(true);
144         });
146         expect(mockApi).toHaveBeenCalledWith(
147             expect.objectContaining({
148                 data: {
149                     DocsCommentsNotificationsEnabled: true,
150                     DocsCommentsNotificationsIncludeDocumentName: true,
151                 },
152             })
153         );
154     });
156     it('should handle document title toggle', async () => {
157         mockApi.mockResolvedValueOnce({
158             UserSettings: {
159                 DocsCommentsNotificationsEnabled: true,
160                 DocsCommentsNotificationsIncludeDocumentName: false,
161             },
162         });
164         const { result, waitForNextUpdate } = renderHook(() => useDocsNotificationsSettings());
165         await waitForNextUpdate();
167         mockApi.mockResolvedValueOnce({});
169         await act(async () => {
170             await result.current.changeDocumentTitleEnabledValue(true);
171         });
173         expect(mockApi).toHaveBeenCalledWith(
174             expect.objectContaining({
175                 data: {
176                     DocsCommentsNotificationsEnabled: true,
177                     DocsCommentsNotificationsIncludeDocumentName: true,
178                 },
179             })
180         );
181     });