@umituz/react-native-settings 4.20.62 → 4.21.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/package.json +6 -61
  2. package/src/domains/feedback/domain/entities/FeedbackEntity.ts +8 -8
  3. package/src/domains/gamification/components/AchievementCard.tsx +142 -0
  4. package/src/domains/gamification/components/AchievementItem.tsx +182 -0
  5. package/src/domains/gamification/components/AchievementToast.tsx +122 -0
  6. package/src/domains/gamification/components/GamificationScreen/AchievementsList.tsx +84 -0
  7. package/src/domains/gamification/components/GamificationScreen/Header.tsx +29 -0
  8. package/src/domains/gamification/components/GamificationScreen/StatsGrid.tsx +51 -0
  9. package/src/domains/gamification/components/GamificationScreen/index.tsx +111 -0
  10. package/src/domains/gamification/components/GamificationScreen/styles.ts +43 -0
  11. package/src/domains/gamification/components/GamificationScreen/types.ts +77 -0
  12. package/src/domains/gamification/components/GamificationScreenWrapper.tsx +4 -4
  13. package/src/domains/gamification/components/GamificationSettingsItem.tsx +1 -1
  14. package/src/domains/gamification/components/LevelProgress.tsx +129 -0
  15. package/src/domains/gamification/components/PointsBadge.tsx +60 -0
  16. package/src/domains/gamification/components/StatsCard.tsx +89 -0
  17. package/src/domains/gamification/components/StreakDisplay.tsx +119 -0
  18. package/src/domains/gamification/components/index.ts +13 -0
  19. package/src/domains/gamification/examples/gamification.config.example.ts +1 -1
  20. package/src/domains/gamification/hooks/useGamification.ts +91 -0
  21. package/src/domains/gamification/index.ts +46 -19
  22. package/src/domains/gamification/store/gamificationStore.ts +162 -0
  23. package/src/domains/gamification/types/index.ts +95 -23
  24. package/src/domains/gamification/types/settings.ts +28 -0
  25. package/src/domains/gamification/utils/calculations.ts +85 -0
  26. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -51
  27. package/.github/ISSUE_TEMPLATE/documentation.md +0 -52
  28. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -63
  29. package/.github/PULL_REQUEST_TEMPLATE.md +0 -84
  30. package/AI_AGENT_GUIDELINES.md +0 -367
  31. package/ARCHITECTURE.md +0 -246
  32. package/CHANGELOG.md +0 -67
  33. package/CODE_OF_CONDUCT.md +0 -75
  34. package/CONTRIBUTING.md +0 -107
  35. package/DOCUMENTATION_MIGRATION.md +0 -319
  36. package/DOCUMENTATION_TEMPLATE.md +0 -155
  37. package/SECURITY.md +0 -98
  38. package/SETTINGS_SCREEN_GUIDE.md +0 -185
  39. package/TESTING.md +0 -358
  40. package/src/__tests__/integration.test.tsx +0 -371
  41. package/src/__tests__/performance.test.tsx +0 -369
  42. package/src/__tests__/setup.test.tsx +0 -20
  43. package/src/__tests__/setup.ts +0 -154
  44. package/src/domains/about/__tests__/integration.test.tsx +0 -328
  45. package/src/domains/about/__tests__/types.d.ts +0 -5
  46. package/src/domains/about/domain/entities/__tests__/AppInfo.test.ts +0 -93
  47. package/src/domains/about/infrastructure/repositories/__tests__/AboutRepository.test.ts +0 -153
  48. package/src/domains/about/presentation/components/__tests__/AboutContent.simple.test.tsx +0 -178
  49. package/src/domains/about/presentation/components/__tests__/AboutContent.test.tsx +0 -293
  50. package/src/domains/about/presentation/components/__tests__/AboutHeader.test.tsx +0 -201
  51. package/src/domains/about/presentation/components/__tests__/AboutSettingItem.test.tsx +0 -71
  52. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.simple.test.tsx +0 -229
  53. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.test.tsx +0 -240
  54. package/src/domains/about/presentation/screens/__tests__/AboutScreen.simple.test.tsx +0 -199
  55. package/src/domains/about/presentation/screens/__tests__/AboutScreen.test.tsx +0 -366
  56. package/src/domains/about/utils/__tests__/index.test.ts +0 -408
  57. package/src/domains/appearance/__tests__/components/AppearanceScreen.test.tsx +0 -195
  58. package/src/domains/appearance/__tests__/hooks/index.test.tsx +0 -232
  59. package/src/domains/appearance/__tests__/integration/index.test.tsx +0 -207
  60. package/src/domains/appearance/__tests__/services/appearanceService.test.ts +0 -299
  61. package/src/domains/appearance/__tests__/setup.ts +0 -88
  62. package/src/domains/appearance/__tests__/stores/appearanceStore.test.tsx +0 -175
  63. package/src/domains/cloud-sync/presentation/components/__tests__/CloudSyncSetting.test.tsx +0 -78
  64. package/src/domains/legal/__tests__/ContentValidationService.test.ts +0 -195
  65. package/src/domains/legal/__tests__/StyleCacheService.test.ts +0 -110
  66. package/src/domains/legal/__tests__/UrlHandlerService.test.ts +0 -71
  67. package/src/domains/legal/__tests__/setup.ts +0 -82
  68. package/src/presentation/components/__tests__/SettingsErrorBoundary.test.tsx +0 -186
  69. package/src/presentation/screens/__tests__/SettingsScreen.test.tsx +0 -322
  70. package/src/presentation/screens/hooks/__tests__/useFeatureDetection.test.tsx +0 -261
@@ -1,299 +0,0 @@
1
- /**
2
- * Appearance Service Tests
3
- */
4
-
5
- import { AppearanceService, appearanceService } from '../../infrastructure/services/appearanceService';
6
- import type { ThemeMode, CustomThemeColors } from '../../types';
7
-
8
- // Mock dependencies
9
- jest.mock('../../infrastructure/stores/appearanceStore');
10
- jest.mock('../../infrastructure/storage/appearanceStorage');
11
- jest.mock('@umituz/react-native-design-system', () => ({
12
- useTheme: {
13
- getState: jest.fn(() => ({
14
- setThemeMode: jest.fn(),
15
- })),
16
- },
17
- useDesignSystemTheme: {
18
- getState: jest.fn(() => ({
19
- setThemeMode: jest.fn(),
20
- setCustomColors: jest.fn(),
21
- })),
22
- },
23
- }));
24
-
25
- const mockAppearanceStore = require('../../infrastructure/stores/appearanceStore').useAppearanceStore;
26
- const mockAppearanceStorage = require('../../infrastructure/storage/appearanceStorage').AppearanceStorage;
27
- const mockUseTheme = require('@umituz/react-native-design-system').useTheme;
28
- const mockUseDesignSystemTheme = require('@umituz/react-native-design-system').useDesignSystemTheme;
29
-
30
- describe('AppearanceService', () => {
31
- let service: AppearanceService;
32
- let mockGetState: jest.MockedFunction<typeof mockAppearanceStore.getState>;
33
- let mockSetSettings: jest.MockedFunction<typeof mockAppearanceStore.getState>;
34
- let mockSetInitialized: jest.MockedFunction<typeof mockAppearanceStore.getState>;
35
- let mockUpdateThemeMode: jest.MockedFunction<typeof mockAppearanceStore.getState>;
36
- let mockUpdateCustomColors: jest.MockedFunction<typeof mockAppearanceStore.getState>;
37
- let mockResetState: jest.MockedFunction<typeof mockAppearanceStore.getState>;
38
-
39
- beforeEach(() => {
40
- jest.clearAllMocks();
41
-
42
- service = appearanceService;
43
-
44
- mockGetState = mockAppearanceStore.getState as jest.MockedFunction<typeof mockAppearanceStore.getState>;
45
- mockSetSettings = mockAppearanceStore.getState as jest.MockedFunction<typeof mockAppearanceStore.getState>;
46
- mockSetInitialized = mockAppearanceStore.getState as jest.MockedFunction<typeof mockAppearanceStore.getState>;
47
- mockUpdateThemeMode = mockAppearanceStore.getState as jest.MockedFunction<typeof mockAppearanceStore.getState>;
48
- mockUpdateCustomColors = mockAppearanceStore.getState as jest.MockedFunction<typeof mockAppearanceStore.getState>;
49
- mockResetState = mockAppearanceStore.getState as jest.MockedFunction<typeof mockAppearanceStore.getState>;
50
-
51
- // Setup mock implementations
52
- mockGetState.mockReturnValue({
53
- settings: { themeMode: 'dark' as ThemeMode },
54
- isInitialized: false,
55
- });
56
-
57
- mockSetSettings.mockReturnValue({} as any);
58
- mockSetInitialized.mockReturnValue({} as any);
59
- mockUpdateThemeMode.mockReturnValue({} as any);
60
- mockUpdateCustomColors.mockReturnValue({} as any);
61
- mockResetState.mockReturnValue({} as any);
62
-
63
- mockAppearanceStorage.getSettings.mockResolvedValue(null);
64
- mockAppearanceStorage.setSettings.mockResolvedValue();
65
- mockAppearanceStorage.clear.mockResolvedValue();
66
-
67
- mockUseTheme.getState.mockReturnValue({
68
- setThemeMode: jest.fn(),
69
- });
70
-
71
- mockUseDesignSystemTheme.getState.mockReturnValue({
72
- setThemeMode: jest.fn(),
73
- setCustomColors: jest.fn(),
74
- });
75
- });
76
-
77
- afterEach(() => {
78
- jest.restoreAllMocks();
79
- });
80
-
81
- describe('initialize', () => {
82
- it('should initialize with saved settings', async () => {
83
- const savedSettings = { themeMode: 'light' as ThemeMode };
84
- mockAppearanceStorage.getSettings.mockResolvedValue(savedSettings);
85
-
86
- await service.initialize();
87
-
88
- expect(mockAppearanceStorage.getSettings).toHaveBeenCalled();
89
- expect(mockSetSettings).toHaveBeenCalledWith(savedSettings);
90
- expect(mockSetInitialized).toHaveBeenCalledWith(true);
91
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalledWith('light');
92
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalledWith('light');
93
- expect(mockUseDesignSystemTheme.getState().setCustomColors).toHaveBeenCalledWith(undefined);
94
- });
95
-
96
- it('should initialize with default settings when no saved settings', async () => {
97
- mockAppearanceStorage.getSettings.mockResolvedValue(null);
98
-
99
- await service.initialize();
100
-
101
- expect(mockSetSettings).toHaveBeenCalledWith({ themeMode: 'dark' });
102
- expect(mockSetInitialized).toHaveBeenCalledWith(true);
103
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalledWith('dark');
104
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalledWith('dark');
105
- });
106
-
107
- it('should handle initialization errors gracefully', async () => {
108
- const error = new Error('Init failed');
109
- mockAppearanceStorage.getSettings.mockRejectedValue(error);
110
-
111
- await service.initialize();
112
-
113
- expect(mockSetSettings).toHaveBeenCalledWith({ themeMode: 'dark' });
114
- expect(mockSetInitialized).toHaveBeenCalledWith(true);
115
- });
116
-
117
- it('should prevent multiple initializations', async () => {
118
- const savedSettings = { themeMode: 'light' as ThemeMode };
119
- mockAppearanceStorage.getSettings.mockResolvedValue(savedSettings);
120
-
121
- const promise1 = service.initialize();
122
- const promise2 = service.initialize();
123
-
124
- await Promise.all([promise1, promise2]);
125
-
126
- expect(mockAppearanceStorage.getSettings).toHaveBeenCalledTimes(1);
127
- });
128
- });
129
-
130
- describe('getThemeMode', () => {
131
- it('should return current theme mode', () => {
132
- mockGetState.mockReturnValue({
133
- settings: { themeMode: 'light' as ThemeMode },
134
- isInitialized: true,
135
- });
136
-
137
- const result = service.getThemeMode();
138
-
139
- expect(result).toBe('light');
140
- expect(mockGetState).toHaveBeenCalled();
141
- });
142
- });
143
-
144
- describe('setThemeMode', () => {
145
- it('should set theme mode and sync with design system', async () => {
146
- const newMode: ThemeMode = 'light';
147
- mockGetState.mockReturnValue({
148
- settings: { themeMode: 'dark' as ThemeMode },
149
- isInitialized: true,
150
- });
151
-
152
- await service.setThemeMode(newMode);
153
-
154
- expect(mockUpdateThemeMode).toHaveBeenCalledWith(newMode);
155
- expect(mockAppearanceStorage.setSettings).toHaveBeenCalledWith({
156
- themeMode: newMode,
157
- });
158
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalledWith(newMode);
159
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalledWith(newMode);
160
- });
161
-
162
- it('should handle setThemeMode errors', async () => {
163
- const error = new Error('Set theme failed');
164
- mockAppearanceStorage.setSettings.mockRejectedValue(error);
165
-
166
- await expect(service.setThemeMode('light')).rejects.toThrow(error);
167
- });
168
- });
169
-
170
- describe('toggleTheme', () => {
171
- it('should toggle between light and dark', async () => {
172
- mockGetState.mockReturnValue({
173
- settings: { themeMode: 'light' as ThemeMode },
174
- isInitialized: true,
175
- });
176
-
177
- await service.toggleTheme();
178
-
179
- expect(mockUpdateThemeMode).toHaveBeenCalledWith('dark');
180
- });
181
-
182
- it('should toggle from dark to light', async () => {
183
- mockGetState.mockReturnValue({
184
- settings: { themeMode: 'dark' as ThemeMode },
185
- isInitialized: true,
186
- });
187
-
188
- await service.toggleTheme();
189
-
190
- expect(mockUpdateThemeMode).toHaveBeenCalledWith('light');
191
- });
192
- });
193
-
194
- describe('getCustomColors', () => {
195
- it('should return current custom colors', () => {
196
- const customColors: CustomThemeColors = { primary: '#FF0000' };
197
- mockGetState.mockReturnValue({
198
- settings: { themeMode: 'dark', customColors },
199
- isInitialized: true,
200
- });
201
-
202
- const result = service.getCustomColors();
203
-
204
- expect(result).toEqual(customColors);
205
- });
206
-
207
- it('should return undefined when no custom colors', () => {
208
- mockGetState.mockReturnValue({
209
- settings: { themeMode: 'dark' },
210
- isInitialized: true,
211
- });
212
-
213
- const result = service.getCustomColors();
214
-
215
- expect(result).toBeUndefined();
216
- });
217
- });
218
-
219
- describe('setCustomColors', () => {
220
- it('should set custom colors and sync with design system', async () => {
221
- const newColors: CustomThemeColors = { primary: '#FF0000' };
222
- const currentColors = { secondary: '#00FF00' };
223
- mockGetState.mockReturnValue({
224
- settings: { themeMode: 'dark', customColors: currentColors },
225
- isInitialized: true,
226
- });
227
-
228
- await service.setCustomColors(newColors);
229
-
230
- expect(mockUpdateCustomColors).toHaveBeenCalledWith({
231
- ...currentColors,
232
- ...newColors,
233
- });
234
- expect(mockAppearanceStorage.setSettings).toHaveBeenCalledWith({
235
- themeMode: 'dark',
236
- customColors: { ...currentColors, ...newColors },
237
- });
238
- expect(mockUseDesignSystemTheme.getState().setCustomColors).toHaveBeenCalledWith({
239
- ...currentColors,
240
- ...newColors,
241
- });
242
- });
243
-
244
- it('should handle setCustomColors errors', async () => {
245
- const error = new Error('Set colors failed');
246
- mockAppearanceStorage.setSettings.mockRejectedValue(error);
247
-
248
- await expect(service.setCustomColors({ primary: '#FF0000' })).rejects.toThrow(error);
249
- });
250
- });
251
-
252
- describe('resetCustomColors', () => {
253
- it('should reset custom colors', async () => {
254
- mockGetState.mockReturnValue({
255
- settings: { themeMode: 'dark', customColors: { primary: '#FF0000' } },
256
- isInitialized: true,
257
- });
258
-
259
- await service.resetCustomColors();
260
-
261
- expect(mockUpdateCustomColors).toHaveBeenCalledWith(undefined);
262
- expect(mockAppearanceStorage.setSettings).toHaveBeenCalledWith({
263
- themeMode: 'dark',
264
- customColors: undefined,
265
- });
266
- expect(mockUseDesignSystemTheme.getState().setCustomColors).toHaveBeenCalledWith(undefined);
267
- });
268
- });
269
-
270
- describe('reset', () => {
271
- it('should reset all settings', async () => {
272
- mockGetState.mockReturnValue({
273
- settings: { themeMode: 'light', customColors: { primary: '#FF0000' } },
274
- isInitialized: true,
275
- });
276
-
277
- await service.reset();
278
-
279
- expect(mockAppearanceStorage.clear).toHaveBeenCalled();
280
- expect(mockResetState).toHaveBeenCalled();
281
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalledWith('dark');
282
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalledWith('dark');
283
- expect(mockUseDesignSystemTheme.getState().setCustomColors).toHaveBeenCalledWith(undefined);
284
- });
285
- });
286
-
287
- describe('isInitialized', () => {
288
- it('should return initialization status', () => {
289
- mockGetState.mockReturnValue({
290
- settings: { themeMode: 'dark' },
291
- isInitialized: true,
292
- });
293
-
294
- const result = service.isInitialized();
295
-
296
- expect(result).toBe(true);
297
- });
298
- });
299
- });
@@ -1,88 +0,0 @@
1
- /**
2
- * Jest Setup File
3
- *
4
- * Global test setup for React Native Appearance package
5
- */
6
-
7
- import 'react-native-gesture-handler/jestSetup';
8
-
9
- // Mock console methods for testing
10
- if (__DEV__) {
11
- global.console = {
12
- ...console,
13
- // Suppress specific console warnings in tests
14
- warn: jest.fn(),
15
- error: jest.fn(),
16
- };
17
- }
18
-
19
- // Mock performance API for testing
20
- if (typeof performance === 'undefined') {
21
- global.performance = {
22
- now: jest.fn(() => Date.now()),
23
- mark: jest.fn(),
24
- measure: jest.fn(),
25
- getEntriesByName: jest.fn(() => []),
26
- getEntriesByType: jest.fn(() => []),
27
- clearMarks: jest.fn(),
28
- clearMeasures: jest.fn(),
29
- clearResourceTimings: jest.fn(),
30
- } as any;
31
- }
32
-
33
- // Mock React Native modules
34
- jest.mock('react-native', () => {
35
- const RN = jest.requireActual('react-native');
36
- return {
37
- ...RN,
38
- Platform: {
39
- OS: 'ios',
40
- select: jest.fn((obj) => obj.ios),
41
- },
42
- };
43
- });
44
-
45
- // Mock design system theme
46
- jest.mock('@umituz/react-native-design-system', () => ({
47
- useTheme: jest.fn(() => ({
48
- setThemeMode: jest.fn(),
49
- })),
50
- useDesignSystemTheme: jest.fn(() => ({
51
- setThemeMode: jest.fn(),
52
- setCustomColors: jest.fn(),
53
- })),
54
- }));
55
-
56
- // Mock storage
57
- jest.mock('@umituz/react-native-storage', () => ({
58
- storageRepository: {
59
- getItem: jest.fn(() => ({
60
- success: true,
61
- data: null,
62
- })),
63
- setItem: jest.fn(() => ({
64
- success: true,
65
- })),
66
- removeItem: jest.fn(() => ({
67
- success: true,
68
- })),
69
- },
70
- unwrap: jest.fn((result, defaultValue) =>
71
- result.success ? result.data : defaultValue
72
- ),
73
- }));
74
-
75
-
76
-
77
- // Mock localization
78
- jest.mock('@umituz/react-native-localization', () => ({
79
- useLocalization: jest.fn(() => ({
80
- t: jest.fn((key) => key),
81
- })),
82
- }));
83
-
84
- // Global test utilities
85
- (globalThis as any).__TEST__ = true;
86
-
87
- // Mock timers
88
- jest.useFakeTimers();
@@ -1,175 +0,0 @@
1
- /**
2
- * Appearance Store Tests
3
- */
4
-
5
- import { renderHook, act } from '@testing-library/react-native';
6
- import { useAppearanceStore } from '../../infrastructure/stores/appearanceStore';
7
- import type { AppearanceSettings, ThemeMode, CustomThemeColors } from '../../types';
8
-
9
- // Mock design system theme
10
- jest.mock('@umituz/react-native-design-system', () => ({
11
- useTheme: {
12
- getState: jest.fn(() => ({
13
- setThemeMode: jest.fn(),
14
- })),
15
- },
16
- useDesignSystemTheme: {
17
- getState: jest.fn(() => ({
18
- setThemeMode: jest.fn(),
19
- setCustomColors: jest.fn(),
20
- })),
21
- },
22
- }));
23
-
24
- const mockUseTheme = require('@umituz/react-native-design-system').useTheme;
25
- const mockUseDesignSystemTheme = require('@umituz/react-native-design-system').useDesignSystemTheme;
26
-
27
- describe('useAppearanceStore', () => {
28
- beforeEach(() => {
29
- jest.clearAllMocks();
30
- });
31
-
32
- afterEach(() => {
33
- jest.restoreAllMocks();
34
- });
35
-
36
- it('should initialize with default settings', () => {
37
- const { result } = renderHook(() => useAppearanceStore());
38
-
39
- expect(result.current).toEqual({
40
- settings: {
41
- themeMode: 'dark',
42
- },
43
- isInitialized: false,
44
- });
45
-
46
- expect(typeof result.current.setSettings).toBe('function');
47
- expect(typeof result.current.setInitialized).toBe('function');
48
- expect(typeof result.current.updateThemeMode).toBe('function');
49
- expect(typeof result.current.updateCustomColors).toBe('function');
50
- expect(typeof result.current.resetState).toBe('function');
51
- });
52
-
53
- it('should update settings correctly', () => {
54
- const { result } = renderHook(() => useAppearanceStore());
55
-
56
- const newSettings: AppearanceSettings = {
57
- themeMode: 'light',
58
- customColors: { primary: '#FF0000' },
59
- };
60
-
61
- act(() => {
62
- result.current.setSettings(newSettings);
63
- });
64
-
65
- expect(result.current.settings).toEqual(newSettings);
66
- expect(mockUseTheme.getState().setThemeMode).not.toHaveBeenCalled();
67
- expect(mockUseDesignSystemTheme.getState().setThemeMode).not.toHaveBeenCalled();
68
- });
69
-
70
- it('should update theme mode correctly', () => {
71
- const { result } = renderHook(() => useAppearanceStore());
72
-
73
- act(() => {
74
- result.current.updateThemeMode('light');
75
- });
76
-
77
- expect(result.current.settings.themeMode).toBe('light');
78
- expect(mockUseTheme.getState().setThemeMode).not.toHaveBeenCalled();
79
- expect(mockUseDesignSystemTheme.getState().setThemeMode).not.toHaveBeenCalled();
80
- });
81
-
82
- it('should not update theme mode if same value', () => {
83
- const { result } = renderHook(() => useAppearanceStore());
84
-
85
- act(() => {
86
- result.current.updateThemeMode('dark'); // Default is dark
87
- });
88
-
89
- expect(result.current.settings.themeMode).toBe('dark');
90
- });
91
-
92
- it('should update custom colors correctly', () => {
93
- const { result } = renderHook(() => useAppearanceStore());
94
-
95
- const newColors: CustomThemeColors = { primary: '#FF0000' };
96
-
97
- act(() => {
98
- result.current.updateCustomColors(newColors);
99
- });
100
-
101
- expect(result.current.settings.customColors).toEqual(newColors);
102
- });
103
-
104
- it('should not update custom colors if same value', () => {
105
- const { result } = renderHook(() => useAppearanceStore());
106
-
107
- const newColors: CustomThemeColors = { primary: '#FF0000' };
108
-
109
- act(() => {
110
- result.current.updateCustomColors(newColors);
111
- result.current.updateCustomColors(newColors); // Second call with same value
112
- });
113
-
114
- // Should only be called once due to optimization
115
- expect(mockUseDesignSystemTheme.getState().setCustomColors).toHaveBeenCalledTimes(1);
116
- });
117
-
118
- it('should reset state correctly', () => {
119
- const { result } = renderHook(() => useAppearanceStore());
120
-
121
- const customColors: CustomThemeColors = { primary: '#FF0000' };
122
-
123
- act(() => {
124
- result.current.updateCustomColors(customColors);
125
- result.current.setInitialized(true);
126
- result.current.resetState();
127
- });
128
-
129
- expect(result.current.settings).toEqual({
130
- themeMode: 'dark',
131
- });
132
- expect(result.current.isInitialized).toBe(false);
133
- });
134
-
135
- it('should not reset if already at default', () => {
136
- const { result } = renderHook(() => useAppearanceStore());
137
-
138
- act(() => {
139
- result.current.resetState();
140
- result.current.resetState(); // Second call
141
- });
142
-
143
- // Should only be called once due to optimization
144
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalledTimes(1);
145
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalledTimes(1);
146
- });
147
-
148
- it('should handle setInitialized correctly', () => {
149
- const { result } = renderHook(() => useAppearanceStore());
150
-
151
- act(() => {
152
- result.current.setInitialized(true);
153
- });
154
-
155
- expect(result.current.isInitialized).toBe(true);
156
-
157
- act(() => {
158
- result.current.setInitialized(true); // Second call with same value
159
- });
160
-
161
- // Should not be called again due to optimization
162
- expect(result.current.isInitialized).toBe(true);
163
- });
164
-
165
- it('should handle setInitialized changes correctly', () => {
166
- const { result } = renderHook(() => useAppearanceStore());
167
-
168
- act(() => {
169
- result.current.setInitialized(false);
170
- result.current.setInitialized(true);
171
- });
172
-
173
- expect(result.current.isInitialized).toBe(true);
174
- });
175
- });
@@ -1,78 +0,0 @@
1
- /**
2
- * Tests for CloudSyncSetting Component
3
- */
4
-
5
- import React from 'react';
6
- import { render, fireEvent } from '@testing-library/react-native';
7
- import { CloudSyncSetting } from '../CloudSyncSetting';
8
-
9
- // Mock lucide-react-native
10
- jest.mock('lucide-react-native', () => ({
11
- Cloud: 'Cloud',
12
- }));
13
-
14
- // Mock SettingsItemCard component
15
- jest.mock('../../../../../presentation/components/SettingsItemCard', () => {
16
- const React = require('react');
17
- const { View, Text } = require('react-native');
18
-
19
- return {
20
- SettingsItemCard: ({ icon, title, description, onPress, testID, showSwitch, switchValue, onSwitchChange, disabled }: any) => (
21
- React.createElement(View, {
22
- testID: testID || 'setting-item',
23
- onTouchEnd: onPress,
24
- style: { padding: 16 }
25
- }, [
26
- React.createElement(Text, { key: 'title' }, title || ''),
27
- description && React.createElement(Text, { key: 'description' }, description),
28
- showSwitch && React.createElement(Text, { key: 'switch' }, switchValue ? 'ON' : 'OFF'),
29
- ])
30
- ),
31
- };
32
- });
33
-
34
- describe('CloudSyncSetting', () => {
35
- it('renders with default props', () => {
36
- const { getByText } = render(<CloudSyncSetting />);
37
-
38
- expect(getByText('cloud_sync')).toBeTruthy();
39
- });
40
-
41
- it('renders with custom title', () => {
42
- const { getByText } = render(<CloudSyncSetting title="Custom Sync" />);
43
-
44
- expect(getByText('Custom Sync')).toBeTruthy();
45
- });
46
-
47
- it('shows syncing state when isSyncing is true', () => {
48
- const { getByText } = render(<CloudSyncSetting isSyncing={true} />);
49
-
50
- expect(getByText('syncing')).toBeTruthy();
51
- });
52
-
53
- it('displays custom description when provided', () => {
54
- const { getByText } = render(
55
- <CloudSyncSetting description="Custom description" />
56
- );
57
-
58
- expect(getByText('Custom description')).toBeTruthy();
59
- });
60
-
61
- it('shows last synced time when provided', () => {
62
- const lastSynced = new Date(Date.now() - 5 * 60 * 1000); // 5 minutes ago
63
- const { getByText } = render(<CloudSyncSetting lastSynced={lastSynced} />);
64
-
65
- expect(getByText('last_synced_5m_ago')).toBeTruthy();
66
- });
67
-
68
- it('handles onPress callback', () => {
69
- const mockOnPress = jest.fn();
70
- const { getByTestId } = render(
71
- <CloudSyncSetting onPress={mockOnPress} />
72
- );
73
-
74
- const pressable = getByTestId('setting-item');
75
- fireEvent.press(pressable);
76
- expect(mockOnPress).toHaveBeenCalled();
77
- });
78
- });