@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,232 +0,0 @@
1
- /**
2
- * Hooks Tests
3
- */
4
-
5
- import { renderHook, act } from '@testing-library/react-native';
6
- import { useAppearance, useAppearanceActions } from '../../hooks';
7
- import type { ThemeMode, CustomThemeColors } from '../../types';
8
-
9
- // Mock design system theme
10
- jest.mock('@umituz/react-native-design-system', () => ({
11
- useTheme: jest.fn(() => ({
12
- getState: jest.fn(() => ({
13
- setThemeMode: jest.fn(),
14
- })),
15
- })),
16
- useDesignSystemTheme: jest.fn(() => ({
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('useAppearance', () => {
28
- beforeEach(() => {
29
- jest.clearAllMocks();
30
-
31
- mockUseTheme.getState.mockReturnValue({
32
- setThemeMode: jest.fn(),
33
- });
34
-
35
- mockUseDesignSystemTheme.getState.mockReturnValue({
36
- setThemeMode: jest.fn(),
37
- setCustomColors: jest.fn(),
38
- });
39
- });
40
-
41
- afterEach(() => {
42
- jest.restoreAllMocks();
43
- });
44
-
45
- it('should return appearance state and actions', () => {
46
- const { result } = renderHook(() => useAppearance());
47
-
48
- expect(result.current).toHaveProperty('themeMode');
49
- expect(result.current).toHaveProperty('customColors');
50
- expect(result.current).toHaveProperty('isInitialized');
51
- expect(result.current).toHaveProperty('setThemeMode');
52
- expect(result.current).toHaveProperty('toggleTheme');
53
- expect(result.current).toHaveProperty('setCustomColors');
54
- expect(result.current).toHaveProperty('resetCustomColors');
55
- expect(result.current).toHaveProperty('reset');
56
-
57
- expect(typeof result.current.setThemeMode).toBe('function');
58
- expect(typeof result.current.toggleTheme).toBe('function');
59
- expect(typeof result.current.setCustomColors).toBe('function');
60
- expect(typeof result.current.resetCustomColors).toBe('function');
61
- expect(typeof result.current.reset).toBe('function');
62
- });
63
-
64
- it('should have stable function references', () => {
65
- const { result: result1 } = renderHook(() => useAppearance());
66
- const { result: result2 } = renderHook(() => useAppearance());
67
-
68
- // Functions should be stable across renders
69
- expect(result1.current.setThemeMode).toBe(result2.current.setThemeMode);
70
- expect(result1.current.toggleTheme).toBe(result2.current.toggleTheme);
71
- expect(result1.current.setCustomColors).toBe(result2.current.setCustomColors);
72
- expect(result1.current.resetCustomColors).toBe(result2.current.resetCustomColors);
73
- expect(result1.current.reset).toBe(result2.current.reset);
74
- });
75
-
76
- it('should call service methods correctly', async () => {
77
- const { result } = renderHook(() => useAppearance());
78
-
79
- const mockSetThemeMode = mockUseTheme.getState().setThemeMode;
80
- const mockSetCustomColors = mockUseDesignSystemTheme.getState().setCustomColors;
81
-
82
- await act(async () => {
83
- await result.current.setThemeMode('light');
84
- });
85
-
86
- expect(mockSetThemeMode).toHaveBeenCalledWith('light');
87
- });
88
-
89
- it('should handle errors gracefully', async () => {
90
- const { result } = renderHook(() => useAppearance());
91
-
92
- const mockSetThemeMode = mockUseTheme.getState().setThemeMode;
93
- const error = new Error('Service error');
94
- mockSetThemeMode.mockImplementation(() => {
95
- throw error;
96
- });
97
-
98
- await expect(result.current.setThemeMode('light')).rejects.toThrow(error);
99
- });
100
- });
101
-
102
- describe('useAppearanceActions', () => {
103
- beforeEach(() => {
104
- jest.clearAllMocks();
105
- });
106
-
107
- afterEach(() => {
108
- jest.restoreAllMocks();
109
- });
110
-
111
- it('should return actions and local state', () => {
112
- const { result } = renderHook(() => useAppearanceActions());
113
-
114
- expect(result.current).toHaveProperty('localCustomColors');
115
- expect(result.current).toHaveProperty('handleThemeSelect');
116
- expect(result.current).toHaveProperty('handleColorChange');
117
- expect(result.current).toHaveProperty('handleResetColors');
118
-
119
- expect(typeof result.current.handleThemeSelect).toBe('function');
120
- expect(typeof result.current.handleColorChange).toBe('function');
121
- expect(typeof result.current.handleResetColors).toBe('function');
122
- });
123
-
124
- it('should initialize with empty custom colors', () => {
125
- const { result } = renderHook(() => useAppearanceActions());
126
-
127
- expect(result.current.localCustomColors).toEqual({});
128
- });
129
-
130
- it('should handle theme selection', async () => {
131
- const { result } = renderHook(() => useAppearanceActions());
132
-
133
- const mockSetThemeMode = mockUseTheme.getState().setThemeMode;
134
-
135
- await act(async () => {
136
- await result.current.handleThemeSelect('light');
137
- });
138
-
139
- expect(mockSetThemeMode).toHaveBeenCalledWith('light');
140
- });
141
-
142
- it('should handle color change', () => {
143
- const { result } = renderHook(() => useAppearanceActions());
144
-
145
- const mockSetCustomColors = mockUseDesignSystemTheme.getState().setCustomColors;
146
-
147
- act(() => {
148
- result.current.handleColorChange('primary', '#FF0000');
149
- });
150
-
151
- expect(mockSetCustomColors).toHaveBeenCalledWith({
152
- primary: '#FF0000',
153
- });
154
- });
155
-
156
- it('should not update if color is same', () => {
157
- const { result } = renderHook(() => useAppearanceActions());
158
-
159
- const mockSetCustomColors = mockUseDesignSystemTheme.getState().setCustomColors;
160
-
161
- act(() => {
162
- result.current.handleColorChange('primary', '#FF0000');
163
- result.current.handleColorChange('primary', '#FF0000'); // Same color
164
- });
165
-
166
- // Should only be called once due to optimization
167
- expect(mockSetCustomColors).toHaveBeenCalledTimes(1);
168
- });
169
-
170
- it('should handle reset colors', () => {
171
- const { result } = renderHook(() => useAppearanceActions());
172
-
173
- const mockResetCustomColors = mockUseDesignSystemTheme.getState().setCustomColors;
174
-
175
- act(() => {
176
- result.current.handleResetColors();
177
- });
178
-
179
- expect(mockResetCustomColors).toHaveBeenCalled();
180
- });
181
-
182
- it('should handle reset colors with config', () => {
183
- const onConfirm = jest.fn();
184
- const config = { onResetConfirm };
185
-
186
- const { result } = renderHook(() => useAppearanceActions(config));
187
-
188
- const mockResetCustomColors = mockUseDesignSystemTheme.getState().setCustomColors;
189
-
190
- act(() => {
191
- result.current.handleResetColors();
192
- });
193
-
194
- expect(mockResetCustomColors).toHaveBeenCalled();
195
- expect(onConfirm).toHaveBeenCalled();
196
- });
197
-
198
- it('should sync local colors with store changes', () => {
199
- const { result, rerender } = renderHook(
200
- () => useAppearanceActions(),
201
- {
202
- initialProps: { customColors: { primary: '#FF0000' } }
203
- }
204
- );
205
-
206
- expect(result.current.localCustomColors).toEqual({ primary: '#FF0000' });
207
-
208
- // Simulate store change
209
- rerender({ customColors: { primary: '#00FF00' } });
210
-
211
- expect(result.current.localCustomColors).toEqual({ primary: '#00FF00' });
212
- });
213
-
214
- it('should have stable function references', () => {
215
- const { result: result1 } = renderHook(() => useAppearanceActions());
216
- const { result: result2 } = renderHook(() => useAppearanceActions());
217
-
218
- // Functions should be stable across renders
219
- expect(result1.current.handleThemeSelect).toBe(result2.current.handleThemeSelect);
220
- expect(result1.current.handleColorChange).toBe(result2.current.handleColorChange);
221
- expect(result1.current.handleResetColors).toBe(result2.current.handleResetColors);
222
- });
223
-
224
- it('should cleanup on unmount', () => {
225
- const { unmount } = renderHook(() => useAppearanceActions());
226
-
227
- unmount();
228
-
229
- // Should not throw any errors during cleanup
230
- expect(true).toBe(true);
231
- });
232
- });
@@ -1,207 +0,0 @@
1
- /**
2
- * Integration Tests
3
- */
4
-
5
- import React from 'react';
6
- import { render, fireEvent, act } from '@testing-library/react-native';
7
- import { AppearanceService, appearanceService } from '../../infrastructure/services/appearanceService';
8
- import { useAppearanceStore } from '../../infrastructure/stores/appearanceStore';
9
- import { AppearanceScreen } from '../../presentation/screens/AppearanceScreen';
10
- import type { ThemeMode, CustomThemeColors } from '../../types';
11
-
12
- // Mock design system theme
13
- jest.mock('@umituz/react-native-design-system', () => ({
14
- useTheme: {
15
- getState: jest.fn(() => ({
16
- setThemeMode: jest.fn(),
17
- })),
18
- },
19
- useDesignSystemTheme: {
20
- getState: jest.fn(() => ({
21
- setThemeMode: jest.fn(),
22
- setCustomColors: jest.fn(),
23
- })),
24
- },
25
- }));
26
-
27
- // Mock storage
28
- jest.mock('../../infrastructure/storage/appearanceStorage', () => ({
29
- AppearanceStorage: {
30
- getSettings: jest.fn(() => Promise.resolve(null)),
31
- setSettings: jest.fn(() => Promise.resolve()),
32
- clear: jest.fn(() => Promise.resolve()),
33
- },
34
- }));
35
-
36
- const mockUseTheme = require('@umituz/react-native-design-system').useTheme;
37
- const mockUseDesignSystemTheme = require('@umituz/react-native-design-system').useDesignSystemTheme;
38
- const mockAppearanceStorage = require('../../infrastructure/storage/appearanceStorage').AppearanceStorage;
39
-
40
- describe('Appearance Integration Tests', () => {
41
- beforeEach(() => {
42
- jest.clearAllMocks();
43
- });
44
-
45
- afterEach(() => {
46
- jest.restoreAllMocks();
47
- });
48
-
49
- it('should initialize and render correctly', async () => {
50
- const { getByTestId } = render(<AppearanceScreen />);
51
-
52
- // Should render without crashing
53
- expect(getByTestId('appearance-screen')).toBeTruthy();
54
-
55
- // Should initialize service
56
- await act(async () => {
57
- await appearanceService.initialize();
58
- });
59
-
60
- expect(mockAppearanceStorage.getSettings).toHaveBeenCalled();
61
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalled();
62
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalled();
63
- });
64
-
65
- it('should handle theme mode changes end-to-end', async () => {
66
- const { getByTestId } = render(<AppearanceScreen />);
67
-
68
- // Initialize service
69
- await act(async () => {
70
- await appearanceService.initialize();
71
- });
72
-
73
- // Change theme mode
74
- await act(async () => {
75
- await appearanceService.setThemeMode('light');
76
- });
77
-
78
- // Verify all systems are updated
79
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalledWith('light');
80
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalledWith('light');
81
- expect(mockAppearanceStorage.setSettings).toHaveBeenCalledWith({
82
- themeMode: 'light',
83
- });
84
- });
85
-
86
- it('should handle custom color changes end-to-end', async () => {
87
- const { getByTestId } = render(<AppearanceScreen />);
88
-
89
- // Initialize service
90
- await act(async () => {
91
- await appearanceService.initialize();
92
- });
93
-
94
- // Change custom colors
95
- const newColors: CustomThemeColors = {
96
- primary: '#FF0000',
97
- secondary: '#00FF00',
98
- };
99
-
100
- await act(async () => {
101
- await appearanceService.setCustomColors(newColors);
102
- });
103
-
104
- // Verify all systems are updated
105
- expect(mockUseDesignSystemTheme.getState().setCustomColors).toHaveBeenCalledWith(newColors);
106
- expect(mockAppearanceStorage.setSettings).toHaveBeenCalledWith({
107
- themeMode: 'dark', // Default theme
108
- customColors: newColors,
109
- });
110
- });
111
-
112
- it('should handle reset end-to-end', async () => {
113
- const { getByTestId } = render(<AppearanceScreen />);
114
-
115
- // Initialize with custom settings
116
- await act(async () => {
117
- await appearanceService.setThemeMode('light');
118
- await appearanceService.setCustomColors({
119
- primary: '#FF0000',
120
- secondary: '#00FF00',
121
- });
122
- });
123
-
124
- // Reset everything
125
- await act(async () => {
126
- await appearanceService.reset();
127
- });
128
-
129
- // Verify reset
130
- expect(mockAppearanceStorage.clear).toHaveBeenCalled();
131
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalledWith('dark');
132
- expect(mockUseDesignSystemTheme.getState().setThemeMode).toHaveBeenCalledWith('dark');
133
- expect(mockUseDesignSystemTheme.getState().setCustomColors).toHaveBeenCalledWith(undefined);
134
- });
135
-
136
- it('should handle errors gracefully', async () => {
137
- const { getByTestId } = render(<AppearanceScreen />);
138
-
139
- // Mock storage to throw error
140
- mockAppearanceStorage.setSettings.mockRejectedValue(new Error('Storage failed'));
141
-
142
- // Should still render without crashing
143
- expect(getByTestId('appearance-screen')).toBeTruthy();
144
-
145
- // Should handle error gracefully
146
- await act(async () => {
147
- await appearanceService.setThemeMode('light');
148
- });
149
-
150
- // Should still attempt to update despite storage error
151
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenCalled();
152
- });
153
-
154
- it('should prevent memory leaks during rapid updates', async () => {
155
- const { getByTestId } = render(<AppearanceScreen />);
156
-
157
- // Initialize service
158
- await act(async () => {
159
- await appearanceService.initialize();
160
- });
161
-
162
- // Rapid theme changes
163
- const promises = [];
164
- for (let i = 0; i < 10; i++) {
165
- promises.push(
166
- act(async () => {
167
- await appearanceService.setThemeMode(i % 2 === 0 ? 'light' : 'dark');
168
- })
169
- );
170
- }
171
-
172
- await Promise.all(promises);
173
-
174
- // Should handle rapid changes without memory leaks
175
- expect(getByTestId('appearance-screen')).toBeTruthy();
176
-
177
- // Verify final state
178
- const finalTheme = i % 2 === 0 ? 'dark' : 'light';
179
- expect(mockUseTheme.getState().setThemeMode).toHaveBeenLastCalledWith(finalTheme);
180
- });
181
-
182
- it('should maintain performance during heavy usage', async () => {
183
- const { getByTestId } = render(<AppearanceScreen />);
184
-
185
- const startTime = performance.now();
186
-
187
- // Heavy usage simulation
188
- await act(async () => {
189
- await appearanceService.initialize();
190
-
191
- // Rapid color changes
192
- for (let i = 0; i < 20; i++) {
193
- const colors: CustomThemeColors = {
194
- primary: `#${i.toString(16).padStart(6, '0')}`,
195
- };
196
- await appearanceService.setCustomColors(colors);
197
- }
198
- });
199
-
200
- const endTime = performance.now();
201
- const duration = endTime - startTime;
202
-
203
- // Should complete within reasonable time
204
- expect(duration).toBeLessThan(1000); // 1 second for 20 color changes
205
- expect(getByTestId('appearance-screen')).toBeTruthy();
206
- });
207
- });