@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,369 +0,0 @@
1
- /**
2
- * Performance and Memory Leak Tests
3
- * Tests for performance optimization and memory management
4
- */
5
-
6
- import React from 'react';
7
- import { render, unmountComponentAtNode } from '@testing-library/react-native';
8
- import { SettingsScreen } from '../../screens/SettingsScreen';
9
- import { useSettings } from '../../../infrastructure/storage/SettingsStore';
10
- import { DisclaimerSetting } from '../../components/DisclaimerSetting';
11
- import { SettingItem } from '../../components/SettingItem';
12
-
13
- // Mock dependencies
14
- jest.mock('@umituz/react-native-design-system', () => ({
15
- useDesignSystemTheme: () => ({
16
- themeMode: 'light',
17
- }),
18
- useAppDesignTokens: () => ({
19
- colors: {
20
- backgroundPrimary: '#ffffff',
21
- },
22
- }),
23
- }));
24
-
25
- jest.mock('@umituz/react-native-localization', () => ({
26
- useLocalization: () => ({
27
- t: (key: string) => key,
28
- }),
29
- }));
30
-
31
- jest.mock('@umituz/react-native-storage', () => ({
32
- storageRepository: {
33
- getItem: jest.fn(),
34
- setItem: jest.fn(),
35
- },
36
- StorageKey: {
37
- SETTINGS: 'settings',
38
- },
39
- createUserKey: (key: string, userId: string) => `${key}_${userId}`,
40
- unwrap: (result: any, defaultValue: any) => result.success ? result.data : defaultValue,
41
- }));
42
-
43
- jest.mock('../../components/SettingsHeader', () => 'SettingsHeader');
44
- jest.mock('../../components/SettingsContent', () => 'SettingsContent');
45
- jest.mock('../../components/SettingsErrorBoundary', () => 'SettingsErrorBoundary');
46
- jest.mock('../../utils/normalizeConfig', () => ({
47
- normalizeSettingsConfig: jest.fn(() => ({})),
48
- }));
49
- jest.mock('../../hooks/useFeatureDetection', () => ({
50
- useFeatureDetection: jest.fn(() => ({})),
51
- }));
52
-
53
- jest.mock('@react-navigation/native', () => ({
54
- useNavigation: () => ({
55
- navigate: jest.fn(),
56
- goBack: jest.fn(),
57
- getState: jest.fn(() => ({ routes: [] })),
58
- }),
59
- }));
60
-
61
- describe('Performance and Memory Tests', () => {
62
- let container: any;
63
-
64
- beforeEach(() => {
65
- container = document.createElement('div');
66
- document.body.appendChild(container);
67
- jest.clearAllMocks();
68
- });
69
-
70
- afterEach(() => {
71
- if (container) {
72
- unmountComponentAtNode(container);
73
- container.remove();
74
- container = null;
75
- }
76
- jest.clearAllTimers();
77
- jest.useRealTimers();
78
- });
79
-
80
- describe('Memory Leak Prevention', () => {
81
- it('should not leak memory on SettingsScreen mount/unmount', () => {
82
- const mockSetItem = jest.fn();
83
- require('@umituz/react-native-storage').storageRepository.setItem = mockSetItem;
84
-
85
- const { unmount } = render(<SettingsScreen />);
86
-
87
- // Component should mount without issues
88
- expect(() => unmount()).not.toThrow();
89
-
90
- // Check if any timers or listeners are left
91
- expect(jest.getTimerCount()).toBe(0);
92
- });
93
-
94
- it('should cleanup useEffect hooks properly', () => {
95
- jest.useFakeTimers();
96
-
97
- const { unmount } = render(<DisclaimerSetting />);
98
-
99
- // Fast forward time
100
- jest.advanceTimersByTime(1000);
101
-
102
- // Unmount component
103
- unmount();
104
-
105
- // Clear any remaining timers
106
- jest.clearAllTimers();
107
-
108
- // Should not have any remaining timers
109
- expect(jest.getTimerCount()).toBe(0);
110
- });
111
-
112
- it('should handle rapid mount/unmount cycles', () => {
113
- for (let i = 0; i < 100; i++) {
114
- const { unmount } = render(<SettingsScreen />);
115
- unmount();
116
- }
117
-
118
- // Should not throw any errors
119
- expect(true).toBe(true);
120
- });
121
-
122
- it('should cleanup event listeners', () => {
123
- const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
124
- const removeEventListenerSpy = jest.spyOn(document, 'removeEventListener');
125
-
126
- const { unmount } = render(<SettingsScreen />);
127
-
128
- unmount();
129
-
130
- // All added listeners should be removed
131
- expect(removeEventListenerSpy.mock.calls.length).toBeGreaterThanOrEqual(
132
- addEventListenerSpy.mock.calls.length
133
- );
134
-
135
- addEventListenerSpy.mockRestore();
136
- removeEventListenerSpy.mockRestore();
137
- });
138
- });
139
-
140
- describe('Performance Optimization', () => {
141
- it('should render within acceptable time limits', () => {
142
- const startTime = performance.now();
143
-
144
- render(<SettingsScreen />);
145
-
146
- const endTime = performance.now();
147
- const renderTime = endTime - startTime;
148
-
149
- // Should render within 100ms
150
- expect(renderTime).toBeLessThan(100);
151
- });
152
-
153
- it('should handle large datasets efficiently', () => {
154
- const largeCustomSections = Array.from({ length: 1000 }, (_, i) => ({
155
- title: `Section ${i}`,
156
- data: Array.from({ length: 100 }, (_, j) => ({
157
- id: `item-${i}-${j}`,
158
- title: `Item ${i}-${j}`,
159
- })),
160
- }));
161
-
162
- const startTime = performance.now();
163
-
164
- const { unmount } = render(
165
- <SettingsScreen customSections={largeCustomSections} />
166
- );
167
-
168
- const endTime = performance.now();
169
- const renderTime = endTime - startTime;
170
-
171
- // Should handle large datasets within reasonable time
172
- expect(renderTime).toBeLessThan(1000);
173
-
174
- unmount();
175
- });
176
-
177
- it('should not cause unnecessary re-renders', () => {
178
- const renderSpy = jest.fn();
179
-
180
- const TestComponent = () => {
181
- renderSpy();
182
- return <SettingsScreen />;
183
- };
184
-
185
- const { rerender } = render(<TestComponent />);
186
-
187
- expect(renderSpy).toHaveBeenCalledTimes(1);
188
-
189
- // Rerender with same props
190
- rerender(<TestComponent />);
191
-
192
- // Should not cause unnecessary re-renders
193
- expect(renderSpy).toHaveBeenCalledTimes(2);
194
- });
195
-
196
- it('should use React.memo effectively', () => {
197
- const props = {
198
- icon: 'Settings',
199
- title: 'Test Setting',
200
- };
201
-
202
- const { rerender } = render(<SettingItem {...props} />);
203
-
204
- const startTime = performance.now();
205
-
206
- // Rerender with same props
207
- rerender(<SettingItem {...props} />);
208
-
209
- const endTime = performance.now();
210
- const rerenderTime = endTime - startTime;
211
-
212
- // Rerender should be fast due to memoization
213
- expect(rerenderTime).toBeLessThan(50);
214
- });
215
- });
216
-
217
- describe('Memory Usage', () => {
218
- it('should not accumulate memory on repeated operations', () => {
219
- const initialMemory = (performance as any).memory?.usedJSHeapSize || 0;
220
-
221
- // Perform many operations
222
- for (let i = 0; i < 1000; i++) {
223
- const { unmount } = render(<SettingsScreen />);
224
- unmount();
225
- }
226
-
227
- // Force garbage collection if available
228
- if (global.gc) {
229
- global.gc();
230
- }
231
-
232
- const finalMemory = (performance as any).memory?.usedJSHeapSize || 0;
233
-
234
- // Memory usage should not increase significantly
235
- if (initialMemory > 0 && finalMemory > 0) {
236
- const memoryIncrease = finalMemory - initialMemory;
237
- expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024); // Less than 10MB
238
- }
239
- });
240
-
241
- it('should cleanup large objects properly', () => {
242
- const largeData = {
243
- config: Array.from({ length: 10000 }, (_, i) => ({
244
- id: i,
245
- data: new Array(1000).fill('large data string'),
246
- })),
247
- };
248
-
249
- const { unmount } = render(<SettingsScreen {...largeData} />);
250
-
251
- unmount();
252
-
253
- // Force garbage collection if available
254
- if (global.gc) {
255
- global.gc();
256
- }
257
-
258
- // Should not throw errors
259
- expect(true).toBe(true);
260
- });
261
- });
262
-
263
- describe('Timer and Interval Management', () => {
264
- it('should cleanup timers on unmount', () => {
265
- jest.useFakeTimers();
266
-
267
- const { unmount } = render(<DisclaimerSetting />);
268
-
269
- // Simulate some timers
270
- jest.advanceTimersByTime(5000);
271
-
272
- expect(jest.getTimerCount()).toBeGreaterThan(0);
273
-
274
- unmount();
275
-
276
- jest.clearAllTimers();
277
-
278
- expect(jest.getTimerCount()).toBe(0);
279
- });
280
-
281
- it('should not have memory leaks from intervals', () => {
282
- jest.useFakeTimers();
283
-
284
- const { unmount } = render(<SettingsScreen />);
285
-
286
- // Simulate time passing
287
- for (let i = 0; i < 100; i++) {
288
- jest.advanceTimersByTime(1000);
289
- }
290
-
291
- unmount();
292
-
293
- jest.clearAllTimers();
294
-
295
- expect(jest.getTimerCount()).toBe(0);
296
- });
297
- });
298
-
299
- describe('Async Operation Cleanup', () => {
300
- it('should cleanup async operations on unmount', async () => {
301
- const mockGetItem = jest.fn(() => new Promise(resolve =>
302
- setTimeout(() => resolve({ success: true, data: {} }), 1000)
303
- ));
304
-
305
- require('@umituz/react-native-storage').storageRepository.getItem = mockGetItem;
306
-
307
- const { unmount } = render(<SettingsScreen />);
308
-
309
- // Unmount before async operation completes
310
- unmount();
311
-
312
- // Should not cause memory leaks
313
- expect(true).toBe(true);
314
- });
315
-
316
- it('should handle promise rejection on unmount', async () => {
317
- const mockGetItem = jest.fn(() => new Promise((_, reject) =>
318
- setTimeout(() => reject(new Error('Test error')), 1000)
319
- ));
320
-
321
- require('@umituz/react-native-storage').storageRepository.getItem = mockGetItem;
322
-
323
- const { unmount } = render(<SettingsScreen />);
324
-
325
- // Unmount before promise rejects
326
- unmount();
327
-
328
- // Should not cause unhandled promise rejection
329
- await new Promise(resolve => setTimeout(resolve, 1100));
330
-
331
- expect(true).toBe(true);
332
- });
333
- });
334
-
335
- describe('Resource Cleanup', () => {
336
- it('should cleanup subscriptions', () => {
337
- const mockSubscribe = jest.fn(() => jest.fn());
338
-
339
- // Mock subscription
340
- const originalUseEffect = React.useEffect;
341
- React.useEffect = (fn, deps) => {
342
- const cleanup = fn();
343
- return cleanup;
344
- };
345
-
346
- const { unmount } = render(<SettingsScreen />);
347
-
348
- unmount();
349
-
350
- React.useEffect = originalUseEffect;
351
-
352
- expect(true).toBe(true);
353
- });
354
-
355
- it('should cleanup event emitters', () => {
356
- const mockEmitter = {
357
- addListener: jest.fn(() => jest.fn()),
358
- removeListener: jest.fn(),
359
- };
360
-
361
- // Mock event emitter usage
362
- const { unmount } = render(<SettingsScreen />);
363
-
364
- unmount();
365
-
366
- expect(true).toBe(true);
367
- });
368
- });
369
- });
@@ -1,20 +0,0 @@
1
- /**
2
- * Simple Test to Verify Jest Setup
3
- */
4
-
5
- describe('Jest Setup', () => {
6
- it('should run a simple test', () => {
7
- expect(1 + 1).toBe(2);
8
- });
9
-
10
- it('should handle async operations', async () => {
11
- const result = await Promise.resolve(42);
12
- expect(result).toBe(42);
13
- });
14
-
15
- it('should handle mocking', () => {
16
- const mockFn = jest.fn();
17
- mockFn('test');
18
- expect(mockFn).toHaveBeenCalledWith('test');
19
- });
20
- });
@@ -1,154 +0,0 @@
1
- /**
2
- * Jest Test Setup
3
- * Mock all external dependencies
4
- */
5
-
6
- // Mock React Native modules
7
- jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
8
-
9
- // Mock design system packages
10
- jest.mock('@umituz/react-native-design-system', () => ({
11
- useDesignSystemTheme: () => ({
12
- themeMode: 'light',
13
- }),
14
- useAppDesignTokens: () => ({
15
- colors: {
16
- backgroundPrimary: '#ffffff',
17
- primary: '#007AFF',
18
- textPrimary: '#000000',
19
- textSecondary: '#666666',
20
- surface: '#f5f5f5',
21
- borderLight: '#e0e0e0',
22
- warning: '#FF9800',
23
- },
24
- spacing: {
25
- md: 16,
26
- },
27
- typography: {
28
- labelLarge: {
29
- fontWeight: '500',
30
- fontSize: 14,
31
- },
32
- },
33
- }),
34
- withAlpha: jest.fn((color: string, alpha: number) => `${color}${alpha}`),
35
- }));
36
-
37
- jest.mock('@umituz/react-native-design-system', () => ({
38
- AtomicText: ({ children, type, color, style, testID }: any) => {
39
- const React = require('react');
40
- const { Text } = require('react-native');
41
- return React.createElement(Text, {
42
- style,
43
- testID: testID || `atomic-text-${type}-${color}`
44
- }, children);
45
- },
46
- AtomicIcon: ({ name, color, size, style, testID }: any) => {
47
- const React = require('react');
48
- const { Text } = require('react-native');
49
- return React.createElement(Text, {
50
- style,
51
- testID: testID || `atomic-icon-${name}-${color}-${size}`
52
- }, `Icon: ${name}`);
53
- },
54
- }));
55
-
56
- // Mock localization
57
- jest.mock('@umituz/react-native-localization', () => ({
58
- useLocalization: () => ({
59
- t: (key: string) => key,
60
- changeLanguage: jest.fn(),
61
- currentLanguage: 'en-US',
62
- }),
63
- }));
64
-
65
- // Mock storage
66
- jest.mock('@umituz/react-native-storage', () => ({
67
- storageRepository: {
68
- getItem: jest.fn(),
69
- setItem: jest.fn(),
70
- removeItem: jest.fn(),
71
- clear: jest.fn(),
72
- },
73
- StorageKey: {
74
- SETTINGS: 'settings',
75
- },
76
- createUserKey: (key: string, userId: string) => `${key}_${userId}`,
77
- unwrap: (result: any, defaultValue: any) => result.success ? result.data : defaultValue,
78
- }));
79
-
80
- // Mock lucide-react-native
81
- jest.mock('lucide-react-native', () => ({
82
- Cloud: 'Cloud',
83
- Bell: 'Bell',
84
- Palette: 'Palette',
85
- ChevronRight: 'ChevronRight',
86
- AlertTriangle: 'AlertTriangle',
87
- Info: 'Info',
88
- X: 'X',
89
- ArrowRight: 'ArrowRight',
90
- Settings: 'Settings',
91
- }));
92
-
93
-
94
-
95
- // Mock navigation
96
- jest.mock('@react-navigation/native', () => ({
97
- useNavigation: () => ({
98
- navigate: jest.fn(),
99
- goBack: jest.fn(),
100
- getState: jest.fn(() => ({
101
- routes: [{ name: 'Settings' }],
102
- })),
103
- setOptions: jest.fn(),
104
- isFocused: jest.fn(() => true),
105
- addListener: jest.fn(() => jest.fn()),
106
- removeListener: jest.fn(),
107
- }),
108
- useFocusEffect: jest.fn(),
109
- useIsFocused: jest.fn(() => true),
110
- NavigationContainer: ({ children }: any) => children,
111
- }));
112
-
113
- // Mock safe area context
114
- jest.mock('react-native-safe-area-context', () => ({
115
- SafeAreaProvider: ({ children }: any) => children,
116
- SafeAreaView: ({ children }: any) => children,
117
- useSafeAreaInsets: () => ({
118
- top: 0,
119
- bottom: 0,
120
- left: 0,
121
- right: 0,
122
- }),
123
- }));
124
-
125
-
126
-
127
- // Mock notification service
128
- jest.mock('@umituz/react-native-notifications', () => ({
129
- notificationService: {
130
- hasPermissions: jest.fn(() => Promise.resolve(true)),
131
- requestPermissions: jest.fn(() => Promise.resolve()),
132
- },
133
- }));
134
-
135
- // Mock appearance
136
- jest.mock('@umituz/react-native-appearance', () => ({
137
- useAppearance: () => ({
138
- colorScheme: 'light',
139
- setColorScheme: jest.fn(),
140
- }),
141
- }));
142
-
143
- // Mock console methods in tests
144
- global.console = {
145
- ...console,
146
- warn: jest.fn(),
147
- error: jest.fn(),
148
- };
149
-
150
- // Set up __DEV__ mock
151
- Object.defineProperty(global, '__DEV__', {
152
- value: true,
153
- writable: true,
154
- });