@umituz/react-native-settings 4.20.61 → 4.21.1

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 (78) hide show
  1. package/package.json +8 -60
  2. package/src/domains/gamification/README.md +343 -0
  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 +91 -0
  13. package/src/domains/gamification/components/GamificationSettingsItem.tsx +33 -0
  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 +70 -0
  20. package/src/domains/gamification/examples/localization.example.json +71 -0
  21. package/src/domains/gamification/hooks/useGamification.ts +91 -0
  22. package/src/domains/gamification/index.ts +65 -0
  23. package/src/domains/gamification/store/gamificationStore.ts +162 -0
  24. package/src/domains/gamification/types/index.ts +103 -0
  25. package/src/domains/gamification/types/settings.ts +28 -0
  26. package/src/domains/gamification/utils/calculations.ts +85 -0
  27. package/src/index.ts +18 -8
  28. package/src/presentation/navigation/SettingsStackNavigator.tsx +12 -0
  29. package/src/presentation/navigation/types.ts +2 -0
  30. package/src/presentation/navigation/utils/navigationScreenOptions.ts +7 -0
  31. package/src/presentation/screens/types/UserFeatureConfig.ts +2 -0
  32. package/src/presentation/utils/configCreators.ts +147 -0
  33. package/src/presentation/utils/index.ts +5 -0
  34. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -51
  35. package/.github/ISSUE_TEMPLATE/documentation.md +0 -52
  36. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -63
  37. package/.github/PULL_REQUEST_TEMPLATE.md +0 -84
  38. package/AI_AGENT_GUIDELINES.md +0 -367
  39. package/ARCHITECTURE.md +0 -246
  40. package/CHANGELOG.md +0 -67
  41. package/CODE_OF_CONDUCT.md +0 -75
  42. package/CONTRIBUTING.md +0 -107
  43. package/DOCUMENTATION_MIGRATION.md +0 -319
  44. package/DOCUMENTATION_TEMPLATE.md +0 -155
  45. package/SECURITY.md +0 -98
  46. package/SETTINGS_SCREEN_GUIDE.md +0 -185
  47. package/TESTING.md +0 -358
  48. package/src/__tests__/integration.test.tsx +0 -371
  49. package/src/__tests__/performance.test.tsx +0 -369
  50. package/src/__tests__/setup.test.tsx +0 -20
  51. package/src/__tests__/setup.ts +0 -154
  52. package/src/domains/about/__tests__/integration.test.tsx +0 -328
  53. package/src/domains/about/__tests__/types.d.ts +0 -5
  54. package/src/domains/about/domain/entities/__tests__/AppInfo.test.ts +0 -93
  55. package/src/domains/about/infrastructure/repositories/__tests__/AboutRepository.test.ts +0 -153
  56. package/src/domains/about/presentation/components/__tests__/AboutContent.simple.test.tsx +0 -178
  57. package/src/domains/about/presentation/components/__tests__/AboutContent.test.tsx +0 -293
  58. package/src/domains/about/presentation/components/__tests__/AboutHeader.test.tsx +0 -201
  59. package/src/domains/about/presentation/components/__tests__/AboutSettingItem.test.tsx +0 -71
  60. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.simple.test.tsx +0 -229
  61. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.test.tsx +0 -240
  62. package/src/domains/about/presentation/screens/__tests__/AboutScreen.simple.test.tsx +0 -199
  63. package/src/domains/about/presentation/screens/__tests__/AboutScreen.test.tsx +0 -366
  64. package/src/domains/about/utils/__tests__/index.test.ts +0 -408
  65. package/src/domains/appearance/__tests__/components/AppearanceScreen.test.tsx +0 -195
  66. package/src/domains/appearance/__tests__/hooks/index.test.tsx +0 -232
  67. package/src/domains/appearance/__tests__/integration/index.test.tsx +0 -207
  68. package/src/domains/appearance/__tests__/services/appearanceService.test.ts +0 -299
  69. package/src/domains/appearance/__tests__/setup.ts +0 -88
  70. package/src/domains/appearance/__tests__/stores/appearanceStore.test.tsx +0 -175
  71. package/src/domains/cloud-sync/presentation/components/__tests__/CloudSyncSetting.test.tsx +0 -78
  72. package/src/domains/legal/__tests__/ContentValidationService.test.ts +0 -195
  73. package/src/domains/legal/__tests__/StyleCacheService.test.ts +0 -110
  74. package/src/domains/legal/__tests__/UrlHandlerService.test.ts +0 -71
  75. package/src/domains/legal/__tests__/setup.ts +0 -82
  76. package/src/presentation/components/__tests__/SettingsErrorBoundary.test.tsx +0 -186
  77. package/src/presentation/screens/__tests__/SettingsScreen.test.tsx +0 -322
  78. package/src/presentation/screens/hooks/__tests__/useFeatureDetection.test.tsx +0 -261
@@ -1,371 +0,0 @@
1
- /**
2
- * Integration Tests for Settings Package
3
- * Tests component interactions and data flow
4
- */
5
-
6
- import React from 'react';
7
- import { render, fireEvent, waitFor } from '@testing-library/react-native';
8
- import { NavigationContainer } from '@react-navigation/native';
9
- import { SettingsScreen } from '../../screens/SettingsScreen';
10
- import { useSettings } from '../../../infrastructure/storage/SettingsStore';
11
-
12
- // Mock all dependencies
13
- jest.mock('@umituz/react-native-design-system', () => ({
14
- useDesignSystemTheme: () => ({
15
- themeMode: 'light',
16
- }),
17
- useAppDesignTokens: () => ({
18
- colors: {
19
- backgroundPrimary: '#ffffff',
20
- },
21
- }),
22
- }));
23
-
24
- jest.mock('@umituz/react-native-localization', () => ({
25
- useLocalization: () => ({
26
- t: (key: string) => key,
27
- }),
28
- }));
29
-
30
- jest.mock('@umituz/react-native-storage', () => ({
31
- storageRepository: {
32
- getItem: jest.fn(),
33
- setItem: jest.fn(),
34
- },
35
- StorageKey: {
36
- SETTINGS: 'settings',
37
- },
38
- createUserKey: (key: string, userId: string) => `${key}_${userId}`,
39
- unwrap: (result: any, defaultValue: any) => result.success ? result.data : defaultValue,
40
- }));
41
-
42
- jest.mock('../../components/SettingsHeader', () => {
43
- const { View } = require('react-native');
44
- return {
45
- SettingsHeader: ({ showCloseButton, onClose }: any) => (
46
- <View testID="settings-header">
47
- {showCloseButton && <View testID="close-button" onTouchEnd={onClose} />}
48
- </View>
49
- ),
50
- };
51
- });
52
-
53
- jest.mock('../../components/SettingsContent', () => {
54
- const { View } = require('react-native');
55
- return {
56
- SettingsContent: ({ normalizedConfig, features, showUserProfile, userProfile, showFooter, footerText, customSections, showCloseButton }: any) => (
57
- <View testID="settings-content">
58
- <View testID="config-data">{JSON.stringify(normalizedConfig)}</View>
59
- <View testID="features-data">{JSON.stringify(features)}</View>
60
- {showUserProfile && <View testID="user-profile">{JSON.stringify(userProfile)}</View>}
61
- {showFooter && <View testID="footer">{footerText || 'default-footer'}</View>}
62
- {customSections && <View testID="custom-sections">{JSON.stringify(customSections)}</View>}
63
- {showCloseButton && <View testID="content-close-button" />}
64
- </View>
65
- ),
66
- };
67
- });
68
-
69
- jest.mock('../../components/SettingsErrorBoundary', () => {
70
- const { View } = require('react-native');
71
- return {
72
- SettingsErrorBoundary: ({ children, fallbackTitle, fallbackMessage }: any) => (
73
- <View testID="error-boundary">
74
- {children}
75
- {fallbackTitle && <View testID="fallback-title">{fallbackTitle}</View>}
76
- {fallbackMessage && <View testID="fallback-message">{fallbackMessage}</View>}
77
- </View>
78
- ),
79
- };
80
- });
81
-
82
- jest.mock('../../utils/normalizeConfig', () => ({
83
- normalizeSettingsConfig: jest.fn((config) => ({
84
- appearance: { enabled: config.appearance !== false, config: { enabled: true } },
85
- language: { enabled: config.language !== false, config: { enabled: true } },
86
- notifications: { enabled: config.notifications !== false, config: { enabled: true } },
87
- about: { enabled: config.about !== false, config: { enabled: true } },
88
- legal: { enabled: config.legal !== false, config: { enabled: true } },
89
- account: { enabled: config.account !== false, config: { enabled: true } },
90
- support: { enabled: config.support !== false, config: { enabled: true } },
91
- developer: { enabled: config.developer !== false, config: { enabled: true } },
92
- })),
93
- }));
94
-
95
- jest.mock('../../hooks/useFeatureDetection', () => ({
96
- useFeatureDetection: jest.fn((config, navigation, options) => ({
97
- appearance: config.appearance?.enabled !== false,
98
- language: config.language?.enabled !== false,
99
- notifications: config.notifications?.enabled !== false && options?.notificationServiceAvailable !== false,
100
- about: config.about?.enabled !== false,
101
- legal: config.legal?.enabled !== false,
102
- account: config.account?.enabled !== false,
103
- support: config.support?.enabled !== false,
104
- developer: config.developer?.enabled !== false && __DEV__,
105
- })),
106
- }));
107
-
108
- jest.mock('@react-navigation/native', () => ({
109
- useNavigation: () => ({
110
- navigate: jest.fn(),
111
- goBack: jest.fn(),
112
- getState: jest.fn(() => ({
113
- routes: [{ name: 'Settings' }],
114
- })),
115
- }),
116
- }));
117
-
118
- const TestWrapper = ({ children }: { children: React.ReactNode }) => (
119
- <NavigationContainer>
120
- {children}
121
- </NavigationContainer>
122
- );
123
-
124
- describe('Settings Integration Tests', () => {
125
- beforeEach(() => {
126
- jest.clearAllMocks();
127
- });
128
-
129
- describe('SettingsScreen Integration', () => {
130
- it('integrates all components correctly', () => {
131
- const config = {
132
- appearance: true,
133
- notifications: true,
134
- about: true,
135
- };
136
-
137
- const userProfile = {
138
- displayName: 'John Doe',
139
- userId: 'user123',
140
- };
141
-
142
- const customSections = [
143
- {
144
- title: 'Custom Section',
145
- data: [{ id: '1', title: 'Custom Item' }],
146
- },
147
- ];
148
-
149
- const { getByTestId } = render(
150
- <TestWrapper>
151
- <SettingsScreen
152
- config={config}
153
- showUserProfile={true}
154
- userProfile={userProfile}
155
- showFooter={true}
156
- footerText="Custom Footer"
157
- customSections={customSections}
158
- showCloseButton={true}
159
- />
160
- </TestWrapper>
161
- );
162
-
163
- expect(getByTestId('settings-header')).toBeTruthy();
164
- expect(getByTestId('error-boundary')).toBeTruthy();
165
- expect(getByTestId('settings-content')).toBeTruthy();
166
- expect(getByTestId('user-profile')).toBeTruthy();
167
- expect(getByTestId('footer')).toBeTruthy();
168
- expect(getByTestId('custom-sections')).toBeTruthy();
169
- expect(getByTestId('close-button')).toBeTruthy();
170
- expect(getByTestId('content-close-button')).toBeTruthy();
171
- });
172
-
173
- it('passes config through normalization correctly', () => {
174
- const config = {
175
- appearance: true,
176
- notifications: false,
177
- about: true,
178
- };
179
-
180
- const { getByTestId } = render(
181
- <TestWrapper>
182
- <SettingsScreen config={config} />
183
- </TestWrapper>
184
- );
185
-
186
- const configData = JSON.parse(getByTestId('config-data').props.children);
187
- expect(configData.appearance.enabled).toBe(true);
188
- expect(configData.notifications.enabled).toBe(false);
189
- expect(configData.about.enabled).toBe(true);
190
- });
191
-
192
- it('integrates feature detection correctly', () => {
193
- const config = {
194
- appearance: true,
195
- notifications: true,
196
- about: true,
197
- };
198
-
199
- const featureOptions = {
200
- notificationServiceAvailable: false,
201
- };
202
-
203
- const { getByTestId } = render(
204
- <TestWrapper>
205
- <SettingsScreen
206
- config={config}
207
- featureOptions={featureOptions}
208
- />
209
- </TestWrapper>
210
- );
211
-
212
- const featuresData = JSON.parse(getByTestId('features-data').props.children);
213
- expect(featuresData.appearance).toBe(true);
214
- expect(featuresData.notifications).toBe(false); // Disabled due to service unavailable
215
- expect(featuresData.about).toBe(true);
216
- });
217
-
218
- it('handles close button integration', () => {
219
- const mockOnClose = jest.fn();
220
-
221
- const { getByTestId } = render(
222
- <TestWrapper>
223
- <SettingsScreen
224
- showCloseButton={true}
225
- onClose={mockOnClose}
226
- />
227
- </TestWrapper>
228
- );
229
-
230
- fireEvent.press(getByTestId('close-button'));
231
- expect(mockOnClose).toHaveBeenCalled();
232
- });
233
-
234
- it('integrates error boundary correctly', () => {
235
- const { getByTestId } = render(
236
- <TestWrapper>
237
- <SettingsScreen
238
- fallbackTitle="custom.error.title"
239
- fallbackMessage="custom.error.message"
240
- />
241
- </TestWrapper>
242
- );
243
-
244
- expect(getByTestId('fallback-title')).toBeTruthy();
245
- expect(getByTestId('fallback-message')).toBeTruthy();
246
- });
247
- });
248
-
249
- describe('Data Flow Integration', () => {
250
- it('maintains data consistency through component tree', () => {
251
- const config = {
252
- appearance: true,
253
- language: true,
254
- notifications: true,
255
- };
256
-
257
- const userProfile = {
258
- displayName: 'Test User',
259
- userId: 'test123',
260
- isGuest: false,
261
- };
262
-
263
- const { getByTestId } = render(
264
- <TestWrapper>
265
- <SettingsScreen
266
- config={config}
267
- showUserProfile={true}
268
- userProfile={userProfile}
269
- />
270
- </TestWrapper>
271
- );
272
-
273
- // Verify config data flows correctly
274
- const configData = JSON.parse(getByTestId('config-data').props.children);
275
- expect(configData.appearance.enabled).toBe(true);
276
- expect(configData.language.enabled).toBe(true);
277
- expect(configData.notifications.enabled).toBe(true);
278
-
279
- // Verify user profile data flows correctly
280
- const profileData = JSON.parse(getByTestId('user-profile').props.children);
281
- expect(profileData.displayName).toBe('Test User');
282
- expect(profileData.userId).toBe('test123');
283
- expect(profileData.isGuest).toBe(false);
284
- });
285
-
286
- it('handles empty and null states gracefully', () => {
287
- const { getByTestId, queryByTestId } = render(
288
- <TestWrapper>
289
- <SettingsScreen
290
- config={{}}
291
- userProfile={{}}
292
- customSections={[]}
293
- showFooter={false}
294
- />
295
- </TestWrapper>
296
- );
297
-
298
- expect(getByTestId('settings-content')).toBeTruthy();
299
- expect(queryByTestId('user-profile')).toBeNull();
300
- expect(queryByTestId('footer')).toBeNull();
301
- expect(queryByTestId('custom-sections')).toBeTruthy();
302
- });
303
- });
304
-
305
- describe('Theme Integration', () => {
306
- it('applies theme consistently across components', () => {
307
- const { getByTestId } = render(
308
- <TestWrapper>
309
- <SettingsScreen />
310
- </TestWrapper>
311
- );
312
-
313
- // All components should receive the same theme context
314
- expect(getByTestId('settings-screen')).toBeTruthy();
315
- });
316
- });
317
-
318
- describe('Navigation Integration', () => {
319
- it('integrates with navigation system correctly', () => {
320
- const { getByTestId } = render(
321
- <TestWrapper>
322
- <SettingsScreen />
323
- </TestWrapper>
324
- );
325
-
326
- // Navigation should be available to all child components
327
- expect(getByTestId('settings-screen')).toBeTruthy();
328
- });
329
- });
330
-
331
- describe('Performance Integration', () => {
332
- it('renders efficiently with large datasets', () => {
333
- const largeCustomSections = Array.from({ length: 100 }, (_, i) => ({
334
- title: `Section ${i}`,
335
- data: Array.from({ length: 50 }, (_, j) => ({
336
- id: `item-${i}-${j}`,
337
- title: `Item ${i}-${j}`,
338
- })),
339
- }));
340
-
341
- const startTime = performance.now();
342
-
343
- const { getByTestId } = render(
344
- <TestWrapper>
345
- <SettingsScreen
346
- customSections={largeCustomSections}
347
- />
348
- </TestWrapper>
349
- );
350
-
351
- const endTime = performance.now();
352
- const renderTime = endTime - startTime;
353
-
354
- expect(getByTestId('settings-screen')).toBeTruthy();
355
- expect(renderTime).toBeLessThan(1000); // Should render within 1 second
356
- });
357
- });
358
-
359
- describe('Error Handling Integration', () => {
360
- it('handles errors gracefully across component boundaries', () => {
361
- const { getByTestId } = render(
362
- <TestWrapper>
363
- <SettingsScreen />
364
- </TestWrapper>
365
- );
366
-
367
- // Error boundary should catch and handle errors
368
- expect(getByTestId('error-boundary')).toBeTruthy();
369
- });
370
- });
371
- });