]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/UtilsTest.php
Don't write History for link import
[github/shaarli/Shaarli.git] / tests / UtilsTest.php
CommitLineData
ca74886f
V
1<?php
2/**
3 * Utilities' tests
4 */
5
6require_once 'application/Utils.php';
84315a3b 7require_once 'application/Languages.php';
68bc2135
V
8require_once 'tests/utils/ReferenceSessionIdHashes.php';
9
10// Initialize reference data before PHPUnit starts a session
11ReferenceSessionIdHashes::genAllHashes();
12
ca74886f
V
13
14/**
15 * Unitary tests for Shaarli utilities
16 */
17class UtilsTest extends PHPUnit_Framework_TestCase
18{
68bc2135
V
19 // Session ID hashes
20 protected static $sidHashes = null;
21
1abe6555
V
22 // Log file
23 protected static $testLogFile = 'tests.log';
24
25 // Expected log date format
478ce8af 26 protected static $dateFormat = 'Y/m/d H:i:s';
52b50310
A
27
28 /**
29 * @var string Save the current timezone.
30 */
31 protected static $defaultTimeZone;
32
1abe6555 33
68bc2135
V
34 /**
35 * Assign reference data
36 */
37 public static function setUpBeforeClass()
38 {
39 self::$sidHashes = ReferenceSessionIdHashes::getHashes();
52b50310
A
40 self::$defaultTimeZone = date_default_timezone_get();
41 // Timezone without DST for test consistency
42 date_default_timezone_set('Africa/Nairobi');
43 }
44
45 /**
46 * Reset the timezone
47 */
48 public static function tearDownAfterClass()
49 {
50 date_default_timezone_set(self::$defaultTimeZone);
68bc2135
V
51 }
52
1abe6555
V
53 /**
54 * Resets test data before each test
55 */
56 protected function setUp()
57 {
58 if (file_exists(self::$testLogFile)) {
59 unlink(self::$testLogFile);
60 }
61 }
62
63 /**
64 * Returns a list of the elements from the last logged entry
65 *
66 * @return list (date, ip address, message)
67 */
68 protected function getLastLogEntry()
69 {
70 $logFile = file(self::$testLogFile);
aa7f7b3e 71 return explode(' - ', trim(array_pop($logFile), PHP_EOL));
1abe6555
V
72 }
73
74 /**
75 * Log a message to a file - IPv4 client address
76 */
77 public function testLogmIp4()
78 {
79 $logMessage = 'IPv4 client connected';
80 logm(self::$testLogFile, '127.0.0.1', $logMessage);
81 list($date, $ip, $message) = $this->getLastLogEntry();
82
83 $this->assertInstanceOf(
84 'DateTime',
85 DateTime::createFromFormat(self::$dateFormat, $date)
86 );
87 $this->assertTrue(
88 filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false
89 );
90 $this->assertEquals($logMessage, $message);
91 }
92
93 /**
94 * Log a message to a file - IPv6 client address
95 */
96 public function testLogmIp6()
97 {
98 $logMessage = 'IPv6 client connected';
99 logm(self::$testLogFile, '2001:db8::ff00:42:8329', $logMessage);
100 list($date, $ip, $message) = $this->getLastLogEntry();
101
102 $this->assertInstanceOf(
103 'DateTime',
104 DateTime::createFromFormat(self::$dateFormat, $date)
105 );
106 $this->assertTrue(
107 filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false
108 );
109 $this->assertEquals($logMessage, $message);
110 }
111
ca74886f
V
112 /**
113 * Represent a link by its hash
114 */
115 public function testSmallHash()
116 {
117 $this->assertEquals('CyAAJw', smallHash('http://test.io'));
118 $this->assertEquals(6, strlen(smallHash('https://github.com')));
119 }
120
121 /**
122 * Look for a substring at the beginning of a string
123 */
124 public function testStartsWithCaseInsensitive()
125 {
126 $this->assertTrue(startsWith('Lorem ipsum', 'lorem', false));
127 $this->assertTrue(startsWith('Lorem ipsum', 'LoReM i', false));
128 }
129
130 /**
131 * Look for a substring at the beginning of a string (case-sensitive)
132 */
133 public function testStartsWithCaseSensitive()
134 {
135 $this->assertTrue(startsWith('Lorem ipsum', 'Lorem', true));
136 $this->assertFalse(startsWith('Lorem ipsum', 'lorem', true));
137 $this->assertFalse(startsWith('Lorem ipsum', 'LoReM i', true));
138 }
139
140 /**
141 * Look for a substring at the beginning of a string (Unicode)
142 */
143 public function testStartsWithSpecialChars()
144 {
145 $this->assertTrue(startsWith('å!ùµ', 'å!', false));
146 $this->assertTrue(startsWith('µ$åù', 'µ$', true));
147 }
148
149 /**
150 * Look for a substring at the end of a string
151 */
152 public function testEndsWithCaseInsensitive()
153 {
154 $this->assertTrue(endsWith('Lorem ipsum', 'ipsum', false));
155 $this->assertTrue(endsWith('Lorem ipsum', 'm IpsUM', false));
156 }
157
158 /**
159 * Look for a substring at the end of a string (case-sensitive)
160 */
161 public function testEndsWithCaseSensitive()
162 {
163 $this->assertTrue(endsWith('lorem Ipsum', 'Ipsum', true));
164 $this->assertFalse(endsWith('lorem Ipsum', 'ipsum', true));
165 $this->assertFalse(endsWith('lorem Ipsum', 'M IPsuM', true));
166 }
167
168 /**
169 * Look for a substring at the end of a string (Unicode)
170 */
171 public function testEndsWithSpecialChars()
172 {
173 $this->assertTrue(endsWith('å!ùµ', 'ùµ', false));
174 $this->assertTrue(endsWith('µ$åù', 'åù', true));
175 }
9186ab95
V
176
177 /**
178 * Check valid date strings, according to a DateTime format
179 */
180 public function testCheckValidDateFormat()
181 {
182 $this->assertTrue(checkDateFormat('Ymd', '20150627'));
183 $this->assertTrue(checkDateFormat('Y-m-d', '2015-06-27'));
184 }
185
186 /**
187 * Check erroneous date strings, according to a DateTime format
188 */
189 public function testCheckInvalidDateFormat()
190 {
191 $this->assertFalse(checkDateFormat('Ymd', '2015'));
192 $this->assertFalse(checkDateFormat('Y-m-d', '2015-06'));
193 $this->assertFalse(checkDateFormat('Ymd', 'DeLorean'));
194 }
775803a0
A
195
196 /**
197 * Test generate location with valid data.
198 */
199 public function testGenerateLocation() {
200 $ref = 'http://localhost/?test';
201 $this->assertEquals($ref, generateLocation($ref, 'localhost'));
202 $ref = 'http://localhost:8080/?test';
203 $this->assertEquals($ref, generateLocation($ref, 'localhost:8080'));
d01c2342
A
204 $ref = '?localreferer#hash';
205 $this->assertEquals($ref, generateLocation($ref, 'localhost:8080'));
775803a0
A
206 }
207
208 /**
209 * Test generate location - anti loop.
210 */
211 public function testGenerateLocationLoop() {
212 $ref = 'http://localhost/?test';
d1e2f8e5 213 $this->assertEquals('?', generateLocation($ref, 'localhost', array('test')));
775803a0
A
214 }
215
216 /**
217 * Test generate location - from other domain.
218 */
219 public function testGenerateLocationOut() {
220 $ref = 'http://somewebsite.com/?test';
221 $this->assertEquals('?', generateLocation($ref, 'localhost'));
222 }
d1e2f8e5 223
06b6660a 224 /**
68bc2135
V
225 * Test is_session_id_valid with a valid ID - TEST ALL THE HASHES!
226 *
227 * This tests extensively covers all hash algorithms / bit representations
228 */
229 public function testIsAnyHashSessionIdValid()
230 {
231 foreach (self::$sidHashes as $algo => $bpcs) {
232 foreach ($bpcs as $bpc => $hash) {
233 $this->assertTrue(is_session_id_valid($hash));
234 }
235 }
236 }
237
238 /**
239 * Test is_session_id_valid with a valid ID - SHA-1 hashes
240 */
241 public function testIsSha1SessionIdValid()
242 {
243 $this->assertTrue(is_session_id_valid(sha1('shaarli')));
244 }
245
246 /**
247 * Test is_session_id_valid with a valid ID - SHA-256 hashes
248 */
249 public function testIsSha256SessionIdValid()
250 {
251 $this->assertTrue(is_session_id_valid(hash('sha256', 'shaarli')));
252 }
253
254 /**
255 * Test is_session_id_valid with a valid ID - SHA-512 hashes
06b6660a 256 */
68bc2135 257 public function testIsSha512SessionIdValid()
06b6660a 258 {
68bc2135 259 $this->assertTrue(is_session_id_valid(hash('sha512', 'shaarli')));
06b6660a
A
260 }
261
262 /**
263 * Test is_session_id_valid with invalid IDs.
264 */
265 public function testIsSessionIdInvalid()
266 {
267 $this->assertFalse(is_session_id_valid(''));
268 $this->assertFalse(is_session_id_valid(array()));
68bc2135
V
269 $this->assertFalse(
270 is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
271 );
06b6660a 272 }
b3051a6a 273
cbfdcff2
A
274 /**
275 * Test generateSecretApi.
276 */
277 public function testGenerateSecretApi()
278 {
279 $this->assertEquals(12, strlen(generate_api_secret('foo', 'bar')));
280 }
281
282 /**
283 * Test generateSecretApi with invalid parameters.
284 */
285 public function testGenerateSecretApiInvalid()
286 {
287 $this->assertFalse(generate_api_secret('', ''));
288 $this->assertFalse(generate_api_secret(false, false));
289 }
b3051a6a
A
290
291 /**
292 * Test normalize_spaces.
293 */
294 public function testNormalizeSpace()
295 {
296 $str = ' foo bar is important ';
297 $this->assertEquals('foo bar is important', normalize_spaces($str));
298 $this->assertEquals('foo', normalize_spaces('foo'));
299 $this->assertEquals('', normalize_spaces(''));
300 $this->assertEquals(null, normalize_spaces(null));
301 }
1255a42c
A
302
303 /**
304 * Test arrays_combine
305 */
52b50310 306 public function testCartesianProductGenerator()
1255a42c
A
307 {
308 $arr = [['ab', 'cd'], ['ef', 'gh'], ['ij', 'kl'], ['m']];
309 $expected = [
52b50310
A
310 ['ab', 'ef', 'ij', 'm'],
311 ['ab', 'ef', 'kl', 'm'],
312 ['ab', 'gh', 'ij', 'm'],
313 ['ab', 'gh', 'kl', 'm'],
314 ['cd', 'ef', 'ij', 'm'],
315 ['cd', 'ef', 'kl', 'm'],
316 ['cd', 'gh', 'ij', 'm'],
317 ['cd', 'gh', 'kl', 'm'],
1255a42c 318 ];
52b50310 319 $this->assertEquals($expected, iterator_to_array(cartesian_product_generator($arr)));
1255a42c
A
320 }
321
52b50310
A
322 /**
323 * Test date_format() with invalid parameter.
324 */
325 public function testDateFormatInvalid()
326 {
327 $this->assertFalse(format_date([]));
328 $this->assertFalse(format_date(null));
329 }
84315a3b
A
330
331 /**
332 * Test is_integer_mixed with valid values
333 */
334 public function testIsIntegerMixedValid()
335 {
336 $this->assertTrue(is_integer_mixed(12));
337 $this->assertTrue(is_integer_mixed('12'));
338 $this->assertTrue(is_integer_mixed(-12));
339 $this->assertTrue(is_integer_mixed('-12'));
340 $this->assertTrue(is_integer_mixed(0));
341 $this->assertTrue(is_integer_mixed('0'));
342 $this->assertTrue(is_integer_mixed(0x0a));
343 }
344
345 /**
346 * Test is_integer_mixed with invalid values
347 */
348 public function testIsIntegerMixedInvalid()
349 {
350 $this->assertFalse(is_integer_mixed(true));
351 $this->assertFalse(is_integer_mixed(false));
352 $this->assertFalse(is_integer_mixed([]));
353 $this->assertFalse(is_integer_mixed(['test']));
354 $this->assertFalse(is_integer_mixed([12]));
355 $this->assertFalse(is_integer_mixed(new DateTime()));
356 $this->assertFalse(is_integer_mixed('0x0a'));
357 $this->assertFalse(is_integer_mixed('12k'));
358 $this->assertFalse(is_integer_mixed('k12'));
359 $this->assertFalse(is_integer_mixed(''));
360 }
361
362 /**
363 * Test return_bytes
364 */
365 public function testReturnBytes()
366 {
367 $this->assertEquals(2 * 1024, return_bytes('2k'));
368 $this->assertEquals(2 * 1024, return_bytes('2K'));
b68134ac
A
369 $this->assertEquals(2 * (pow(1024, 2)), return_bytes('2m'));
370 $this->assertEquals(2 * (pow(1024, 2)), return_bytes('2M'));
371 $this->assertEquals(2 * (pow(1024, 3)), return_bytes('2g'));
372 $this->assertEquals(2 * (pow(1024, 3)), return_bytes('2G'));
84315a3b
A
373 $this->assertEquals(374, return_bytes('374'));
374 $this->assertEquals(374, return_bytes(374));
375 $this->assertEquals(0, return_bytes('0'));
376 $this->assertEquals(0, return_bytes(0));
377 $this->assertEquals(-1, return_bytes('-1'));
378 $this->assertEquals(-1, return_bytes(-1));
379 $this->assertEquals('', return_bytes(''));
380 }
381
382 /**
383 * Test human_bytes
384 */
385 public function testHumanBytes()
386 {
387 $this->assertEquals('2kiB', human_bytes(2 * 1024));
388 $this->assertEquals('2kiB', human_bytes(strval(2 * 1024)));
b68134ac
A
389 $this->assertEquals('2MiB', human_bytes(2 * (pow(1024, 2))));
390 $this->assertEquals('2MiB', human_bytes(strval(2 * (pow(1024, 2)))));
391 $this->assertEquals('2GiB', human_bytes(2 * (pow(1024, 3))));
392 $this->assertEquals('2GiB', human_bytes(strval(2 * (pow(1024, 3)))));
84315a3b
A
393 $this->assertEquals('374B', human_bytes(374));
394 $this->assertEquals('374B', human_bytes('374'));
6a19124a 395 $this->assertEquals('232kiB', human_bytes(237481));
84315a3b
A
396 $this->assertEquals('Unlimited', human_bytes('0'));
397 $this->assertEquals('Unlimited', human_bytes(0));
398 $this->assertEquals('Setting not set', human_bytes(''));
399 }
400
401 /**
6a19124a 402 * Test get_max_upload_size with formatting
84315a3b
A
403 */
404 public function testGetMaxUploadSize()
405 {
406 $this->assertEquals('1MiB', get_max_upload_size(2097152, '1024k'));
407 $this->assertEquals('1MiB', get_max_upload_size('1m', '2m'));
408 $this->assertEquals('100B', get_max_upload_size(100, 100));
409 }
6a19124a
A
410
411 /**
412 * Test get_max_upload_size without formatting
413 */
414 public function testGetMaxUploadSizeRaw()
415 {
416 $this->assertEquals('1048576', get_max_upload_size(2097152, '1024k', false));
417 $this->assertEquals('1048576', get_max_upload_size('1m', '2m', false));
418 $this->assertEquals('100', get_max_upload_size(100, 100, false));
419 }
aa4797ba
A
420
421 /**
422 * Test alphabetical_sort by value, not reversed, with php-intl.
423 */
424 public function testAlphabeticalSortByValue()
425 {
426 $arr = [
427 'zZz',
428 'éee',
429 'éae',
430 'eee',
431 'A',
432 'a',
433 'zzz',
434 ];
435 $expected = [
436 'a',
437 'A',
438 'éae',
439 'eee',
440 'éee',
441 'zzz',
442 'zZz',
443 ];
444
445 alphabetical_sort($arr);
446 $this->assertEquals($expected, $arr);
447 }
448
449 /**
450 * Test alphabetical_sort by value, reversed, with php-intl.
451 */
452 public function testAlphabeticalSortByValueReversed()
453 {
454 $arr = [
455 'zZz',
456 'éee',
457 'éae',
458 'eee',
459 'A',
460 'a',
461 'zzz',
462 ];
463 $expected = [
464 'zZz',
465 'zzz',
466 'éee',
467 'eee',
468 'éae',
469 'A',
470 'a',
471 ];
472
473 alphabetical_sort($arr, true);
474 $this->assertEquals($expected, $arr);
475 }
476
477 /**
478 * Test alphabetical_sort by keys, not reversed, with php-intl.
479 */
480 public function testAlphabeticalSortByKeys()
481 {
482 $arr = [
483 'zZz' => true,
484 'éee' => true,
485 'éae' => true,
486 'eee' => true,
487 'A' => true,
488 'a' => true,
489 'zzz' => true,
490 ];
491 $expected = [
492 'a' => true,
493 'A' => true,
494 'éae' => true,
495 'eee' => true,
496 'éee' => true,
497 'zzz' => true,
498 'zZz' => true,
499 ];
500
501 alphabetical_sort($arr, true, true);
502 $this->assertEquals($expected, $arr);
503 }
504
505 /**
506 * Test alphabetical_sort by keys, reversed, with php-intl.
507 */
508 public function testAlphabeticalSortByKeysReversed()
509 {
510 $arr = [
511 'zZz' => true,
512 'éee' => true,
513 'éae' => true,
514 'eee' => true,
515 'A' => true,
516 'a' => true,
517 'zzz' => true,
518 ];
519 $expected = [
520 'zZz' => true,
521 'zzz' => true,
522 'éee' => true,
523 'eee' => true,
524 'éae' => true,
525 'A' => true,
526 'a' => true,
527 ];
528
529 alphabetical_sort($arr, true, true);
530 $this->assertEquals($expected, $arr);
531 }
ca74886f 532}