1 import { act, renderHook } from '@testing-library/react-hooks';
2 import { c } from 'ttag';
4 import { useDocsNotificationsSettings } from './useDocsNotificationsSettings';
6 jest.mock('../useApi', () => ({
11 jest.mock('../useNotifications', () => ({
13 default: jest.fn(() => ({
14 createNotification: jest.fn(),
18 describe('useDocsNotificationsSettings', () => {
19 const mockApi = jest.fn();
20 const mockCreateNotification = jest.fn();
24 require('../useApi').default.mockReturnValue(mockApi);
25 require('../useNotifications').default.mockReturnValue({
26 createNotification: mockCreateNotification,
28 mockApi.mockImplementation(() =>
31 DocsCommentsNotificationsEnabled: false,
32 DocsCommentsNotificationsIncludeDocumentName: false,
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);
48 it('should fetch settings on mount', async () => {
49 const mockSettings = {
51 DocsCommentsNotificationsEnabled: true,
52 DocsCommentsNotificationsIncludeDocumentName: false,
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);
70 it('should update notification settings successfully', async () => {
71 mockApi.mockResolvedValueOnce({
73 DocsCommentsNotificationsEnabled: true,
74 DocsCommentsNotificationsIncludeDocumentName: true,
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,
90 expect(mockCreateNotification).toHaveBeenCalledWith({
91 text: c('Info').t`Settings updated`,
94 expect(result.current.emailNotificationsEnabled).toBe(false);
95 expect(result.current.emailTitleEnabled).toBe(false);
98 it('should handle update failure', async () => {
99 mockApi.mockResolvedValueOnce({
101 DocsCommentsNotificationsEnabled: true,
102 DocsCommentsNotificationsIncludeDocumentName: true,
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,
119 expect(mockCreateNotification).toHaveBeenCalledWith({
121 text: c('Info').t`Settings update failed`,
124 // Values should remain unchanged after failed update
125 expect(result.current.emailNotificationsEnabled).toBe(true);
126 expect(result.current.emailTitleEnabled).toBe(true);
129 it('should handle email notifications toggle', async () => {
130 mockApi.mockResolvedValueOnce({
132 DocsCommentsNotificationsEnabled: false,
133 DocsCommentsNotificationsIncludeDocumentName: true,
137 const { result, waitForNextUpdate } = renderHook(() => useDocsNotificationsSettings());
138 await waitForNextUpdate();
140 mockApi.mockResolvedValueOnce({});
142 await act(async () => {
143 await result.current.changeEmailNotificationsEnabledValue(true);
146 expect(mockApi).toHaveBeenCalledWith(
147 expect.objectContaining({
149 DocsCommentsNotificationsEnabled: true,
150 DocsCommentsNotificationsIncludeDocumentName: true,
156 it('should handle document title toggle', async () => {
157 mockApi.mockResolvedValueOnce({
159 DocsCommentsNotificationsEnabled: true,
160 DocsCommentsNotificationsIncludeDocumentName: false,
164 const { result, waitForNextUpdate } = renderHook(() => useDocsNotificationsSettings());
165 await waitForNextUpdate();
167 mockApi.mockResolvedValueOnce({});
169 await act(async () => {
170 await result.current.changeDocumentTitleEnabledValue(true);
173 expect(mockApi).toHaveBeenCalledWith(
174 expect.objectContaining({
176 DocsCommentsNotificationsEnabled: true,
177 DocsCommentsNotificationsIncludeDocumentName: true,