@umituz/react-native-settings 4.20.62 → 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 (69) hide show
  1. package/package.json +6 -61
  2. package/src/domains/gamification/components/AchievementCard.tsx +142 -0
  3. package/src/domains/gamification/components/AchievementItem.tsx +182 -0
  4. package/src/domains/gamification/components/AchievementToast.tsx +122 -0
  5. package/src/domains/gamification/components/GamificationScreen/AchievementsList.tsx +84 -0
  6. package/src/domains/gamification/components/GamificationScreen/Header.tsx +29 -0
  7. package/src/domains/gamification/components/GamificationScreen/StatsGrid.tsx +51 -0
  8. package/src/domains/gamification/components/GamificationScreen/index.tsx +111 -0
  9. package/src/domains/gamification/components/GamificationScreen/styles.ts +43 -0
  10. package/src/domains/gamification/components/GamificationScreen/types.ts +77 -0
  11. package/src/domains/gamification/components/GamificationScreenWrapper.tsx +4 -4
  12. package/src/domains/gamification/components/GamificationSettingsItem.tsx +1 -1
  13. package/src/domains/gamification/components/LevelProgress.tsx +129 -0
  14. package/src/domains/gamification/components/PointsBadge.tsx +60 -0
  15. package/src/domains/gamification/components/StatsCard.tsx +89 -0
  16. package/src/domains/gamification/components/StreakDisplay.tsx +119 -0
  17. package/src/domains/gamification/components/index.ts +13 -0
  18. package/src/domains/gamification/examples/gamification.config.example.ts +1 -1
  19. package/src/domains/gamification/hooks/useGamification.ts +91 -0
  20. package/src/domains/gamification/index.ts +46 -19
  21. package/src/domains/gamification/store/gamificationStore.ts +162 -0
  22. package/src/domains/gamification/types/index.ts +95 -23
  23. package/src/domains/gamification/types/settings.ts +28 -0
  24. package/src/domains/gamification/utils/calculations.ts +85 -0
  25. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -51
  26. package/.github/ISSUE_TEMPLATE/documentation.md +0 -52
  27. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -63
  28. package/.github/PULL_REQUEST_TEMPLATE.md +0 -84
  29. package/AI_AGENT_GUIDELINES.md +0 -367
  30. package/ARCHITECTURE.md +0 -246
  31. package/CHANGELOG.md +0 -67
  32. package/CODE_OF_CONDUCT.md +0 -75
  33. package/CONTRIBUTING.md +0 -107
  34. package/DOCUMENTATION_MIGRATION.md +0 -319
  35. package/DOCUMENTATION_TEMPLATE.md +0 -155
  36. package/SECURITY.md +0 -98
  37. package/SETTINGS_SCREEN_GUIDE.md +0 -185
  38. package/TESTING.md +0 -358
  39. package/src/__tests__/integration.test.tsx +0 -371
  40. package/src/__tests__/performance.test.tsx +0 -369
  41. package/src/__tests__/setup.test.tsx +0 -20
  42. package/src/__tests__/setup.ts +0 -154
  43. package/src/domains/about/__tests__/integration.test.tsx +0 -328
  44. package/src/domains/about/__tests__/types.d.ts +0 -5
  45. package/src/domains/about/domain/entities/__tests__/AppInfo.test.ts +0 -93
  46. package/src/domains/about/infrastructure/repositories/__tests__/AboutRepository.test.ts +0 -153
  47. package/src/domains/about/presentation/components/__tests__/AboutContent.simple.test.tsx +0 -178
  48. package/src/domains/about/presentation/components/__tests__/AboutContent.test.tsx +0 -293
  49. package/src/domains/about/presentation/components/__tests__/AboutHeader.test.tsx +0 -201
  50. package/src/domains/about/presentation/components/__tests__/AboutSettingItem.test.tsx +0 -71
  51. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.simple.test.tsx +0 -229
  52. package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.test.tsx +0 -240
  53. package/src/domains/about/presentation/screens/__tests__/AboutScreen.simple.test.tsx +0 -199
  54. package/src/domains/about/presentation/screens/__tests__/AboutScreen.test.tsx +0 -366
  55. package/src/domains/about/utils/__tests__/index.test.ts +0 -408
  56. package/src/domains/appearance/__tests__/components/AppearanceScreen.test.tsx +0 -195
  57. package/src/domains/appearance/__tests__/hooks/index.test.tsx +0 -232
  58. package/src/domains/appearance/__tests__/integration/index.test.tsx +0 -207
  59. package/src/domains/appearance/__tests__/services/appearanceService.test.ts +0 -299
  60. package/src/domains/appearance/__tests__/setup.ts +0 -88
  61. package/src/domains/appearance/__tests__/stores/appearanceStore.test.tsx +0 -175
  62. package/src/domains/cloud-sync/presentation/components/__tests__/CloudSyncSetting.test.tsx +0 -78
  63. package/src/domains/legal/__tests__/ContentValidationService.test.ts +0 -195
  64. package/src/domains/legal/__tests__/StyleCacheService.test.ts +0 -110
  65. package/src/domains/legal/__tests__/UrlHandlerService.test.ts +0 -71
  66. package/src/domains/legal/__tests__/setup.ts +0 -82
  67. package/src/presentation/components/__tests__/SettingsErrorBoundary.test.tsx +0 -186
  68. package/src/presentation/screens/__tests__/SettingsScreen.test.tsx +0 -322
  69. 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
- });