@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,178 +0,0 @@
1
- /**
2
- * Simple test for AboutContent component
3
- */
4
- import React from 'react';
5
- import { AboutContent } from '../AboutContent';
6
- import { AppInfo, AboutConfig } from '../../../domain/entities/AppInfo';
7
-
8
- describe('AboutContent', () => {
9
- const mockAppInfo: AppInfo = {
10
- name: 'Test App',
11
- version: '1.0.0',
12
- description: 'Test Description',
13
- developer: 'Test Developer',
14
- contactEmail: 'test@example.com',
15
- websiteUrl: 'https://example.com',
16
- websiteDisplay: 'example.com',
17
- moreAppsUrl: 'https://apps.example.com',
18
- privacyPolicyUrl: 'https://example.com/privacy',
19
- termsOfServiceUrl: 'https://example.com/terms',
20
- };
21
-
22
- const mockConfig: AboutConfig = {
23
- appInfo: mockAppInfo,
24
- actions: {
25
- onEmailPress: jest.fn(),
26
- onWebsitePress: jest.fn(),
27
- onPrivacyPress: jest.fn(),
28
- onTermsPress: jest.fn(),
29
- onMoreAppsPress: jest.fn(),
30
- },
31
- };
32
-
33
- it('should render without crashing', () => {
34
- const element = React.createElement(AboutContent, { appInfo: mockAppInfo, config: mockConfig });
35
- expect(element).toBeTruthy();
36
- });
37
-
38
- it('should render developer when provided', () => {
39
- const element = React.createElement(AboutContent, { appInfo: mockAppInfo, config: mockConfig });
40
- expect(element).toBeTruthy();
41
- expect(mockAppInfo.developer).toBe('Test Developer');
42
- });
43
-
44
- it('should render contact email when provided', () => {
45
- const element = React.createElement(AboutContent, { appInfo: mockAppInfo, config: mockConfig });
46
- expect(element).toBeTruthy();
47
- expect(mockAppInfo.contactEmail).toBe('test@example.com');
48
- });
49
-
50
- it('should render website when provided', () => {
51
- const element = React.createElement(AboutContent, { appInfo: mockAppInfo, config: mockConfig });
52
- expect(element).toBeTruthy();
53
- expect(mockAppInfo.websiteUrl).toBe('https://example.com');
54
- });
55
-
56
- it('should render more apps when provided', () => {
57
- const element = React.createElement(AboutContent, { appInfo: mockAppInfo, config: mockConfig });
58
- expect(element).toBeTruthy();
59
- expect(mockAppInfo.moreAppsUrl).toBe('https://apps.example.com');
60
- });
61
-
62
- it('should render privacy policy when provided', () => {
63
- const element = React.createElement(AboutContent, { appInfo: mockAppInfo, config: mockConfig });
64
- expect(element).toBeTruthy();
65
- expect(mockAppInfo.privacyPolicyUrl).toBe('https://example.com/privacy');
66
- });
67
-
68
- it('should render terms of service when provided', () => {
69
- const element = React.createElement(AboutContent, { appInfo: mockAppInfo, config: mockConfig });
70
- expect(element).toBeTruthy();
71
- expect(mockAppInfo.termsOfServiceUrl).toBe('https://example.com/terms');
72
- });
73
-
74
- it('should not render developer when not provided', () => {
75
- const appInfoWithoutDeveloper = {
76
- ...mockAppInfo,
77
- developer: '',
78
- };
79
-
80
- const element = React.createElement(AboutContent, { appInfo: appInfoWithoutDeveloper, config: mockConfig });
81
- expect(element).toBeTruthy();
82
- expect(appInfoWithoutDeveloper.developer).toBe('');
83
- });
84
-
85
- it('should not render contact email when not provided', () => {
86
- const appInfoWithoutEmail = {
87
- ...mockAppInfo,
88
- contactEmail: '',
89
- };
90
-
91
- const element = React.createElement(AboutContent, { appInfo: appInfoWithoutEmail, config: mockConfig });
92
- expect(element).toBeTruthy();
93
- expect(appInfoWithoutEmail.contactEmail).toBe('');
94
- });
95
-
96
- it('should not render website when not provided', () => {
97
- const appInfoWithoutWebsite = {
98
- ...mockAppInfo,
99
- websiteUrl: '',
100
- websiteDisplay: '',
101
- };
102
-
103
- const element = React.createElement(AboutContent, { appInfo: appInfoWithoutWebsite, config: mockConfig });
104
- expect(element).toBeTruthy();
105
- expect(appInfoWithoutWebsite.websiteUrl).toBe('');
106
- });
107
-
108
- it('should use websiteDisplay when provided', () => {
109
- const appInfoWithDisplay = {
110
- ...mockAppInfo,
111
- websiteDisplay: 'Custom Display',
112
- };
113
-
114
- const element = React.createElement(AboutContent, { appInfo: appInfoWithDisplay, config: mockConfig });
115
- expect(element).toBeTruthy();
116
- expect(appInfoWithDisplay.websiteDisplay).toBe('Custom Display');
117
- });
118
-
119
- it('should use websiteUrl when websiteDisplay not provided', () => {
120
- const appInfoWithoutDisplay = {
121
- ...mockAppInfo,
122
- websiteDisplay: '',
123
- };
124
-
125
- const element = React.createElement(AboutContent, { appInfo: appInfoWithoutDisplay, config: mockConfig });
126
- expect(element).toBeTruthy();
127
- expect(appInfoWithoutDisplay.websiteDisplay).toBe('');
128
- });
129
-
130
- it('should handle empty app info', () => {
131
- const emptyAppInfo: AppInfo = {
132
- name: '',
133
- version: '',
134
- description: '',
135
- developer: '',
136
- contactEmail: '',
137
- websiteUrl: '',
138
- websiteDisplay: '',
139
- moreAppsUrl: '',
140
- privacyPolicyUrl: '',
141
- termsOfServiceUrl: '',
142
- };
143
-
144
- const element = React.createElement(AboutContent, { appInfo: emptyAppInfo, config: mockConfig });
145
- expect(element).toBeTruthy();
146
- });
147
-
148
- it('should handle app info with only required fields', () => {
149
- const minimalAppInfo: AppInfo = {
150
- name: 'Minimal App',
151
- version: '1.0.0',
152
- description: '',
153
- developer: '',
154
- contactEmail: '',
155
- websiteUrl: '',
156
- websiteDisplay: '',
157
- moreAppsUrl: '',
158
- privacyPolicyUrl: '',
159
- termsOfServiceUrl: '',
160
- };
161
-
162
- const element = React.createElement(AboutContent, { appInfo: minimalAppInfo, config: mockConfig });
163
- expect(element).toBeTruthy();
164
- expect(minimalAppInfo.name).toBe('Minimal App');
165
- });
166
-
167
- it('should handle special characters in text', () => {
168
- const appInfoWithSpecialChars: AppInfo = {
169
- ...mockAppInfo,
170
- developer: 'Test & Developer <script>',
171
- contactEmail: 'test+special@example.com',
172
- };
173
-
174
- const element = React.createElement(AboutContent, { appInfo: appInfoWithSpecialChars, config: mockConfig });
175
- expect(element).toBeTruthy();
176
- expect(appInfoWithSpecialChars.developer).toBe('Test & Developer <script>');
177
- });
178
- });
@@ -1,293 +0,0 @@
1
- /**
2
- * Tests for AboutContent component
3
- */
4
- import React from 'react';
5
- import { render, fireEvent } from '@testing-library/react';
6
- import { AboutContent } from '../AboutContent';
7
- import { AppInfo, AboutConfig } from '../../../domain/entities/AppInfo';
8
-
9
- describe('AboutContent', () => {
10
- const mockAppInfo: AppInfo = {
11
- name: 'Test App',
12
- version: '1.0.0',
13
- description: 'Test Description',
14
- developer: 'Test Developer',
15
- contactEmail: 'test@example.com',
16
- websiteUrl: 'https://example.com',
17
- websiteDisplay: 'example.com',
18
- moreAppsUrl: 'https://apps.example.com',
19
- };
20
-
21
- const mockConfig: AboutConfig = {
22
- appInfo: mockAppInfo,
23
- actions: {
24
- onEmailPress: jest.fn(),
25
- onWebsitePress: jest.fn(),
26
- onMoreAppsPress: jest.fn(),
27
- },
28
- };
29
-
30
- beforeEach(() => {
31
- jest.clearAllMocks();
32
- });
33
-
34
- describe('Rendering', () => {
35
- it('should render developer when provided', () => {
36
- const { getByText } = render(
37
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
38
- );
39
-
40
- expect(getByText('Developer')).toBeTruthy();
41
- expect(getByText('Test Developer')).toBeTruthy();
42
- });
43
-
44
- it('should render contact email when provided', () => {
45
- const { getByText } = render(
46
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
47
- );
48
-
49
- expect(getByText('Contact')).toBeTruthy();
50
- expect(getByText('test@example.com')).toBeTruthy();
51
- });
52
-
53
- it('should render website when provided', () => {
54
- const { getByText } = render(
55
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
56
- );
57
-
58
- expect(getByText('Website')).toBeTruthy();
59
- expect(getByText('example.com')).toBeTruthy();
60
- });
61
-
62
- it('should render more apps when provided', () => {
63
- const { getByText } = render(
64
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
65
- );
66
-
67
- expect(getByText('More Apps')).toBeTruthy();
68
- });
69
-
70
- it('should not render developer when not provided', () => {
71
- const appInfoWithoutDeveloper: AppInfo = {
72
- name: 'Test App',
73
- version: '1.0.0',
74
- };
75
-
76
- const { queryByText } = render(
77
- <AboutContent appInfo={appInfoWithoutDeveloper} config={mockConfig} />
78
- );
79
-
80
- expect(queryByText('Developer')).toBeFalsy();
81
- });
82
-
83
- it('should not render contact email when not provided', () => {
84
- const appInfoWithoutEmail: AppInfo = {
85
- name: 'Test App',
86
- version: '1.0.0',
87
- };
88
-
89
- const { queryByText } = render(
90
- <AboutContent appInfo={appInfoWithoutEmail} config={mockConfig} />
91
- );
92
-
93
- expect(queryByText('Contact')).toBeFalsy();
94
- });
95
-
96
- it('should not render website when not provided', () => {
97
- const appInfoWithoutWebsite: AppInfo = {
98
- name: 'Test App',
99
- version: '1.0.0',
100
- };
101
-
102
- const { queryByText } = render(
103
- <AboutContent appInfo={appInfoWithoutWebsite} config={mockConfig} />
104
- );
105
-
106
- expect(queryByText('Website')).toBeFalsy();
107
- });
108
-
109
- it('should use websiteDisplay when provided', () => {
110
- const appInfoWithDisplay: AppInfo = {
111
- name: 'Test App',
112
- version: '1.0.0',
113
- websiteUrl: 'https://example.com',
114
- websiteDisplay: 'Custom Display',
115
- };
116
-
117
- const { getByText, queryByText } = render(
118
- <AboutContent appInfo={appInfoWithDisplay} config={mockConfig} />
119
- );
120
-
121
- expect(getByText('Custom Display')).toBeTruthy();
122
- expect(queryByText('https://example.com')).toBeFalsy();
123
- });
124
-
125
- it('should use websiteUrl when websiteDisplay not provided', () => {
126
- const appInfoWithoutDisplay: AppInfo = {
127
- name: 'Test App',
128
- version: '1.0.0',
129
- websiteUrl: 'https://example.com',
130
- };
131
-
132
- const { getByText } = render(
133
- <AboutContent appInfo={appInfoWithoutDisplay} config={mockConfig} />
134
- );
135
-
136
- expect(getByText('https://example.com')).toBeTruthy();
137
- });
138
- });
139
-
140
- describe('Interactions', () => {
141
- it('should call onEmailPress when email item is pressed', () => {
142
- const { getByTestId } = render(
143
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
144
- );
145
-
146
- fireEvent.click(getByTestId('email-item'));
147
- expect(mockConfig.actions!.onEmailPress).toHaveBeenCalledTimes(1);
148
- });
149
-
150
- it('should call onWebsitePress when website item is pressed', () => {
151
- const { getByTestId } = render(
152
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
153
- );
154
-
155
- fireEvent.click(getByTestId('website-item'));
156
- expect(mockConfig.actions!.onWebsitePress).toHaveBeenCalledTimes(1);
157
- });
158
-
159
- it('should call onMoreAppsPress when more apps item is pressed', () => {
160
- const { getByTestId } = render(
161
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
162
- );
163
-
164
- fireEvent.click(getByTestId('more-apps-item'));
165
- expect(mockConfig.actions!.onMoreAppsPress).toHaveBeenCalledTimes(1);
166
- });
167
-
168
- it('should not crash when actions are not provided', () => {
169
- const configWithoutActions: AboutConfig = {
170
- appInfo: mockAppInfo,
171
- };
172
-
173
- const { getByTestId } = render(
174
- <AboutContent appInfo={mockAppInfo} config={configWithoutActions} />
175
- );
176
-
177
- expect(() => {
178
- fireEvent.click(getByTestId('email-item'));
179
- fireEvent.click(getByTestId('website-item'));
180
- }).not.toThrow();
181
- });
182
-
183
- it('should not call actions when they are undefined', () => {
184
- const configWithUndefinedActions: AboutConfig = {
185
- appInfo: mockAppInfo,
186
- actions: {
187
- onEmailPress: undefined,
188
- onWebsitePress: undefined,
189
- },
190
- };
191
-
192
- const { getByTestId } = render(
193
- <AboutContent appInfo={mockAppInfo} config={configWithUndefinedActions} />
194
- );
195
-
196
- fireEvent.click(getByTestId('email-item'));
197
- fireEvent.click(getByTestId('website-item'));
198
-
199
- // Should not throw and should not call any undefined functions
200
- expect(true).toBe(true);
201
- });
202
- });
203
-
204
- describe('Performance', () => {
205
- it('should memoize render functions', () => {
206
- const { rerender } = render(
207
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
208
- );
209
-
210
- // Re-render with same props
211
- rerender(
212
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
213
- );
214
-
215
- // Should not throw and should render correctly
216
- expect(() => {
217
- rerender(
218
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
219
- );
220
- }).not.toThrow();
221
- });
222
-
223
- it('should handle rapid prop changes', () => {
224
- const { rerender } = render(
225
- <AboutContent appInfo={mockAppInfo} config={mockConfig} />
226
- );
227
-
228
- // Rapid prop changes
229
- for (let i = 0; i < 10; i++) {
230
- const newAppInfo = { ...mockAppInfo, name: `App ${i}` };
231
- rerender(
232
- <AboutContent appInfo={newAppInfo} config={mockConfig} />
233
- );
234
- }
235
-
236
- expect(() => {
237
- rerender(
238
- <AboutContent appInfo={{ ...mockAppInfo, name: 'Final App' }} config={mockConfig} />
239
- );
240
- }).not.toThrow();
241
- });
242
- });
243
-
244
- describe('Edge Cases', () => {
245
- it('should handle empty app info', () => {
246
- const emptyAppInfo: AppInfo = {
247
- name: '',
248
- version: '1.0.0',
249
- };
250
-
251
- const { queryByText } = render(
252
- <AboutContent appInfo={emptyAppInfo} config={mockConfig} />
253
- );
254
-
255
- expect(queryByText('Developer')).toBeFalsy();
256
- expect(queryByText('Contact')).toBeFalsy();
257
- expect(queryByText('Website')).toBeFalsy();
258
- });
259
-
260
- it('should handle app info with only required fields', () => {
261
- const minimalAppInfo: AppInfo = {
262
- name: 'Minimal App',
263
- version: '1.0.0',
264
- };
265
-
266
- const { queryByText } = render(
267
- <AboutContent appInfo={minimalAppInfo} config={mockConfig} />
268
- );
269
-
270
- expect(queryByText('Developer')).toBeFalsy();
271
- expect(queryByText('Contact')).toBeFalsy();
272
- expect(queryByText('Website')).toBeFalsy();
273
- });
274
-
275
- it('should handle special characters in text', () => {
276
- const appInfoWithSpecialChars: AppInfo = {
277
- name: 'Test App',
278
- version: '1.0.0',
279
- developer: 'Developer & Co. <test>',
280
- contactEmail: 'test+special@example.com',
281
- websiteUrl: 'https://example.com/path?param=value&other=test',
282
- };
283
-
284
- const { getByText } = render(
285
- <AboutContent appInfo={appInfoWithSpecialChars} config={mockConfig} />
286
- );
287
-
288
- expect(getByText('Developer & Co. <test>')).toBeTruthy();
289
- expect(getByText('test+special@example.com')).toBeTruthy();
290
- expect(getByText('https://example.com/path?param=value&other=test')).toBeTruthy();
291
- });
292
- });
293
- });
@@ -1,201 +0,0 @@
1
- /**
2
- * Tests for AboutHeader component
3
- */
4
- import React from 'react';
5
- import { render } from '@testing-library/react';
6
- import { AboutHeader } from '../AboutHeader';
7
- import { AppInfo } from '../../../domain/entities/AppInfo';
8
-
9
- describe('AboutHeader', () => {
10
- const mockAppInfo: AppInfo = {
11
- name: 'Test App',
12
- version: '1.0.0',
13
- description: 'Test Description',
14
- developer: 'Test Developer',
15
- };
16
-
17
- beforeEach(() => {
18
- jest.clearAllMocks();
19
- });
20
-
21
- describe('Rendering', () => {
22
- it('should render correctly with required props', () => {
23
- const { getByText } = render(
24
- <AboutHeader appInfo={mockAppInfo} />
25
- );
26
-
27
- expect(getByText('Test App')).toBeTruthy();
28
- expect(getByText('Version 1.0.0')).toBeTruthy();
29
- });
30
-
31
- it('should render description when provided', () => {
32
- const { getByText } = render(
33
- <AboutHeader appInfo={mockAppInfo} />
34
- );
35
-
36
- expect(getByText('Test Description')).toBeTruthy();
37
- });
38
-
39
- it('should not render description when not provided', () => {
40
- const appInfoWithoutDescription: AppInfo = {
41
- name: 'Test App',
42
- version: '1.0.0',
43
- };
44
-
45
- const { queryByText } = render(
46
- <AboutHeader appInfo={appInfoWithoutDescription} />
47
- );
48
-
49
- expect(queryByText('Test Description')).toBeFalsy();
50
- });
51
-
52
- it('should render with all optional fields', () => {
53
- const fullAppInfo: AppInfo = {
54
- name: 'Full App',
55
- version: '2.0.0',
56
- description: 'Full Description',
57
- developer: 'Full Developer',
58
- contactEmail: 'full@example.com',
59
- websiteUrl: 'https://full.example.com',
60
- };
61
-
62
- const { getByText } = render(
63
- <AboutHeader appInfo={fullAppInfo} />
64
- );
65
-
66
- expect(getByText('Full App')).toBeTruthy();
67
- expect(getByText('Version 2.0.0')).toBeTruthy();
68
- expect(getByText('Full Description')).toBeTruthy();
69
- });
70
- });
71
-
72
- describe('Custom Styles', () => {
73
- it('should apply custom container style', () => {
74
- const customStyle = { backgroundColor: 'red' };
75
-
76
- const { getByTestId } = render(
77
- <AboutHeader appInfo={mockAppInfo} containerStyle={customStyle} testID="header" />
78
- );
79
-
80
- const header = getByTestId('header');
81
- expect(header).toBeInTheDocument();
82
- });
83
-
84
- it('should apply custom title style', () => {
85
- const customStyle = { color: 'blue' };
86
-
87
- const { getByText } = render(
88
- <AboutHeader appInfo={mockAppInfo} titleStyle={customStyle} />
89
- );
90
-
91
- const title = getByText('Test App');
92
- expect(title).toBeInTheDocument();
93
- });
94
-
95
- it('should apply custom version style', () => {
96
- const customStyle = { color: 'purple' };
97
-
98
- const { getByText } = render(
99
- <AboutHeader appInfo={mockAppInfo} versionStyle={customStyle} />
100
- );
101
-
102
- const version = getByText('Version 1.0.0');
103
- expect(version).toBeInTheDocument();
104
- });
105
-
106
- it('should apply custom description style', () => {
107
- const customStyle = { color: 'green' };
108
-
109
- const { getByText } = render(
110
- <AboutHeader appInfo={mockAppInfo} descriptionStyle={customStyle} />
111
- );
112
-
113
- const description = getByText('Test Description');
114
- expect(description).toBeInTheDocument();
115
- });
116
- });
117
-
118
- describe('Performance', () => {
119
- it('should memoize render functions', () => {
120
- const { rerender } = render(
121
- <AboutHeader appInfo={mockAppInfo} />
122
- );
123
-
124
- expect(() => {
125
- rerender(
126
- <AboutHeader appInfo={mockAppInfo} />
127
- );
128
- }).not.toThrow();
129
- });
130
-
131
- it('should handle rapid prop changes', () => {
132
- const { rerender } = render(
133
- <AboutHeader appInfo={mockAppInfo} />
134
- );
135
-
136
- for (let i = 0; i < 10; i++) {
137
- const newAppInfo = { ...mockAppInfo, name: `App ${i}` };
138
- rerender(
139
- <AboutHeader appInfo={newAppInfo} />
140
- );
141
- }
142
-
143
- expect(() => {
144
- rerender(
145
- <AboutHeader appInfo={{ ...mockAppInfo, name: 'Final App' }} />
146
- );
147
- }).not.toThrow();
148
- });
149
- });
150
-
151
- describe('Edge Cases', () => {
152
- it('should handle empty description', () => {
153
- const appInfoWithEmptyDescription: AppInfo = {
154
- name: 'Test App',
155
- version: '1.0.0',
156
- description: '',
157
- };
158
-
159
- const { getByText, container } = render(
160
- <AboutHeader appInfo={appInfoWithEmptyDescription} />
161
- );
162
-
163
- expect(getByText('Test App')).toBeTruthy();
164
- expect(getByText('Version 1.0.0')).toBeTruthy();
165
- expect(container.textContent).toContain('');
166
- });
167
-
168
- it('should handle very long text', () => {
169
- const longName = 'A'.repeat(100);
170
- const longDescription = 'B'.repeat(200);
171
-
172
- const appInfoWithLongText: AppInfo = {
173
- name: longName,
174
- version: '1.0.0',
175
- description: longDescription,
176
- };
177
-
178
- const { getByText } = render(
179
- <AboutHeader appInfo={appInfoWithLongText} />
180
- );
181
-
182
- expect(getByText(longName)).toBeTruthy();
183
- expect(getByText(longDescription)).toBeTruthy();
184
- });
185
-
186
- it('should handle special characters', () => {
187
- const appInfoWithSpecialChars: AppInfo = {
188
- name: 'Test & App <script>',
189
- version: '1.0.0',
190
- description: 'Description with émojis 🎉 and ñ',
191
- };
192
-
193
- const { getByText } = render(
194
- <AboutHeader appInfo={appInfoWithSpecialChars} />
195
- );
196
-
197
- expect(getByText('Test & App <script>')).toBeTruthy();
198
- expect(getByText('Description with émojis 🎉 and ñ')).toBeTruthy();
199
- });
200
- });
201
- });