@osimatic/helpers-js 1.4.24 → 1.4.26
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/.claude/settings.local.json +2 -1
- package/chartjs.js +1 -1
- package/date_time.js +25 -16
- package/draw.js +3 -2
- package/duration.js +176 -130
- package/event_bus.js +2 -2
- package/file.js +20 -5
- package/form_helper.js +1 -1
- package/google_charts.js +2 -1
- package/http_client.js +2 -0
- package/jwt.js +18 -6
- package/location.js +5 -1
- package/media.js +7 -7
- package/multi_files_input.js +3 -1
- package/number.js +2 -3
- package/package.json +4 -2
- package/paging.js +2 -2
- package/social_network.js +5 -0
- package/string.js +11 -2
- package/tests/__mocks__/socket.io-client.js +13 -0
- package/tests/chartjs.test.js +273 -0
- package/tests/count_down.test.js +580 -0
- package/tests/date_time/DatePeriod.test.js +179 -0
- package/tests/date_time/DateTime.test.js +492 -0
- package/tests/date_time/SqlDate.test.js +205 -0
- package/tests/date_time/SqlDateTime.test.js +326 -0
- package/tests/date_time/SqlTime.test.js +162 -0
- package/tests/date_time/TimestampUnix.test.js +262 -0
- package/tests/details_sub_array.test.js +367 -0
- package/tests/draw.test.js +271 -0
- package/tests/duration.test.js +365 -0
- package/tests/event_bus.test.js +268 -0
- package/tests/file.test.js +568 -0
- package/tests/flash_message.test.js +297 -0
- package/tests/form_date.test.js +1559 -0
- package/tests/form_helper.test.js +1065 -0
- package/tests/google_charts.test.js +768 -0
- package/tests/google_maps.test.js +655 -0
- package/tests/google_recaptcha.test.js +441 -0
- package/tests/http_client.test.js +570 -0
- package/tests/import_from_csv.test.js +797 -0
- package/tests/jwt.test.js +804 -0
- package/tests/list_box.test.js +255 -0
- package/tests/location.test.js +86 -0
- package/tests/media.test.js +473 -0
- package/tests/multi_files_input.test.js +1015 -0
- package/tests/multiple_action_in_table.test.js +477 -0
- package/tests/network.test.js +489 -0
- package/tests/number.test.js +448 -0
- package/tests/open_street_map.test.js +388 -0
- package/tests/paging.test.js +646 -0
- package/tests/select_all.test.js +360 -0
- package/tests/shopping_cart.test.js +355 -0
- package/tests/social_network.test.js +333 -0
- package/tests/sortable_list.test.js +602 -0
- package/tests/string.test.js +489 -0
- package/tests/user.test.js +204 -0
- package/tests/util.test.js +99 -0
- package/tests/visitor.test.js +508 -0
- package/tests/web_rtc.test.js +458 -0
- package/tests/web_socket.test.js +538 -0
- package/visitor.js +2 -2
- package/tmpclaude-0fa4-cwd +0 -1
- package/tmpclaude-104f-cwd +0 -1
- package/tmpclaude-1468-cwd +0 -1
- package/tmpclaude-324b-cwd +0 -1
- package/tmpclaude-35d3-cwd +0 -1
- package/tmpclaude-4aa8-cwd +0 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const { sleep, refresh } = require('../util');
|
|
2
|
+
|
|
3
|
+
describe('Util', () => {
|
|
4
|
+
describe('sleep', () => {
|
|
5
|
+
test('should block for approximately the specified time', () => {
|
|
6
|
+
const startTime = Date.now();
|
|
7
|
+
sleep(100);
|
|
8
|
+
const endTime = Date.now();
|
|
9
|
+
const elapsed = endTime - startTime;
|
|
10
|
+
|
|
11
|
+
// Allow some tolerance for timing
|
|
12
|
+
expect(elapsed).toBeGreaterThanOrEqual(100);
|
|
13
|
+
expect(elapsed).toBeLessThan(200);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('should block for 0 milliseconds', () => {
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
sleep(0);
|
|
19
|
+
const endTime = Date.now();
|
|
20
|
+
const elapsed = endTime - startTime;
|
|
21
|
+
|
|
22
|
+
// Should complete very quickly
|
|
23
|
+
expect(elapsed).toBeLessThan(50);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('should handle small delays', () => {
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
sleep(10);
|
|
29
|
+
const endTime = Date.now();
|
|
30
|
+
const elapsed = endTime - startTime;
|
|
31
|
+
|
|
32
|
+
expect(elapsed).toBeGreaterThanOrEqual(10);
|
|
33
|
+
expect(elapsed).toBeLessThan(100);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('should handle negative values as immediate return', () => {
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
sleep(-100);
|
|
39
|
+
const endTime = Date.now();
|
|
40
|
+
const elapsed = endTime - startTime;
|
|
41
|
+
|
|
42
|
+
// Should complete immediately as condition is never met
|
|
43
|
+
expect(elapsed).toBeLessThan(50);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('should not throw error', () => {
|
|
47
|
+
expect(() => sleep(50)).not.toThrow();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('should be a function', () => {
|
|
51
|
+
expect(typeof sleep).toBe('function');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('refresh', () => {
|
|
56
|
+
let reloadMock;
|
|
57
|
+
let originalWindow;
|
|
58
|
+
|
|
59
|
+
beforeEach(() => {
|
|
60
|
+
// Save original window
|
|
61
|
+
originalWindow = global.window;
|
|
62
|
+
|
|
63
|
+
// Mock window.location.reload
|
|
64
|
+
reloadMock = jest.fn();
|
|
65
|
+
global.window = {
|
|
66
|
+
location: {
|
|
67
|
+
reload: reloadMock
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
// Restore original window
|
|
74
|
+
global.window = originalWindow;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('should call window.location.reload with true', () => {
|
|
78
|
+
refresh();
|
|
79
|
+
|
|
80
|
+
expect(reloadMock).toHaveBeenCalledTimes(1);
|
|
81
|
+
expect(reloadMock).toHaveBeenCalledWith(true);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('should not throw error', () => {
|
|
85
|
+
expect(() => refresh()).not.toThrow();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('should be a function', () => {
|
|
89
|
+
expect(typeof refresh).toBe('function');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('should force reload (not use cache)', () => {
|
|
93
|
+
refresh();
|
|
94
|
+
|
|
95
|
+
// Verify that reload was called with true (force reload)
|
|
96
|
+
expect(reloadMock).toHaveBeenCalledWith(true);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
const { Browser, UserAgent } = require('../visitor');
|
|
2
|
+
|
|
3
|
+
describe('Browser', () => {
|
|
4
|
+
describe('isOpera', () => {
|
|
5
|
+
test('should return true when window.opr exists', () => {
|
|
6
|
+
global.window = { opr: { addons: true } };
|
|
7
|
+
global.opr = { addons: true };
|
|
8
|
+
global.navigator = { userAgent: '' };
|
|
9
|
+
|
|
10
|
+
expect(Browser.isOpera()).toBe(true);
|
|
11
|
+
|
|
12
|
+
delete global.window;
|
|
13
|
+
delete global.opr;
|
|
14
|
+
delete global.navigator;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('should return true when window.opera exists', () => {
|
|
18
|
+
global.window = { opera: {} };
|
|
19
|
+
global.navigator = { userAgent: '' };
|
|
20
|
+
|
|
21
|
+
expect(Browser.isOpera()).toBe(true);
|
|
22
|
+
|
|
23
|
+
delete global.window;
|
|
24
|
+
delete global.navigator;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('should return true when userAgent contains OPR/', () => {
|
|
28
|
+
global.window = {};
|
|
29
|
+
global.navigator = { userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 OPR/77.0.4054.277' };
|
|
30
|
+
|
|
31
|
+
expect(Browser.isOpera()).toBe(true);
|
|
32
|
+
|
|
33
|
+
delete global.window;
|
|
34
|
+
delete global.navigator;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('should return false when not Opera', () => {
|
|
38
|
+
global.window = {};
|
|
39
|
+
global.navigator = { userAgent: 'Mozilla/5.0' };
|
|
40
|
+
|
|
41
|
+
expect(Browser.isOpera()).toBe(false);
|
|
42
|
+
|
|
43
|
+
delete global.window;
|
|
44
|
+
delete global.navigator;
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe('isFirefox', () => {
|
|
49
|
+
test('should return true when InstallTrigger is defined', () => {
|
|
50
|
+
global.InstallTrigger = {};
|
|
51
|
+
|
|
52
|
+
expect(Browser.isFirefox()).toBe(true);
|
|
53
|
+
|
|
54
|
+
delete global.InstallTrigger;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('should return false when InstallTrigger is undefined', () => {
|
|
58
|
+
expect(Browser.isFirefox()).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('isSafari', () => {
|
|
63
|
+
test('should return true when HTMLElement toString contains Constructor', () => {
|
|
64
|
+
// Mock Object.prototype.toString pour simuler Safari
|
|
65
|
+
const originalToString = Object.prototype.toString;
|
|
66
|
+
Object.prototype.toString = function() {
|
|
67
|
+
if (this === global.window.HTMLElement) {
|
|
68
|
+
return '[object HTMLElementConstructor]';
|
|
69
|
+
}
|
|
70
|
+
return originalToString.call(this);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
global.window = { HTMLElement: function() {} };
|
|
74
|
+
|
|
75
|
+
expect(Browser.isSafari()).toBe(true);
|
|
76
|
+
|
|
77
|
+
// Restore
|
|
78
|
+
Object.prototype.toString = originalToString;
|
|
79
|
+
delete global.window;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('should return false when HTMLElement toString does not contain Constructor', () => {
|
|
83
|
+
const originalToString = Object.prototype.toString;
|
|
84
|
+
Object.prototype.toString = function() {
|
|
85
|
+
if (this === global.window.HTMLElement) {
|
|
86
|
+
return '[object Function]';
|
|
87
|
+
}
|
|
88
|
+
return originalToString.call(this);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
global.window = { HTMLElement: function() {} };
|
|
92
|
+
|
|
93
|
+
expect(Browser.isSafari()).toBe(false);
|
|
94
|
+
|
|
95
|
+
Object.prototype.toString = originalToString;
|
|
96
|
+
delete global.window;
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('isChrome', () => {
|
|
101
|
+
test('should return true when window.chrome.webstore exists', () => {
|
|
102
|
+
global.window = {
|
|
103
|
+
chrome: {
|
|
104
|
+
webstore: {}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
expect(Browser.isChrome()).toBe(true);
|
|
109
|
+
|
|
110
|
+
delete global.window;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('should return false when window.chrome is undefined', () => {
|
|
114
|
+
global.window = {};
|
|
115
|
+
|
|
116
|
+
expect(Browser.isChrome()).toBe(false);
|
|
117
|
+
|
|
118
|
+
delete global.window;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('should return false when window.chrome.webstore is undefined', () => {
|
|
122
|
+
global.window = {
|
|
123
|
+
chrome: {}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
expect(Browser.isChrome()).toBe(false);
|
|
127
|
+
|
|
128
|
+
delete global.window;
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('isIE', () => {
|
|
133
|
+
test('should return true when document.documentMode exists', () => {
|
|
134
|
+
global.document = { documentMode: 11 };
|
|
135
|
+
|
|
136
|
+
expect(Browser.isIE()).toBe(true);
|
|
137
|
+
|
|
138
|
+
delete global.document;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('should return false when document.documentMode is undefined', () => {
|
|
142
|
+
global.document = {};
|
|
143
|
+
|
|
144
|
+
expect(Browser.isIE()).toBe(false);
|
|
145
|
+
|
|
146
|
+
delete global.document;
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('isEdge', () => {
|
|
151
|
+
test('should return true when window.StyleMedia exists and not IE', () => {
|
|
152
|
+
global.document = {};
|
|
153
|
+
global.window = { StyleMedia: {} };
|
|
154
|
+
|
|
155
|
+
expect(Browser.isEdge()).toBe(true);
|
|
156
|
+
|
|
157
|
+
delete global.document;
|
|
158
|
+
delete global.window;
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('should return false when window.StyleMedia is undefined', () => {
|
|
162
|
+
global.document = {};
|
|
163
|
+
global.window = {};
|
|
164
|
+
|
|
165
|
+
expect(Browser.isEdge()).toBe(false);
|
|
166
|
+
|
|
167
|
+
delete global.document;
|
|
168
|
+
delete global.window;
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
describe('UserAgent', () => {
|
|
174
|
+
describe('getInfosDisplay', () => {
|
|
175
|
+
test('should join all components with default separator', () => {
|
|
176
|
+
const data = {
|
|
177
|
+
os: 'Windows 10',
|
|
178
|
+
browser: 'Chrome 91',
|
|
179
|
+
device: 'Desktop'
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
expect(UserAgent.getInfosDisplay(data)).toBe('Windows 10 — Chrome 91 — Desktop');
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('should join all components with custom separator', () => {
|
|
186
|
+
const data = {
|
|
187
|
+
os: 'Windows 10',
|
|
188
|
+
browser: 'Chrome 91',
|
|
189
|
+
device: 'Desktop'
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
expect(UserAgent.getInfosDisplay(data, ' | ')).toBe('Windows 10 | Chrome 91 | Desktop');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('should skip null os', () => {
|
|
196
|
+
const data = {
|
|
197
|
+
os: null,
|
|
198
|
+
browser: 'Chrome 91',
|
|
199
|
+
device: 'Desktop'
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
expect(UserAgent.getInfosDisplay(data)).toBe('Chrome 91 — Desktop');
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('should skip null browser', () => {
|
|
206
|
+
const data = {
|
|
207
|
+
os: 'Windows 10',
|
|
208
|
+
browser: null,
|
|
209
|
+
device: 'Desktop'
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
expect(UserAgent.getInfosDisplay(data)).toBe('Windows 10 — Desktop');
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
test('should skip null device', () => {
|
|
216
|
+
const data = {
|
|
217
|
+
os: 'Windows 10',
|
|
218
|
+
browser: 'Chrome 91',
|
|
219
|
+
device: null
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
expect(UserAgent.getInfosDisplay(data)).toBe('Windows 10 — Chrome 91');
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
test('should return empty string when all null', () => {
|
|
226
|
+
const data = {
|
|
227
|
+
os: null,
|
|
228
|
+
browser: null,
|
|
229
|
+
device: null
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
expect(UserAgent.getInfosDisplay(data)).toBe('');
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test('should handle only one component', () => {
|
|
236
|
+
const data = {
|
|
237
|
+
os: 'Windows 10',
|
|
238
|
+
browser: null,
|
|
239
|
+
device: null
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
expect(UserAgent.getInfosDisplay(data)).toBe('Windows 10');
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
describe('getData', () => {
|
|
247
|
+
test('should return null when UAParser is undefined', () => {
|
|
248
|
+
expect(UserAgent.getData('some user agent')).toBeNull();
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test('should parse user agent when UAParser is defined', () => {
|
|
252
|
+
global.UAParser = jest.fn(() => ({
|
|
253
|
+
os: { name: 'Windows', version: '10' },
|
|
254
|
+
browser: { name: 'Chrome', major: '91' },
|
|
255
|
+
device: { type: 'desktop', vendor: 'Dell', model: 'Inspiron' }
|
|
256
|
+
}));
|
|
257
|
+
|
|
258
|
+
const result = UserAgent.getData('Mozilla/5.0...');
|
|
259
|
+
|
|
260
|
+
expect(result).toEqual({
|
|
261
|
+
os: 'Windows 10',
|
|
262
|
+
browser: 'Chrome 91',
|
|
263
|
+
device: 'desktop Dell Inspiron'
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
delete global.UAParser;
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test('should handle os without version', () => {
|
|
270
|
+
global.UAParser = jest.fn(() => ({
|
|
271
|
+
os: { name: 'Linux' },
|
|
272
|
+
browser: { name: 'Firefox', major: '89' },
|
|
273
|
+
device: {}
|
|
274
|
+
}));
|
|
275
|
+
|
|
276
|
+
const result = UserAgent.getData('Mozilla/5.0...');
|
|
277
|
+
|
|
278
|
+
expect(result.os).toBe('Linux');
|
|
279
|
+
|
|
280
|
+
delete global.UAParser;
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test('should handle browser with version instead of major', () => {
|
|
284
|
+
global.UAParser = jest.fn(() => ({
|
|
285
|
+
os: { name: 'Windows', version: '10' },
|
|
286
|
+
browser: { name: 'Safari', version: '14.1.2' },
|
|
287
|
+
device: {}
|
|
288
|
+
}));
|
|
289
|
+
|
|
290
|
+
const result = UserAgent.getData('Mozilla/5.0...');
|
|
291
|
+
|
|
292
|
+
expect(result.browser).toBe('Safari 14.1.2');
|
|
293
|
+
|
|
294
|
+
delete global.UAParser;
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test('should handle device with only type', () => {
|
|
298
|
+
global.UAParser = jest.fn(() => ({
|
|
299
|
+
os: { name: 'iOS', version: '14' },
|
|
300
|
+
browser: { name: 'Safari', major: '14' },
|
|
301
|
+
device: { type: 'mobile' }
|
|
302
|
+
}));
|
|
303
|
+
|
|
304
|
+
const result = UserAgent.getData('Mozilla/5.0...');
|
|
305
|
+
|
|
306
|
+
expect(result.device).toBe('mobile');
|
|
307
|
+
|
|
308
|
+
delete global.UAParser;
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test('should return null for empty os', () => {
|
|
312
|
+
global.UAParser = jest.fn(() => ({
|
|
313
|
+
os: { name: '' },
|
|
314
|
+
browser: { name: 'Chrome', major: '91' },
|
|
315
|
+
device: {}
|
|
316
|
+
}));
|
|
317
|
+
|
|
318
|
+
const result = UserAgent.getData('Mozilla/5.0...');
|
|
319
|
+
|
|
320
|
+
expect(result.os).toBeNull();
|
|
321
|
+
|
|
322
|
+
delete global.UAParser;
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test('should return null for empty browser', () => {
|
|
326
|
+
global.UAParser = jest.fn(() => ({
|
|
327
|
+
os: { name: 'Windows', version: '10' },
|
|
328
|
+
browser: { name: '' },
|
|
329
|
+
device: {}
|
|
330
|
+
}));
|
|
331
|
+
|
|
332
|
+
const result = UserAgent.getData('Mozilla/5.0...');
|
|
333
|
+
|
|
334
|
+
expect(result.browser).toBeNull();
|
|
335
|
+
|
|
336
|
+
delete global.UAParser;
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test('should return null when all undefined', () => {
|
|
340
|
+
global.UAParser = jest.fn(() => ({
|
|
341
|
+
os: {},
|
|
342
|
+
browser: {},
|
|
343
|
+
device: {}
|
|
344
|
+
}));
|
|
345
|
+
|
|
346
|
+
const result = UserAgent.getData('Mozilla/5.0...');
|
|
347
|
+
|
|
348
|
+
expect(result).toEqual({
|
|
349
|
+
os: null,
|
|
350
|
+
browser: null,
|
|
351
|
+
device: null
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
delete global.UAParser;
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
describe('getOsIcon', () => {
|
|
359
|
+
test('should return Windows icon', () => {
|
|
360
|
+
expect(UserAgent.getOsIcon('Windows')).toBe('<i class="fab fa-windows"></i>');
|
|
361
|
+
expect(UserAgent.getOsIcon('WINDOWS')).toBe('<i class="fab fa-windows"></i>');
|
|
362
|
+
expect(UserAgent.getOsIcon('windows')).toBe('<i class="fab fa-windows"></i>');
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test('should return Linux icon', () => {
|
|
366
|
+
expect(UserAgent.getOsIcon('Linux')).toBe('<i class="fab fa-linux"></i>');
|
|
367
|
+
expect(UserAgent.getOsIcon('LINUX')).toBe('<i class="fab fa-linux"></i>');
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
test('should return Apple icon for macOS', () => {
|
|
371
|
+
expect(UserAgent.getOsIcon('macOS')).toBe('<i class="fab fa-apple"></i>');
|
|
372
|
+
expect(UserAgent.getOsIcon('MACOS')).toBe('<i class="fab fa-apple"></i>');
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
test('should return Apple icon for iOS', () => {
|
|
376
|
+
expect(UserAgent.getOsIcon('iOS')).toBe('<i class="fab fa-apple"></i>');
|
|
377
|
+
expect(UserAgent.getOsIcon('IOS')).toBe('<i class="fab fa-apple"></i>');
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
test('should return Android icon', () => {
|
|
381
|
+
expect(UserAgent.getOsIcon('Android')).toBe('<i class="fab fa-android"></i>');
|
|
382
|
+
expect(UserAgent.getOsIcon('ANDROID')).toBe('<i class="fab fa-android"></i>');
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
test('should return empty string for unknown OS', () => {
|
|
386
|
+
expect(UserAgent.getOsIcon('Unknown')).toBe('');
|
|
387
|
+
expect(UserAgent.getOsIcon('FreeBSD')).toBe('');
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
describe('getOsDisplay', () => {
|
|
392
|
+
test('should return icon and name for Windows', () => {
|
|
393
|
+
const result = UserAgent.getOsDisplay('Windows');
|
|
394
|
+
expect(result).toContain('<i class="fab fa-windows"></i>');
|
|
395
|
+
expect(result).toContain('Windows');
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test('should return only name when no icon', () => {
|
|
399
|
+
const result = UserAgent.getOsDisplay('Unknown');
|
|
400
|
+
expect(result).toBe('Unknown');
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
describe('getBrowserIcon', () => {
|
|
405
|
+
test('should return Chrome icon', () => {
|
|
406
|
+
expect(UserAgent.getBrowserIcon('Chrome')).toBe('<i class="fab fa-chrome"></i>');
|
|
407
|
+
expect(UserAgent.getBrowserIcon('CHROME')).toBe('<i class="fab fa-chrome"></i>');
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test('should return Firefox icon', () => {
|
|
411
|
+
expect(UserAgent.getBrowserIcon('Firefox')).toBe('<i class="fab fa-firefox"></i>');
|
|
412
|
+
expect(UserAgent.getBrowserIcon('FIREFOX')).toBe('<i class="fab fa-firefox"></i>');
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test('should return Edge icon', () => {
|
|
416
|
+
expect(UserAgent.getBrowserIcon('Edge')).toBe('<i class="fab fa-edge"></i>');
|
|
417
|
+
expect(UserAgent.getBrowserIcon('EDGE')).toBe('<i class="fab fa-edge"></i>');
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
test('should return Safari icon', () => {
|
|
421
|
+
expect(UserAgent.getBrowserIcon('Safari')).toBe('<i class="fab fa-safari"></i>');
|
|
422
|
+
expect(UserAgent.getBrowserIcon('SAFARI')).toBe('<i class="fab fa-safari"></i>');
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test('should return Opera icon', () => {
|
|
426
|
+
expect(UserAgent.getBrowserIcon('Opera')).toBe('<i class="fab fa-opera"></i>');
|
|
427
|
+
expect(UserAgent.getBrowserIcon('OPERA')).toBe('<i class="fab fa-opera"></i>');
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
test('should return empty string for unknown browser', () => {
|
|
431
|
+
expect(UserAgent.getBrowserIcon('Unknown')).toBe('');
|
|
432
|
+
expect(UserAgent.getBrowserIcon('Brave')).toBe('');
|
|
433
|
+
});
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
describe('getBrowserDisplay', () => {
|
|
437
|
+
test('should return icon and name for Chrome', () => {
|
|
438
|
+
const result = UserAgent.getBrowserDisplay('Chrome');
|
|
439
|
+
expect(result).toContain('<i class="fab fa-chrome"></i>');
|
|
440
|
+
expect(result).toContain('Chrome');
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
test('should return only name when no icon', () => {
|
|
444
|
+
const result = UserAgent.getBrowserDisplay('Unknown');
|
|
445
|
+
expect(result).toBe('Unknown');
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
describe('getDeviceDisplay', () => {
|
|
450
|
+
test('should return desktop icon for desktop type', () => {
|
|
451
|
+
const device = { type: 'desktop' };
|
|
452
|
+
const result = UserAgent.getDeviceDisplay(device);
|
|
453
|
+
|
|
454
|
+
expect(result).toBe('<i class="fas fa-desktop"></i> Ordinateur');
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test('should return mobile icon with manufacturer and model', () => {
|
|
458
|
+
const device = {
|
|
459
|
+
type: 'mobile',
|
|
460
|
+
is_mobile: true,
|
|
461
|
+
manufacturer: 'Apple',
|
|
462
|
+
model: 'iPhone 12'
|
|
463
|
+
};
|
|
464
|
+
const result = UserAgent.getDeviceDisplay(device);
|
|
465
|
+
|
|
466
|
+
expect(result).toContain('<i class="fas fa-mobile-alt"></i>');
|
|
467
|
+
expect(result).toContain('Apple');
|
|
468
|
+
expect(result).toContain('iPhone 12');
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
test('should show "Mobile" when no manufacturer and model', () => {
|
|
472
|
+
const device = {
|
|
473
|
+
type: 'mobile',
|
|
474
|
+
is_mobile: true,
|
|
475
|
+
manufacturer: null,
|
|
476
|
+
model: null
|
|
477
|
+
};
|
|
478
|
+
const result = UserAgent.getDeviceDisplay(device);
|
|
479
|
+
|
|
480
|
+
expect(result).toContain('Mobile');
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
test('should handle tablet without is_mobile flag', () => {
|
|
484
|
+
const device = {
|
|
485
|
+
type: 'tablet',
|
|
486
|
+
is_mobile: false,
|
|
487
|
+
manufacturer: 'Samsung',
|
|
488
|
+
model: 'Galaxy Tab'
|
|
489
|
+
};
|
|
490
|
+
const result = UserAgent.getDeviceDisplay(device);
|
|
491
|
+
|
|
492
|
+
expect(result).toContain('Samsung');
|
|
493
|
+
expect(result).toContain('Galaxy Tab');
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
test('should handle device with only manufacturer', () => {
|
|
497
|
+
const device = {
|
|
498
|
+
type: 'mobile',
|
|
499
|
+
is_mobile: true,
|
|
500
|
+
manufacturer: 'Google',
|
|
501
|
+
model: undefined
|
|
502
|
+
};
|
|
503
|
+
const result = UserAgent.getDeviceDisplay(device);
|
|
504
|
+
|
|
505
|
+
expect(result).toContain('Google');
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
});
|