@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.
- package/package.json +6 -61
- package/src/domains/feedback/domain/entities/FeedbackEntity.ts +8 -8
- package/src/domains/gamification/components/AchievementCard.tsx +142 -0
- package/src/domains/gamification/components/AchievementItem.tsx +182 -0
- package/src/domains/gamification/components/AchievementToast.tsx +122 -0
- package/src/domains/gamification/components/GamificationScreen/AchievementsList.tsx +84 -0
- package/src/domains/gamification/components/GamificationScreen/Header.tsx +29 -0
- package/src/domains/gamification/components/GamificationScreen/StatsGrid.tsx +51 -0
- package/src/domains/gamification/components/GamificationScreen/index.tsx +111 -0
- package/src/domains/gamification/components/GamificationScreen/styles.ts +43 -0
- package/src/domains/gamification/components/GamificationScreen/types.ts +77 -0
- package/src/domains/gamification/components/GamificationScreenWrapper.tsx +4 -4
- package/src/domains/gamification/components/GamificationSettingsItem.tsx +1 -1
- package/src/domains/gamification/components/LevelProgress.tsx +129 -0
- package/src/domains/gamification/components/PointsBadge.tsx +60 -0
- package/src/domains/gamification/components/StatsCard.tsx +89 -0
- package/src/domains/gamification/components/StreakDisplay.tsx +119 -0
- package/src/domains/gamification/components/index.ts +13 -0
- package/src/domains/gamification/examples/gamification.config.example.ts +1 -1
- package/src/domains/gamification/hooks/useGamification.ts +91 -0
- package/src/domains/gamification/index.ts +46 -19
- package/src/domains/gamification/store/gamificationStore.ts +162 -0
- package/src/domains/gamification/types/index.ts +95 -23
- package/src/domains/gamification/types/settings.ts +28 -0
- package/src/domains/gamification/utils/calculations.ts +85 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -51
- package/.github/ISSUE_TEMPLATE/documentation.md +0 -52
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -63
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -84
- package/AI_AGENT_GUIDELINES.md +0 -367
- package/ARCHITECTURE.md +0 -246
- package/CHANGELOG.md +0 -67
- package/CODE_OF_CONDUCT.md +0 -75
- package/CONTRIBUTING.md +0 -107
- package/DOCUMENTATION_MIGRATION.md +0 -319
- package/DOCUMENTATION_TEMPLATE.md +0 -155
- package/SECURITY.md +0 -98
- package/SETTINGS_SCREEN_GUIDE.md +0 -185
- package/TESTING.md +0 -358
- package/src/__tests__/integration.test.tsx +0 -371
- package/src/__tests__/performance.test.tsx +0 -369
- package/src/__tests__/setup.test.tsx +0 -20
- package/src/__tests__/setup.ts +0 -154
- package/src/domains/about/__tests__/integration.test.tsx +0 -328
- package/src/domains/about/__tests__/types.d.ts +0 -5
- package/src/domains/about/domain/entities/__tests__/AppInfo.test.ts +0 -93
- package/src/domains/about/infrastructure/repositories/__tests__/AboutRepository.test.ts +0 -153
- package/src/domains/about/presentation/components/__tests__/AboutContent.simple.test.tsx +0 -178
- package/src/domains/about/presentation/components/__tests__/AboutContent.test.tsx +0 -293
- package/src/domains/about/presentation/components/__tests__/AboutHeader.test.tsx +0 -201
- package/src/domains/about/presentation/components/__tests__/AboutSettingItem.test.tsx +0 -71
- package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.simple.test.tsx +0 -229
- package/src/domains/about/presentation/hooks/__tests__/useAboutInfo.test.tsx +0 -240
- package/src/domains/about/presentation/screens/__tests__/AboutScreen.simple.test.tsx +0 -199
- package/src/domains/about/presentation/screens/__tests__/AboutScreen.test.tsx +0 -366
- package/src/domains/about/utils/__tests__/index.test.ts +0 -408
- package/src/domains/appearance/__tests__/components/AppearanceScreen.test.tsx +0 -195
- package/src/domains/appearance/__tests__/hooks/index.test.tsx +0 -232
- package/src/domains/appearance/__tests__/integration/index.test.tsx +0 -207
- package/src/domains/appearance/__tests__/services/appearanceService.test.ts +0 -299
- package/src/domains/appearance/__tests__/setup.ts +0 -88
- package/src/domains/appearance/__tests__/stores/appearanceStore.test.tsx +0 -175
- package/src/domains/cloud-sync/presentation/components/__tests__/CloudSyncSetting.test.tsx +0 -78
- package/src/domains/legal/__tests__/ContentValidationService.test.ts +0 -195
- package/src/domains/legal/__tests__/StyleCacheService.test.ts +0 -110
- package/src/domains/legal/__tests__/UrlHandlerService.test.ts +0 -71
- package/src/domains/legal/__tests__/setup.ts +0 -82
- package/src/presentation/components/__tests__/SettingsErrorBoundary.test.tsx +0 -186
- package/src/presentation/screens/__tests__/SettingsScreen.test.tsx +0 -322
- 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
|
-
});
|