aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/HttpUtils/ServerUrlTest.php32
-rw-r--r--tests/LanguagesTest.php186
-rw-r--r--tests/LinkFilterTest.php13
-rw-r--r--tests/LinkUtilsTest.php25
-rw-r--r--tests/NetscapeBookmarkUtils/BookmarkImportTest.php81
-rw-r--r--tests/SessionManagerTest.php149
-rw-r--r--tests/UtilsTest.php88
-rw-r--r--tests/bootstrap.php6
-rw-r--r--tests/languages/bootstrap.php7
-rw-r--r--tests/languages/fr/LanguagesFrTest.php175
-rw-r--r--tests/utils/FakeConfigManager.php12
-rw-r--r--tests/utils/ReferenceLinkDB.php23
-rw-r--r--tests/utils/languages/fr/LC_MESSAGES/test.mobin0 -> 456 bytes
-rw-r--r--tests/utils/languages/fr/LC_MESSAGES/test.po19
14 files changed, 683 insertions, 133 deletions
diff --git a/tests/HttpUtils/ServerUrlTest.php b/tests/HttpUtils/ServerUrlTest.php
index dac02b3e..324b827a 100644
--- a/tests/HttpUtils/ServerUrlTest.php
+++ b/tests/HttpUtils/ServerUrlTest.php
@@ -186,4 +186,36 @@ class ServerUrlTest extends PHPUnit_Framework_TestCase
186 ) 186 )
187 ); 187 );
188 } 188 }
189
190 /**
191 * Misconfigured server (see #1022): Proxy HTTP but 443
192 */
193 public function testHttpWithPort433()
194 {
195 $this->assertEquals(
196 'https://host.tld',
197 server_url(
198 array(
199 'HTTPS' => 'Off',
200 'SERVER_NAME' => 'host.tld',
201 'SERVER_PORT' => '80',
202 'HTTP_X_FORWARDED_PROTO' => 'http',
203 'HTTP_X_FORWARDED_PORT' => '443'
204 )
205 )
206 );
207
208 $this->assertEquals(
209 'https://host.tld',
210 server_url(
211 array(
212 'HTTPS' => 'Off',
213 'SERVER_NAME' => 'host.tld',
214 'SERVER_PORT' => '80',
215 'HTTP_X_FORWARDED_PROTO' => 'https, http',
216 'HTTP_X_FORWARDED_PORT' => '443, 80'
217 )
218 )
219 );
220 }
189} 221}
diff --git a/tests/LanguagesTest.php b/tests/LanguagesTest.php
index 79c136c8..864ce630 100644
--- a/tests/LanguagesTest.php
+++ b/tests/LanguagesTest.php
@@ -1,41 +1,203 @@
1<?php 1<?php
2 2
3require_once 'application/Languages.php'; 3namespace Shaarli;
4
5use Shaarli\Config\ConfigManager;
4 6
5/** 7/**
6 * Class LanguagesTest. 8 * Class LanguagesTest.
7 */ 9 */
8class LanguagesTest extends PHPUnit_Framework_TestCase 10class LanguagesTest extends \PHPUnit_Framework_TestCase
9{ 11{
10 /** 12 /**
13 * @var string Config file path (without extension).
14 */
15 protected static $configFile = 'tests/utils/config/configJson';
16
17 /**
18 * @var ConfigManager
19 */
20 protected $conf;
21
22 /**
23 *
24 */
25 public function setUp()
26 {
27 $this->conf = new ConfigManager(self::$configFile);
28 }
29
30 /**
31 * Test t() with a simple non identified value.
32 */
33 public function testTranslateSingleNotIDGettext()
34 {
35 $this->conf->set('translation.mode', 'gettext');
36 new Languages('en', $this->conf);
37 $text = 'abcdé 564 fgK';
38 $this->assertEquals($text, t($text));
39 }
40
41 /**
42 * Test t() with a simple identified value in gettext mode.
43 */
44 public function testTranslateSingleIDGettext()
45 {
46 $this->conf->set('translation.mode', 'gettext');
47 new Languages('en', $this->conf);
48 $text = 'permalink';
49 $this->assertEquals($text, t($text));
50 }
51
52 /**
53 * Test t() with a non identified plural form in gettext mode.
54 */
55 public function testTranslatePluralNotIDGettext()
56 {
57 $this->conf->set('translation.mode', 'gettext');
58 new Languages('en', $this->conf);
59 $text = 'sandwich';
60 $nText = 'sandwiches';
61 $this->assertEquals('sandwiches', t($text, $nText, 0));
62 $this->assertEquals('sandwich', t($text, $nText, 1));
63 $this->assertEquals('sandwiches', t($text, $nText, 2));
64 }
65
66 /**
67 * Test t() with an identified plural form in gettext mode.
68 */
69 public function testTranslatePluralIDGettext()
70 {
71 $this->conf->set('translation.mode', 'gettext');
72 new Languages('en', $this->conf);
73 $text = 'shaare';
74 $nText = 'shaares';
75 // In english, zero is followed by plural form
76 $this->assertEquals('shaares', t($text, $nText, 0));
77 $this->assertEquals('shaare', t($text, $nText, 1));
78 $this->assertEquals('shaares', t($text, $nText, 2));
79 }
80
81 /**
11 * Test t() with a simple non identified value. 82 * Test t() with a simple non identified value.
12 */ 83 */
13 public function testTranslateSingleNotID() 84 public function testTranslateSingleNotIDPhp()
14 { 85 {
86 $this->conf->set('translation.mode', 'php');
87 new Languages('en', $this->conf);
15 $text = 'abcdé 564 fgK'; 88 $text = 'abcdé 564 fgK';
16 $this->assertEquals($text, t($text)); 89 $this->assertEquals($text, t($text));
17 } 90 }
18 91
19 /** 92 /**
20 * Test t() with a non identified plural form. 93 * Test t() with a simple identified value in PHP mode.
21 */ 94 */
22 public function testTranslatePluralNotID() 95 public function testTranslateSingleIDPhp()
23 { 96 {
24 $text = '%s sandwich'; 97 $this->conf->set('translation.mode', 'php');
25 $nText = '%s sandwiches'; 98 new Languages('en', $this->conf);
26 $this->assertEquals('0 sandwich', t($text, $nText)); 99 $text = 'permalink';
27 $this->assertEquals('1 sandwich', t($text, $nText, 1)); 100 $this->assertEquals($text, t($text));
28 $this->assertEquals('2 sandwiches', t($text, $nText, 2));
29 } 101 }
30 102
31 /** 103 /**
32 * Test t() with a non identified invalid plural form. 104 * Test t() with a non identified plural form in PHP mode.
33 */ 105 */
34 public function testTranslatePluralNotIDInvalid() 106 public function testTranslatePluralNotIDPhp()
35 { 107 {
108 $this->conf->set('translation.mode', 'php');
109 new Languages('en', $this->conf);
36 $text = 'sandwich'; 110 $text = 'sandwich';
37 $nText = 'sandwiches'; 111 $nText = 'sandwiches';
112 $this->assertEquals('sandwiches', t($text, $nText, 0));
38 $this->assertEquals('sandwich', t($text, $nText, 1)); 113 $this->assertEquals('sandwich', t($text, $nText, 1));
39 $this->assertEquals('sandwiches', t($text, $nText, 2)); 114 $this->assertEquals('sandwiches', t($text, $nText, 2));
40 } 115 }
116
117 /**
118 * Test t() with an identified plural form in PHP mode.
119 */
120 public function testTranslatePluralIDPhp()
121 {
122 $this->conf->set('translation.mode', 'php');
123 new Languages('en', $this->conf);
124 $text = 'shaare';
125 $nText = 'shaares';
126 // In english, zero is followed by plural form
127 $this->assertEquals('shaares', t($text, $nText, 0));
128 $this->assertEquals('shaare', t($text, $nText, 1));
129 $this->assertEquals('shaares', t($text, $nText, 2));
130 }
131
132 /**
133 * Test t() with an invalid language set in the configuration in gettext mode.
134 */
135 public function testTranslateWithInvalidConfLanguageGettext()
136 {
137 $this->conf->set('translation.mode', 'gettext');
138 $this->conf->set('translation.language', 'nope');
139 new Languages('fr', $this->conf);
140 $text = 'grumble';
141 $this->assertEquals($text, t($text));
142 }
143
144 /**
145 * Test t() with an invalid language set in the configuration in PHP mode.
146 */
147 public function testTranslateWithInvalidConfLanguagePhp()
148 {
149 $this->conf->set('translation.mode', 'php');
150 $this->conf->set('translation.language', 'nope');
151 new Languages('fr', $this->conf);
152 $text = 'grumble';
153 $this->assertEquals($text, t($text));
154 }
155
156 /**
157 * Test t() with an invalid language set with auto language in gettext mode.
158 */
159 public function testTranslateWithInvalidAutoLanguageGettext()
160 {
161 $this->conf->set('translation.mode', 'gettext');
162 new Languages('nope', $this->conf);
163 $text = 'grumble';
164 $this->assertEquals($text, t($text));
165 }
166
167 /**
168 * Test t() with an invalid language set with auto language in PHP mode.
169 */
170 public function testTranslateWithInvalidAutoLanguagePhp()
171 {
172 $this->conf->set('translation.mode', 'php');
173 new Languages('nope', $this->conf);
174 $text = 'grumble';
175 $this->assertEquals($text, t($text));
176 }
177
178 /**
179 * Test t() with an extension language file in gettext mode
180 */
181 public function testTranslationExtensionGettext()
182 {
183 $this->conf->set('translation.mode', 'gettext');
184 $this->conf->set('translation.extensions.test', 'tests/utils/languages/');
185 new Languages('en', $this->conf);
186 $txt = 'car'; // ignore me poedit
187 $this->assertEquals('car', t($txt, $txt, 1, 'test'));
188 $this->assertEquals('Search', t('Search', 'Search', 1, 'test'));
189 }
190
191 /**
192 * Test t() with an extension language file in PHP mode
193 */
194 public function testTranslationExtensionPhp()
195 {
196 $this->conf->set('translation.mode', 'php');
197 $this->conf->set('translation.extensions.test', 'tests/utils/languages/');
198 new Languages('en', $this->conf);
199 $txt = 'car'; // ignore me poedit
200 $this->assertEquals('car', t($txt, $txt, 1, 'test'));
201 $this->assertEquals('Search', t('Search', 'Search', 1, 'test'));
202 }
41} 203}
diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php
index d796d3a3..9cd6dbd4 100644
--- a/tests/LinkFilterTest.php
+++ b/tests/LinkFilterTest.php
@@ -8,6 +8,10 @@ require_once 'application/LinkFilter.php';
8class LinkFilterTest extends PHPUnit_Framework_TestCase 8class LinkFilterTest extends PHPUnit_Framework_TestCase
9{ 9{
10 /** 10 /**
11 * @var string Test datastore path.
12 */
13 protected static $testDatastore = 'sandbox/datastore.php';
14 /**
11 * @var LinkFilter instance. 15 * @var LinkFilter instance.
12 */ 16 */
13 protected static $linkFilter; 17 protected static $linkFilter;
@@ -18,12 +22,19 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
18 protected static $refDB; 22 protected static $refDB;
19 23
20 /** 24 /**
25 * @var LinkDB instance
26 */
27 protected static $linkDB;
28
29 /**
21 * Instanciate linkFilter with ReferenceLinkDB data. 30 * Instanciate linkFilter with ReferenceLinkDB data.
22 */ 31 */
23 public static function setUpBeforeClass() 32 public static function setUpBeforeClass()
24 { 33 {
25 self::$refDB = new ReferenceLinkDB(); 34 self::$refDB = new ReferenceLinkDB();
26 self::$linkFilter = new LinkFilter(self::$refDB->getLinks()); 35 self::$refDB->write(self::$testDatastore);
36 self::$linkDB = new LinkDB(self::$testDatastore, true, false);
37 self::$linkFilter = new LinkFilter(self::$linkDB);
27 } 38 }
28 39
29 /** 40 /**
diff --git a/tests/LinkUtilsTest.php b/tests/LinkUtilsTest.php
index ef650f44..7fbd59b0 100644
--- a/tests/LinkUtilsTest.php
+++ b/tests/LinkUtilsTest.php
@@ -214,6 +214,16 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
214 $expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff'; 214 $expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff';
215 $processedText = text2clickable($text, ''); 215 $processedText = text2clickable($text, '');
216 $this->assertEquals($expectedText, $processedText); 216 $this->assertEquals($expectedText, $processedText);
217
218 $text = 'stuff http://hello.there/is=someone#here(please) otherstuff';
219 $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)">http://hello.there/is=someone#here(please)</a> otherstuff';
220 $processedText = text2clickable($text, '');
221 $this->assertEquals($expectedText, $processedText);
222
223 $text = 'stuff http://hello.there/is=someone#here(please)&no otherstuff';
224 $expectedText = 'stuff <a href="http://hello.there/is=someone#here(please)&no">http://hello.there/is=someone#here(please)&no</a> otherstuff';
225 $processedText = text2clickable($text, '');
226 $this->assertEquals($expectedText, $processedText);
217 } 227 }
218 228
219 /** 229 /**
@@ -232,6 +242,21 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
232 } 242 }
233 243
234 /** 244 /**
245 * Test text2clickable a redirector set and without URL encode.
246 */
247 public function testText2clickableWithRedirectorDontEncode()
248 {
249 $text = 'stuff http://hello.there/?is=someone&or=something#here otherstuff';
250 $redirector = 'http://redirector.to';
251 $expectedText = 'stuff <a href="'.
252 $redirector .
253 'http://hello.there/?is=someone&or=something#here' .
254 '">http://hello.there/?is=someone&or=something#here</a> otherstuff';
255 $processedText = text2clickable($text, $redirector, false);
256 $this->assertEquals($expectedText, $processedText);
257 }
258
259 /**
235 * Test testSpace2nbsp. 260 * Test testSpace2nbsp.
236 */ 261 */
237 public function testSpace2nbsp() 262 public function testSpace2nbsp()
diff --git a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
index 5fc1d1e8..4961aa2c 100644
--- a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
+++ b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
@@ -132,8 +132,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
132 public function testImportInternetExplorerEncoding() 132 public function testImportInternetExplorerEncoding()
133 { 133 {
134 $files = file2array('internet_explorer_encoding.htm'); 134 $files = file2array('internet_explorer_encoding.htm');
135 $this->assertEquals( 135 $this->assertStringMatchesFormat(
136 'File internet_explorer_encoding.htm (356 bytes) was successfully processed:' 136 'File internet_explorer_encoding.htm (356 bytes) was successfully processed in %d seconds:'
137 .' 1 links imported, 0 links overwritten, 0 links skipped.', 137 .' 1 links imported, 0 links overwritten, 0 links skipped.',
138 NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history) 138 NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
139 ); 139 );
@@ -161,8 +161,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
161 public function testImportNested() 161 public function testImportNested()
162 { 162 {
163 $files = file2array('netscape_nested.htm'); 163 $files = file2array('netscape_nested.htm');
164 $this->assertEquals( 164 $this->assertStringMatchesFormat(
165 'File netscape_nested.htm (1337 bytes) was successfully processed:' 165 'File netscape_nested.htm (1337 bytes) was successfully processed in %d seconds:'
166 .' 8 links imported, 0 links overwritten, 0 links skipped.', 166 .' 8 links imported, 0 links overwritten, 0 links skipped.',
167 NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history) 167 NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
168 ); 168 );
@@ -283,8 +283,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
283 public function testImportDefaultPrivacyNoPost() 283 public function testImportDefaultPrivacyNoPost()
284 { 284 {
285 $files = file2array('netscape_basic.htm'); 285 $files = file2array('netscape_basic.htm');
286 $this->assertEquals( 286 $this->assertStringMatchesFormat(
287 'File netscape_basic.htm (482 bytes) was successfully processed:' 287 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
288 .' 2 links imported, 0 links overwritten, 0 links skipped.', 288 .' 2 links imported, 0 links overwritten, 0 links skipped.',
289 NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history) 289 NetscapeBookmarkUtils::import([], $files, $this->linkDb, $this->conf, $this->history)
290 ); 290 );
@@ -328,8 +328,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
328 { 328 {
329 $post = array('privacy' => 'default'); 329 $post = array('privacy' => 'default');
330 $files = file2array('netscape_basic.htm'); 330 $files = file2array('netscape_basic.htm');
331 $this->assertEquals( 331 $this->assertStringMatchesFormat(
332 'File netscape_basic.htm (482 bytes) was successfully processed:' 332 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
333 .' 2 links imported, 0 links overwritten, 0 links skipped.', 333 .' 2 links imported, 0 links overwritten, 0 links skipped.',
334 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 334 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
335 ); 335 );
@@ -372,8 +372,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
372 { 372 {
373 $post = array('privacy' => 'public'); 373 $post = array('privacy' => 'public');
374 $files = file2array('netscape_basic.htm'); 374 $files = file2array('netscape_basic.htm');
375 $this->assertEquals( 375 $this->assertStringMatchesFormat(
376 'File netscape_basic.htm (482 bytes) was successfully processed:' 376 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
377 .' 2 links imported, 0 links overwritten, 0 links skipped.', 377 .' 2 links imported, 0 links overwritten, 0 links skipped.',
378 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 378 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
379 ); 379 );
@@ -396,8 +396,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
396 { 396 {
397 $post = array('privacy' => 'private'); 397 $post = array('privacy' => 'private');
398 $files = file2array('netscape_basic.htm'); 398 $files = file2array('netscape_basic.htm');
399 $this->assertEquals( 399 $this->assertStringMatchesFormat(
400 'File netscape_basic.htm (482 bytes) was successfully processed:' 400 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
401 .' 2 links imported, 0 links overwritten, 0 links skipped.', 401 .' 2 links imported, 0 links overwritten, 0 links skipped.',
402 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 402 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
403 ); 403 );
@@ -422,8 +422,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
422 422
423 // import links as private 423 // import links as private
424 $post = array('privacy' => 'private'); 424 $post = array('privacy' => 'private');
425 $this->assertEquals( 425 $this->assertStringMatchesFormat(
426 'File netscape_basic.htm (482 bytes) was successfully processed:' 426 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
427 .' 2 links imported, 0 links overwritten, 0 links skipped.', 427 .' 2 links imported, 0 links overwritten, 0 links skipped.',
428 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 428 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
429 ); 429 );
@@ -442,8 +442,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
442 'privacy' => 'public', 442 'privacy' => 'public',
443 'overwrite' => 'true' 443 'overwrite' => 'true'
444 ); 444 );
445 $this->assertEquals( 445 $this->assertStringMatchesFormat(
446 'File netscape_basic.htm (482 bytes) was successfully processed:' 446 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
447 .' 2 links imported, 2 links overwritten, 0 links skipped.', 447 .' 2 links imported, 2 links overwritten, 0 links skipped.',
448 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 448 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
449 ); 449 );
@@ -468,8 +468,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
468 468
469 // import links as public 469 // import links as public
470 $post = array('privacy' => 'public'); 470 $post = array('privacy' => 'public');
471 $this->assertEquals( 471 $this->assertStringMatchesFormat(
472 'File netscape_basic.htm (482 bytes) was successfully processed:' 472 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
473 .' 2 links imported, 0 links overwritten, 0 links skipped.', 473 .' 2 links imported, 0 links overwritten, 0 links skipped.',
474 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 474 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
475 ); 475 );
@@ -489,8 +489,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
489 'privacy' => 'private', 489 'privacy' => 'private',
490 'overwrite' => 'true' 490 'overwrite' => 'true'
491 ); 491 );
492 $this->assertEquals( 492 $this->assertStringMatchesFormat(
493 'File netscape_basic.htm (482 bytes) was successfully processed:' 493 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
494 .' 2 links imported, 2 links overwritten, 0 links skipped.', 494 .' 2 links imported, 2 links overwritten, 0 links skipped.',
495 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 495 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
496 ); 496 );
@@ -513,8 +513,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
513 { 513 {
514 $post = array('privacy' => 'public'); 514 $post = array('privacy' => 'public');
515 $files = file2array('netscape_basic.htm'); 515 $files = file2array('netscape_basic.htm');
516 $this->assertEquals( 516 $this->assertStringMatchesFormat(
517 'File netscape_basic.htm (482 bytes) was successfully processed:' 517 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
518 .' 2 links imported, 0 links overwritten, 0 links skipped.', 518 .' 2 links imported, 0 links overwritten, 0 links skipped.',
519 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 519 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
520 ); 520 );
@@ -523,8 +523,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
523 523
524 // re-import as private, DO NOT enable overwriting 524 // re-import as private, DO NOT enable overwriting
525 $post = array('privacy' => 'private'); 525 $post = array('privacy' => 'private');
526 $this->assertEquals( 526 $this->assertStringMatchesFormat(
527 'File netscape_basic.htm (482 bytes) was successfully processed:' 527 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
528 .' 0 links imported, 0 links overwritten, 2 links skipped.', 528 .' 0 links imported, 0 links overwritten, 2 links skipped.',
529 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 529 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
530 ); 530 );
@@ -542,8 +542,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
542 'default_tags' => 'tag1,tag2 tag3' 542 'default_tags' => 'tag1,tag2 tag3'
543 ); 543 );
544 $files = file2array('netscape_basic.htm'); 544 $files = file2array('netscape_basic.htm');
545 $this->assertEquals( 545 $this->assertStringMatchesFormat(
546 'File netscape_basic.htm (482 bytes) was successfully processed:' 546 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
547 .' 2 links imported, 0 links overwritten, 0 links skipped.', 547 .' 2 links imported, 0 links overwritten, 0 links skipped.',
548 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 548 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
549 ); 549 );
@@ -569,8 +569,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
569 'default_tags' => 'tag1&,tag2 "tag3"' 569 'default_tags' => 'tag1&,tag2 "tag3"'
570 ); 570 );
571 $files = file2array('netscape_basic.htm'); 571 $files = file2array('netscape_basic.htm');
572 $this->assertEquals( 572 $this->assertStringMatchesFormat(
573 'File netscape_basic.htm (482 bytes) was successfully processed:' 573 'File netscape_basic.htm (482 bytes) was successfully processed in %d seconds:'
574 .' 2 links imported, 0 links overwritten, 0 links skipped.', 574 .' 2 links imported, 0 links overwritten, 0 links skipped.',
575 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history) 575 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history)
576 ); 576 );
@@ -594,8 +594,8 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
594 public function testImportSameDate() 594 public function testImportSameDate()
595 { 595 {
596 $files = file2array('same_date.htm'); 596 $files = file2array('same_date.htm');
597 $this->assertEquals( 597 $this->assertStringMatchesFormat(
598 'File same_date.htm (453 bytes) was successfully processed:' 598 'File same_date.htm (453 bytes) was successfully processed in %d seconds:'
599 .' 3 links imported, 0 links overwritten, 0 links skipped.', 599 .' 3 links imported, 0 links overwritten, 0 links skipped.',
600 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf, $this->history) 600 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->conf, $this->history)
601 ); 601 );
@@ -622,24 +622,19 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
622 'overwrite' => 'true', 622 'overwrite' => 'true',
623 ]; 623 ];
624 $files = file2array('netscape_basic.htm'); 624 $files = file2array('netscape_basic.htm');
625 $nbLinks = 2;
626 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history); 625 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history);
627 $history = $this->history->getHistory(); 626 $history = $this->history->getHistory();
628 $this->assertEquals($nbLinks, count($history)); 627 $this->assertEquals(1, count($history));
629 foreach ($history as $value) { 628 $this->assertEquals(History::IMPORT, $history[0]['event']);
630 $this->assertEquals(History::CREATED, $value['event']); 629 $this->assertTrue(new DateTime('-5 seconds') < $history[0]['datetime']);
631 $this->assertTrue(new DateTime('-5 seconds') < $value['datetime']);
632 $this->assertTrue(is_int($value['id']));
633 }
634 630
635 // re-import as private, enable overwriting 631 // re-import as private, enable overwriting
636 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history); 632 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->conf, $this->history);
637 $history = $this->history->getHistory(); 633 $history = $this->history->getHistory();
638 $this->assertEquals($nbLinks * 2, count($history)); 634 $this->assertEquals(2, count($history));
639 for ($i = 0 ; $i < $nbLinks ; $i++) { 635 $this->assertEquals(History::IMPORT, $history[0]['event']);
640 $this->assertEquals(History::UPDATED, $history[$i]['event']); 636 $this->assertTrue(new DateTime('-5 seconds') < $history[0]['datetime']);
641 $this->assertTrue(new DateTime('-5 seconds') < $history[$i]['datetime']); 637 $this->assertEquals(History::IMPORT, $history[1]['event']);
642 $this->assertTrue(is_int($history[$i]['id'])); 638 $this->assertTrue(new DateTime('-5 seconds') < $history[1]['datetime']);
643 }
644 } 639 }
645} 640}
diff --git a/tests/SessionManagerTest.php b/tests/SessionManagerTest.php
new file mode 100644
index 00000000..aa75962a
--- /dev/null
+++ b/tests/SessionManagerTest.php
@@ -0,0 +1,149 @@
1<?php
2require_once 'tests/utils/FakeConfigManager.php';
3
4// Initialize reference data _before_ PHPUnit starts a session
5require_once 'tests/utils/ReferenceSessionIdHashes.php';
6ReferenceSessionIdHashes::genAllHashes();
7
8use \Shaarli\SessionManager;
9use \PHPUnit\Framework\TestCase;
10
11
12/**
13 * Test coverage for SessionManager
14 */
15class SessionManagerTest extends TestCase
16{
17 // Session ID hashes
18 protected static $sidHashes = null;
19
20 // Fake ConfigManager
21 protected static $conf = null;
22
23 /**
24 * Assign reference data
25 */
26 public static function setUpBeforeClass()
27 {
28 self::$sidHashes = ReferenceSessionIdHashes::getHashes();
29 self::$conf = new FakeConfigManager();
30 }
31
32 /**
33 * Generate a session token
34 */
35 public function testGenerateToken()
36 {
37 $session = [];
38 $sessionManager = new SessionManager($session, self::$conf);
39
40 $token = $sessionManager->generateToken();
41
42 $this->assertEquals(1, $session['tokens'][$token]);
43 $this->assertEquals(40, strlen($token));
44 }
45
46 /**
47 * Check a session token
48 */
49 public function testCheckToken()
50 {
51 $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b';
52 $session = [
53 'tokens' => [
54 $token => 1,
55 ],
56 ];
57 $sessionManager = new SessionManager($session, self::$conf);
58
59 // check and destroy the token
60 $this->assertTrue($sessionManager->checkToken($token));
61 $this->assertFalse(isset($session['tokens'][$token]));
62
63 // ensure the token has been destroyed
64 $this->assertFalse($sessionManager->checkToken($token));
65 }
66
67 /**
68 * Generate and check a session token
69 */
70 public function testGenerateAndCheckToken()
71 {
72 $session = [];
73 $sessionManager = new SessionManager($session, self::$conf);
74
75 $token = $sessionManager->generateToken();
76
77 // ensure a token has been generated
78 $this->assertEquals(1, $session['tokens'][$token]);
79 $this->assertEquals(40, strlen($token));
80
81 // check and destroy the token
82 $this->assertTrue($sessionManager->checkToken($token));
83 $this->assertFalse(isset($session['tokens'][$token]));
84
85 // ensure the token has been destroyed
86 $this->assertFalse($sessionManager->checkToken($token));
87 }
88
89 /**
90 * Check an invalid session token
91 */
92 public function testCheckInvalidToken()
93 {
94 $session = [];
95 $sessionManager = new SessionManager($session, self::$conf);
96
97 $this->assertFalse($sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'));
98 }
99
100 /**
101 * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES!
102 *
103 * This tests extensively covers all hash algorithms / bit representations
104 */
105 public function testIsAnyHashSessionIdValid()
106 {
107 foreach (self::$sidHashes as $algo => $bpcs) {
108 foreach ($bpcs as $bpc => $hash) {
109 $this->assertTrue(SessionManager::checkId($hash));
110 }
111 }
112 }
113
114 /**
115 * Test checkId with a valid ID - SHA-1 hashes
116 */
117 public function testIsSha1SessionIdValid()
118 {
119 $this->assertTrue(SessionManager::checkId(sha1('shaarli')));
120 }
121
122 /**
123 * Test checkId with a valid ID - SHA-256 hashes
124 */
125 public function testIsSha256SessionIdValid()
126 {
127 $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli')));
128 }
129
130 /**
131 * Test checkId with a valid ID - SHA-512 hashes
132 */
133 public function testIsSha512SessionIdValid()
134 {
135 $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli')));
136 }
137
138 /**
139 * Test checkId with invalid IDs.
140 */
141 public function testIsSessionIdInvalid()
142 {
143 $this->assertFalse(SessionManager::checkId(''));
144 $this->assertFalse(SessionManager::checkId([]));
145 $this->assertFalse(
146 SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
147 );
148 }
149}
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php
index 3d1aa653..6cd37a7a 100644
--- a/tests/UtilsTest.php
+++ b/tests/UtilsTest.php
@@ -5,10 +5,6 @@
5 5
6require_once 'application/Utils.php'; 6require_once 'application/Utils.php';
7require_once 'application/Languages.php'; 7require_once 'application/Languages.php';
8require_once 'tests/utils/ReferenceSessionIdHashes.php';
9
10// Initialize reference data before PHPUnit starts a session
11ReferenceSessionIdHashes::genAllHashes();
12 8
13 9
14/** 10/**
@@ -16,9 +12,6 @@ ReferenceSessionIdHashes::genAllHashes();
16 */ 12 */
17class UtilsTest extends PHPUnit_Framework_TestCase 13class UtilsTest extends PHPUnit_Framework_TestCase
18{ 14{
19 // Session ID hashes
20 protected static $sidHashes = null;
21
22 // Log file 15 // Log file
23 protected static $testLogFile = 'tests.log'; 16 protected static $testLogFile = 'tests.log';
24 17
@@ -30,13 +23,11 @@ class UtilsTest extends PHPUnit_Framework_TestCase
30 */ 23 */
31 protected static $defaultTimeZone; 24 protected static $defaultTimeZone;
32 25
33
34 /** 26 /**
35 * Assign reference data 27 * Assign reference data
36 */ 28 */
37 public static function setUpBeforeClass() 29 public static function setUpBeforeClass()
38 { 30 {
39 self::$sidHashes = ReferenceSessionIdHashes::getHashes();
40 self::$defaultTimeZone = date_default_timezone_get(); 31 self::$defaultTimeZone = date_default_timezone_get();
41 // Timezone without DST for test consistency 32 // Timezone without DST for test consistency
42 date_default_timezone_set('Africa/Nairobi'); 33 date_default_timezone_set('Africa/Nairobi');
@@ -221,57 +212,8 @@ class UtilsTest extends PHPUnit_Framework_TestCase
221 $this->assertEquals('?', generateLocation($ref, 'localhost')); 212 $this->assertEquals('?', generateLocation($ref, 'localhost'));
222 } 213 }
223 214
224 /**
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 215
238 /** 216 /**
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
256 */
257 public function testIsSha512SessionIdValid()
258 {
259 $this->assertTrue(is_session_id_valid(hash('sha512', 'shaarli')));
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()));
269 $this->assertFalse(
270 is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
271 );
272 }
273
274 /**
275 * Test generateSecretApi. 217 * Test generateSecretApi.
276 */ 218 */
277 public function testGenerateSecretApi() 219 public function testGenerateSecretApi()
@@ -384,18 +326,18 @@ class UtilsTest extends PHPUnit_Framework_TestCase
384 */ 326 */
385 public function testHumanBytes() 327 public function testHumanBytes()
386 { 328 {
387 $this->assertEquals('2kiB', human_bytes(2 * 1024)); 329 $this->assertEquals('2'. t('kiB'), human_bytes(2 * 1024));
388 $this->assertEquals('2kiB', human_bytes(strval(2 * 1024))); 330 $this->assertEquals('2'. t('kiB'), human_bytes(strval(2 * 1024)));
389 $this->assertEquals('2MiB', human_bytes(2 * (pow(1024, 2)))); 331 $this->assertEquals('2'. t('MiB'), human_bytes(2 * (pow(1024, 2))));
390 $this->assertEquals('2MiB', human_bytes(strval(2 * (pow(1024, 2))))); 332 $this->assertEquals('2'. t('MiB'), human_bytes(strval(2 * (pow(1024, 2)))));
391 $this->assertEquals('2GiB', human_bytes(2 * (pow(1024, 3)))); 333 $this->assertEquals('2'. t('GiB'), human_bytes(2 * (pow(1024, 3))));
392 $this->assertEquals('2GiB', human_bytes(strval(2 * (pow(1024, 3))))); 334 $this->assertEquals('2'. t('GiB'), human_bytes(strval(2 * (pow(1024, 3)))));
393 $this->assertEquals('374B', human_bytes(374)); 335 $this->assertEquals('374'. t('B'), human_bytes(374));
394 $this->assertEquals('374B', human_bytes('374')); 336 $this->assertEquals('374'. t('B'), human_bytes('374'));
395 $this->assertEquals('232kiB', human_bytes(237481)); 337 $this->assertEquals('232'. t('kiB'), human_bytes(237481));
396 $this->assertEquals('Unlimited', human_bytes('0')); 338 $this->assertEquals(t('Unlimited'), human_bytes('0'));
397 $this->assertEquals('Unlimited', human_bytes(0)); 339 $this->assertEquals(t('Unlimited'), human_bytes(0));
398 $this->assertEquals('Setting not set', human_bytes('')); 340 $this->assertEquals(t('Setting not set'), human_bytes(''));
399 } 341 }
400 342
401 /** 343 /**
@@ -403,9 +345,9 @@ class UtilsTest extends PHPUnit_Framework_TestCase
403 */ 345 */
404 public function testGetMaxUploadSize() 346 public function testGetMaxUploadSize()
405 { 347 {
406 $this->assertEquals('1MiB', get_max_upload_size(2097152, '1024k')); 348 $this->assertEquals('1'. t('MiB'), get_max_upload_size(2097152, '1024k'));
407 $this->assertEquals('1MiB', get_max_upload_size('1m', '2m')); 349 $this->assertEquals('1'. t('MiB'), get_max_upload_size('1m', '2m'));
408 $this->assertEquals('100B', get_max_upload_size(100, 100)); 350 $this->assertEquals('100'. t('B'), get_max_upload_size(100, 100));
409 } 351 }
410 352
411 /** 353 /**
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 00000000..d36d73cd
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,6 @@
1<?php
2
3require_once 'vendor/autoload.php';
4
5$conf = new \Shaarli\Config\ConfigManager('tests/utils/config/configJson');
6new \Shaarli\Languages('en', $conf);
diff --git a/tests/languages/bootstrap.php b/tests/languages/bootstrap.php
index 95609210..da6ac2e4 100644
--- a/tests/languages/bootstrap.php
+++ b/tests/languages/bootstrap.php
@@ -1,7 +1,6 @@
1<?php 1<?php
2if (! empty('UT_LOCALE')) { 2require_once 'tests/bootstrap.php';
3
4if (! empty(getenv('UT_LOCALE'))) {
3 setlocale(LC_ALL, getenv('UT_LOCALE')); 5 setlocale(LC_ALL, getenv('UT_LOCALE'));
4} 6}
5
6require_once 'vendor/autoload.php';
7
diff --git a/tests/languages/fr/LanguagesFrTest.php b/tests/languages/fr/LanguagesFrTest.php
new file mode 100644
index 00000000..79d05172
--- /dev/null
+++ b/tests/languages/fr/LanguagesFrTest.php
@@ -0,0 +1,175 @@
1<?php
2
3
4namespace Shaarli;
5
6
7use Shaarli\Config\ConfigManager;
8
9/**
10 * Class LanguagesFrTest
11 *
12 * Test the translation system in PHP and gettext mode with French language.
13 *
14 * @package Shaarli
15 */
16class LanguagesFrTest extends \PHPUnit_Framework_TestCase
17{
18 /**
19 * @var string Config file path (without extension).
20 */
21 protected static $configFile = 'tests/utils/config/configJson';
22
23 /**
24 * @var ConfigManager
25 */
26 protected $conf;
27
28 /**
29 * Init: force French
30 */
31 public function setUp()
32 {
33 $this->conf = new ConfigManager(self::$configFile);
34 $this->conf->set('translation.language', 'fr');
35 }
36
37 /**
38 * Reset the locale since gettext seems to mess with it, making it too long
39 */
40 public static function tearDownAfterClass()
41 {
42 if (! empty(getenv('UT_LOCALE'))) {
43 setlocale(LC_ALL, getenv('UT_LOCALE'));
44 }
45 }
46
47 /**
48 * Test t() with a simple non identified value.
49 */
50 public function testTranslateSingleNotIDGettext()
51 {
52 $this->conf->set('translation.mode', 'gettext');
53 new Languages('en', $this->conf);
54 $text = 'abcdé 564 fgK';
55 $this->assertEquals($text, t($text));
56 }
57
58 /**
59 * Test t() with a simple identified value in gettext mode.
60 */
61 public function testTranslateSingleIDGettext()
62 {
63 $this->conf->set('translation.mode', 'gettext');
64 new Languages('en', $this->conf);
65 $text = 'permalink';
66 $this->assertEquals('permalien', t($text));
67 }
68
69 /**
70 * Test t() with a non identified plural form in gettext mode.
71 */
72 public function testTranslatePluralNotIDGettext()
73 {
74 $this->conf->set('translation.mode', 'gettext');
75 new Languages('en', $this->conf);
76 $text = 'sandwich';
77 $nText = 'sandwiches';
78 // Not ID, so English fallback, and in english, plural 0
79 $this->assertEquals('sandwiches', t($text, $nText, 0));
80 $this->assertEquals('sandwich', t($text, $nText, 1));
81 $this->assertEquals('sandwiches', t($text, $nText, 2));
82 }
83
84 /**
85 * Test t() with an identified plural form in gettext mode.
86 */
87 public function testTranslatePluralIDGettext()
88 {
89 $this->conf->set('translation.mode', 'gettext');
90 new Languages('en', $this->conf);
91 $text = 'shaare';
92 $nText = 'shaares';
93 $this->assertEquals('shaare', t($text, $nText, 0));
94 $this->assertEquals('shaare', t($text, $nText, 1));
95 $this->assertEquals('shaares', t($text, $nText, 2));
96 }
97
98 /**
99 * Test t() with a simple non identified value.
100 */
101 public function testTranslateSingleNotIDPhp()
102 {
103 $this->conf->set('translation.mode', 'php');
104 new Languages('en', $this->conf);
105 $text = 'abcdé 564 fgK';
106 $this->assertEquals($text, t($text));
107 }
108
109 /**
110 * Test t() with a simple identified value in PHP mode.
111 */
112 public function testTranslateSingleIDPhp()
113 {
114 $this->conf->set('translation.mode', 'php');
115 new Languages('en', $this->conf);
116 $text = 'permalink';
117 $this->assertEquals('permalien', t($text));
118 }
119
120 /**
121 * Test t() with a non identified plural form in PHP mode.
122 */
123 public function testTranslatePluralNotIDPhp()
124 {
125 $this->conf->set('translation.mode', 'php');
126 new Languages('en', $this->conf);
127 $text = 'sandwich';
128 $nText = 'sandwiches';
129 // Not ID, so English fallback, and in english, plural 0
130 $this->assertEquals('sandwiches', t($text, $nText, 0));
131 $this->assertEquals('sandwich', t($text, $nText, 1));
132 $this->assertEquals('sandwiches', t($text, $nText, 2));
133 }
134
135 /**
136 * Test t() with an identified plural form in PHP mode.
137 */
138 public function testTranslatePluralIDPhp()
139 {
140 $this->conf->set('translation.mode', 'php');
141 new Languages('en', $this->conf);
142 $text = 'shaare';
143 $nText = 'shaares';
144 // In english, zero is followed by plural form
145 $this->assertEquals('shaare', t($text, $nText, 0));
146 $this->assertEquals('shaare', t($text, $nText, 1));
147 $this->assertEquals('shaares', t($text, $nText, 2));
148 }
149
150 /**
151 * Test t() with an extension language file in gettext mode
152 */
153 public function testTranslationExtensionGettext()
154 {
155 $this->conf->set('translation.mode', 'gettext');
156 $this->conf->set('translation.extensions.test', 'tests/utils/languages/');
157 new Languages('en', $this->conf);
158 $txt = 'car'; // ignore me poedit
159 $this->assertEquals('voiture', t($txt, $txt, 1, 'test'));
160 $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test'));
161 }
162
163 /**
164 * Test t() with an extension language file in PHP mode
165 */
166 public function testTranslationExtensionPhp()
167 {
168 $this->conf->set('translation.mode', 'php');
169 $this->conf->set('translation.extensions.test', 'tests/utils/languages/');
170 new Languages('en', $this->conf);
171 $txt = 'car'; // ignore me poedit
172 $this->assertEquals('voiture', t($txt, $txt, 1, 'test'));
173 $this->assertEquals('Fouille', t('Search', 'Search', 1, 'test'));
174 }
175}
diff --git a/tests/utils/FakeConfigManager.php b/tests/utils/FakeConfigManager.php
new file mode 100644
index 00000000..f29760cb
--- /dev/null
+++ b/tests/utils/FakeConfigManager.php
@@ -0,0 +1,12 @@
1<?php
2
3/**
4 * Fake ConfigManager
5 */
6class FakeConfigManager
7{
8 public static function get($key)
9 {
10 return $key;
11 }
12}
diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php
index f09eebc1..e887aa78 100644
--- a/tests/utils/ReferenceLinkDB.php
+++ b/tests/utils/ReferenceLinkDB.php
@@ -141,6 +141,7 @@ class ReferenceLinkDB
141 */ 141 */
142 public function write($filename) 142 public function write($filename)
143 { 143 {
144 $this->reorder();
144 file_put_contents( 145 file_put_contents(
145 $filename, 146 $filename,
146 '<?php /* '.base64_encode(gzdeflate(serialize($this->_links))).' */ ?>' 147 '<?php /* '.base64_encode(gzdeflate(serialize($this->_links))).' */ ?>'
@@ -148,6 +149,27 @@ class ReferenceLinkDB
148 } 149 }
149 150
150 /** 151 /**
152 * Reorder links by creation date (newest first).
153 *
154 * Also update the urls and ids mapping arrays.
155 *
156 * @param string $order ASC|DESC
157 */
158 public function reorder($order = 'DESC')
159 {
160 // backward compatibility: ignore reorder if the the `created` field doesn't exist
161 if (! isset(array_values($this->_links)[0]['created'])) {
162 return;
163 }
164
165 $order = $order === 'ASC' ? -1 : 1;
166 // Reorder array by dates.
167 usort($this->_links, function($a, $b) use ($order) {
168 return $a['created'] < $b['created'] ? 1 * $order : -1 * $order;
169 });
170 }
171
172 /**
151 * Returns the number of links in the reference data 173 * Returns the number of links in the reference data
152 */ 174 */
153 public function countLinks() 175 public function countLinks()
@@ -187,6 +209,7 @@ class ReferenceLinkDB
187 209
188 public function getLinks() 210 public function getLinks()
189 { 211 {
212 $this->reorder();
190 return $this->_links; 213 return $this->_links;
191 } 214 }
192 215
diff --git a/tests/utils/languages/fr/LC_MESSAGES/test.mo b/tests/utils/languages/fr/LC_MESSAGES/test.mo
new file mode 100644
index 00000000..416c7831
--- /dev/null
+++ b/tests/utils/languages/fr/LC_MESSAGES/test.mo
Binary files differ
diff --git a/tests/utils/languages/fr/LC_MESSAGES/test.po b/tests/utils/languages/fr/LC_MESSAGES/test.po
new file mode 100644
index 00000000..89a4fd9b
--- /dev/null
+++ b/tests/utils/languages/fr/LC_MESSAGES/test.po
@@ -0,0 +1,19 @@
1msgid ""
2msgstr ""
3"Project-Id-Version: Extension test\n"
4"POT-Creation-Date: 2017-05-20 13:54+0200\n"
5"PO-Revision-Date: 2017-05-20 14:16+0200\n"
6"Last-Translator: \n"
7"Language-Team: Shaarli\n"
8"Language: fr_FR\n"
9"MIME-Version: 1.0\n"
10"Content-Type: text/plain; charset=UTF-8\n"
11"Content-Transfer-Encoding: 8bit\n"
12"Plural-Forms: nplurals=2; plural=(n > 1);\n"
13"X-Generator: Poedit 2.0.1\n"
14
15msgid "car"
16msgstr "voiture"
17
18msgid "Search"
19msgstr "Fouille"