aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.htaccess15
-rw-r--r--tests/ApplicationUtilsTest.php57
-rw-r--r--tests/CacheTest.php3
-rw-r--r--tests/ConfigTest.php244
-rw-r--r--tests/FeedBuilderTest.php77
-rw-r--r--tests/HttpUtils/GetIpAdressFromProxyTest.php58
-rw-r--r--tests/LanguagesTest.php41
-rw-r--r--tests/LinkDBTest.php59
-rw-r--r--tests/LinkFilterTest.php32
-rw-r--r--tests/LinkUtilsTest.php88
-rw-r--r--tests/NetscapeBookmarkUtils/BookmarkExportTest.php (renamed from tests/NetscapeBookmarkUtilsTest.php)10
-rw-r--r--tests/NetscapeBookmarkUtils/BookmarkImportTest.php590
-rw-r--r--tests/NetscapeBookmarkUtils/input/empty.htm0
-rw-r--r--tests/NetscapeBookmarkUtils/input/internet_explorer_encoding.htm9
-rw-r--r--tests/NetscapeBookmarkUtils/input/netscape_basic.htm11
-rw-r--r--tests/NetscapeBookmarkUtils/input/netscape_nested.htm31
-rw-r--r--tests/NetscapeBookmarkUtils/input/no_doctype.htm7
-rw-r--r--tests/NetscapeBookmarkUtils/input/same_date.htm11
-rw-r--r--tests/PluginManagerTest.php46
-rw-r--r--tests/Updater/DummyUpdater.php12
-rw-r--r--tests/Updater/UpdaterTest.php347
-rw-r--r--tests/Url/UrlTest.php5
-rw-r--r--tests/UtilsTest.php37
-rw-r--r--tests/config/ConfigJsonTest.php133
-rw-r--r--tests/config/ConfigManagerTest.php172
-rw-r--r--tests/config/ConfigPhpTest.php82
-rw-r--r--tests/config/ConfigPluginTest.php121
-rw-r--r--tests/plugins/PluginArchiveorgTest.php102
-rw-r--r--tests/plugins/PluginIssoTest.php151
-rw-r--r--tests/plugins/PluginMarkdownTest.php99
-rw-r--r--tests/plugins/PluginReadityourselfTest.php31
-rw-r--r--tests/plugins/PluginWallabagTest.php29
-rw-r--r--tests/plugins/resources/markdown.html24
-rw-r--r--tests/plugins/resources/markdown.md24
-rw-r--r--tests/plugins/test/test.meta4
-rw-r--r--tests/utils/ReferenceLinkDB.php77
-rw-r--r--tests/utils/config/configInvalid.json.php5
-rw-r--r--tests/utils/config/configJson.json.php34
-rw-r--r--tests/utils/config/configPhp.php14
39 files changed, 2409 insertions, 483 deletions
diff --git a/tests/.htaccess b/tests/.htaccess
index b584d98c..f601c1ee 100644
--- a/tests/.htaccess
+++ b/tests/.htaccess
@@ -1,2 +1,13 @@
1Allow from none 1<IfModule version_module>
2Deny from all 2 <IfVersion >= 2.4>
3 Require all denied
4 </IfVersion>
5 <IfVersion < 2.4>
6 Allow from none
7 Deny from all
8 </IfVersion>
9</IfModule>
10
11<IfModule !version_module>
12 Require all denied
13</IfModule>
diff --git a/tests/ApplicationUtilsTest.php b/tests/ApplicationUtilsTest.php
index 6064357d..861b8d4e 100644
--- a/tests/ApplicationUtilsTest.php
+++ b/tests/ApplicationUtilsTest.php
@@ -3,6 +3,7 @@
3 * ApplicationUtils' tests 3 * ApplicationUtils' tests
4 */ 4 */
5 5
6require_once 'application/config/ConfigManager.php';
6require_once 'application/ApplicationUtils.php'; 7require_once 'application/ApplicationUtils.php';
7 8
8/** 9/**
@@ -59,7 +60,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase
59 $testTimeout 60 $testTimeout
60 ) 61 )
61 ); 62 );
62 $this->assertRegexp( 63 $this->assertRegExp(
63 self::$versionPattern, 64 self::$versionPattern,
64 ApplicationUtils::getLatestGitVersionCode( 65 ApplicationUtils::getLatestGitVersionCode(
65 'https://raw.githubusercontent.com/shaarli/Shaarli/' 66 'https://raw.githubusercontent.com/shaarli/Shaarli/'
@@ -74,9 +75,12 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase
74 */ 75 */
75 public function testGetLatestGitVersionCodeInvalidUrl() 76 public function testGetLatestGitVersionCodeInvalidUrl()
76 { 77 {
78 $oldlog = ini_get('error_log');
79 ini_set('error_log', '/dev/null');
77 $this->assertFalse( 80 $this->assertFalse(
78 ApplicationUtils::getLatestGitVersionCode('htttp://null.io', 1) 81 ApplicationUtils::getLatestGitVersionCode('htttp://null.io', 1)
79 ); 82 );
83 ini_set('error_log', $oldlog);
80 } 84 }
81 85
82 /** 86 /**
@@ -275,21 +279,21 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase
275 */ 279 */
276 public function testCheckCurrentResourcePermissions() 280 public function testCheckCurrentResourcePermissions()
277 { 281 {
278 $config = array( 282 $conf = new ConfigManager('');
279 'CACHEDIR' => 'cache', 283 $conf->set('resource.thumbnails_cache', 'cache');
280 'CONFIG_FILE' => 'data/config.php', 284 $conf->set('resource.config', 'data/config.php');
281 'DATADIR' => 'data', 285 $conf->set('resource.data_dir', 'data');
282 'DATASTORE' => 'data/datastore.php', 286 $conf->set('resource.datastore', 'data/datastore.php');
283 'IPBANS_FILENAME' => 'data/ipbans.php', 287 $conf->set('resource.ban_file', 'data/ipbans.php');
284 'LOG_FILE' => 'data/log.txt', 288 $conf->set('resource.log', 'data/log.txt');
285 'PAGECACHE' => 'pagecache', 289 $conf->set('resource.page_cache', 'pagecache');
286 'RAINTPL_TMP' => 'tmp', 290 $conf->set('resource.raintpl_tmp', 'tmp');
287 'RAINTPL_TPL' => 'tpl', 291 $conf->set('resource.raintpl_tpl', 'tpl');
288 'UPDATECHECK_FILENAME' => 'data/lastupdatecheck.txt' 292 $conf->set('resource.update_check', 'data/lastupdatecheck.txt');
289 ); 293
290 $this->assertEquals( 294 $this->assertEquals(
291 array(), 295 array(),
292 ApplicationUtils::checkResourcePermissions($config) 296 ApplicationUtils::checkResourcePermissions($conf)
293 ); 297 );
294 } 298 }
295 299
@@ -298,18 +302,17 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase
298 */ 302 */
299 public function testCheckCurrentResourcePermissionsErrors() 303 public function testCheckCurrentResourcePermissionsErrors()
300 { 304 {
301 $config = array( 305 $conf = new ConfigManager('');
302 'CACHEDIR' => 'null/cache', 306 $conf->set('resource.thumbnails_cache', 'null/cache');
303 'CONFIG_FILE' => 'null/data/config.php', 307 $conf->set('resource.config', 'null/data/config.php');
304 'DATADIR' => 'null/data', 308 $conf->set('resource.data_dir', 'null/data');
305 'DATASTORE' => 'null/data/store.php', 309 $conf->set('resource.datastore', 'null/data/store.php');
306 'IPBANS_FILENAME' => 'null/data/ipbans.php', 310 $conf->set('resource.ban_file', 'null/data/ipbans.php');
307 'LOG_FILE' => 'null/data/log.txt', 311 $conf->set('resource.log', 'null/data/log.txt');
308 'PAGECACHE' => 'null/pagecache', 312 $conf->set('resource.page_cache', 'null/pagecache');
309 'RAINTPL_TMP' => 'null/tmp', 313 $conf->set('resource.raintpl_tmp', 'null/tmp');
310 'RAINTPL_TPL' => 'null/tpl', 314 $conf->set('resource.raintpl_tpl', 'null/tpl');
311 'UPDATECHECK_FILENAME' => 'null/data/lastupdatecheck.txt' 315 $conf->set('resource.update_check', 'null/data/lastupdatecheck.txt');
312 );
313 $this->assertEquals( 316 $this->assertEquals(
314 array( 317 array(
315 '"null/tpl" directory is not readable', 318 '"null/tpl" directory is not readable',
@@ -322,7 +325,7 @@ class ApplicationUtilsTest extends PHPUnit_Framework_TestCase
322 '"null/tmp" directory is not readable', 325 '"null/tmp" directory is not readable',
323 '"null/tmp" directory is not writable' 326 '"null/tmp" directory is not writable'
324 ), 327 ),
325 ApplicationUtils::checkResourcePermissions($config) 328 ApplicationUtils::checkResourcePermissions($conf)
326 ); 329 );
327 } 330 }
328} 331}
diff --git a/tests/CacheTest.php b/tests/CacheTest.php
index 26c43225..992e26a5 100644
--- a/tests/CacheTest.php
+++ b/tests/CacheTest.php
@@ -64,10 +64,13 @@ class CacheTest extends PHPUnit_Framework_TestCase
64 */ 64 */
65 public function testPurgeCachedPagesMissingDir() 65 public function testPurgeCachedPagesMissingDir()
66 { 66 {
67 $oldlog = ini_get('error_log');
68 ini_set('error_log', '/dev/null');
67 $this->assertEquals( 69 $this->assertEquals(
68 'Cannot purge sandbox/dummycache_missing: no directory', 70 'Cannot purge sandbox/dummycache_missing: no directory',
69 purgeCachedPages(self::$testCacheDir.'_missing') 71 purgeCachedPages(self::$testCacheDir.'_missing')
70 ); 72 );
73 ini_set('error_log', $oldlog);
71 } 74 }
72 75
73 /** 76 /**
diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php
deleted file mode 100644
index 7200aae6..00000000
--- a/tests/ConfigTest.php
+++ /dev/null
@@ -1,244 +0,0 @@
1<?php
2/**
3 * Config' tests
4 */
5
6require_once 'application/Config.php';
7
8/**
9 * Unitary tests for Shaarli config related functions
10 */
11class ConfigTest extends PHPUnit_Framework_TestCase
12{
13 // Configuration input set.
14 private static $configFields;
15
16 /**
17 * Executed before each test.
18 */
19 public function setUp()
20 {
21 self::$configFields = array(
22 'login' => 'login',
23 'hash' => 'hash',
24 'salt' => 'salt',
25 'timezone' => 'Europe/Paris',
26 'title' => 'title',
27 'titleLink' => 'titleLink',
28 'redirector' => '',
29 'disablesessionprotection' => false,
30 'privateLinkByDefault' => false,
31 'config' => array(
32 'CONFIG_FILE' => 'tests/config.php',
33 'DATADIR' => 'tests',
34 'config1' => 'config1data',
35 'config2' => 'config2data',
36 )
37 );
38 }
39
40 /**
41 * Executed after each test.
42 *
43 * @return void
44 */
45 public function tearDown()
46 {
47 if (is_file(self::$configFields['config']['CONFIG_FILE'])) {
48 unlink(self::$configFields['config']['CONFIG_FILE']);
49 }
50 }
51
52 /**
53 * Test writeConfig function, valid use case, while being logged in.
54 */
55 public function testWriteConfig()
56 {
57 writeConfig(self::$configFields, true);
58
59 include self::$configFields['config']['CONFIG_FILE'];
60 $this->assertEquals(self::$configFields['login'], $GLOBALS['login']);
61 $this->assertEquals(self::$configFields['hash'], $GLOBALS['hash']);
62 $this->assertEquals(self::$configFields['salt'], $GLOBALS['salt']);
63 $this->assertEquals(self::$configFields['timezone'], $GLOBALS['timezone']);
64 $this->assertEquals(self::$configFields['title'], $GLOBALS['title']);
65 $this->assertEquals(self::$configFields['titleLink'], $GLOBALS['titleLink']);
66 $this->assertEquals(self::$configFields['redirector'], $GLOBALS['redirector']);
67 $this->assertEquals(self::$configFields['disablesessionprotection'], $GLOBALS['disablesessionprotection']);
68 $this->assertEquals(self::$configFields['privateLinkByDefault'], $GLOBALS['privateLinkByDefault']);
69 $this->assertEquals(self::$configFields['config']['config1'], $GLOBALS['config']['config1']);
70 $this->assertEquals(self::$configFields['config']['config2'], $GLOBALS['config']['config2']);
71 }
72
73 /**
74 * Test writeConfig option while logged in:
75 * 1. init fields.
76 * 2. update fields, add new sub config, add new root config.
77 * 3. rewrite config.
78 * 4. check result.
79 */
80 public function testWriteConfigFieldUpdate()
81 {
82 writeConfig(self::$configFields, true);
83 self::$configFields['title'] = 'ok';
84 self::$configFields['config']['config1'] = 'ok';
85 self::$configFields['config']['config_new'] = 'ok';
86 self::$configFields['new'] = 'should not be saved';
87 writeConfig(self::$configFields, true);
88
89 include self::$configFields['config']['CONFIG_FILE'];
90 $this->assertEquals('ok', $GLOBALS['title']);
91 $this->assertEquals('ok', $GLOBALS['config']['config1']);
92 $this->assertEquals('ok', $GLOBALS['config']['config_new']);
93 $this->assertFalse(isset($GLOBALS['new']));
94 }
95
96 /**
97 * Test writeConfig function with an empty array.
98 *
99 * @expectedException MissingFieldConfigException
100 */
101 public function testWriteConfigEmpty()
102 {
103 writeConfig(array(), true);
104 }
105
106 /**
107 * Test writeConfig function with a missing mandatory field.
108 *
109 * @expectedException MissingFieldConfigException
110 */
111 public function testWriteConfigMissingField()
112 {
113 unset(self::$configFields['login']);
114 writeConfig(self::$configFields, true);
115 }
116
117 /**
118 * Test writeConfig function while being logged out, and there is no config file existing.
119 */
120 public function testWriteConfigLoggedOutNoFile()
121 {
122 writeConfig(self::$configFields, false);
123 }
124
125 /**
126 * Test writeConfig function while being logged out, and a config file already exists.
127 *
128 * @expectedException UnauthorizedConfigException
129 */
130 public function testWriteConfigLoggedOutWithFile()
131 {
132 file_put_contents(self::$configFields['config']['CONFIG_FILE'], '');
133 writeConfig(self::$configFields, false);
134 }
135
136 /**
137 * Test save_plugin_config with valid data.
138 *
139 * @throws PluginConfigOrderException
140 */
141 public function testSavePluginConfigValid()
142 {
143 $data = array(
144 'order_plugin1' => 2, // no plugin related
145 'plugin2' => 0, // new - at the end
146 'plugin3' => 0, // 2nd
147 'order_plugin3' => 8,
148 'plugin4' => 0, // 1st
149 'order_plugin4' => 5,
150 );
151
152 $expected = array(
153 'plugin3',
154 'plugin4',
155 'plugin2',
156 );
157
158 $out = save_plugin_config($data);
159 $this->assertEquals($expected, $out);
160 }
161
162 /**
163 * Test save_plugin_config with invalid data.
164 *
165 * @expectedException PluginConfigOrderException
166 */
167 public function testSavePluginConfigInvalid()
168 {
169 $data = array(
170 'plugin2' => 0,
171 'plugin3' => 0,
172 'order_plugin3' => 0,
173 'plugin4' => 0,
174 'order_plugin4' => 0,
175 );
176
177 save_plugin_config($data);
178 }
179
180 /**
181 * Test save_plugin_config without data.
182 */
183 public function testSavePluginConfigEmpty()
184 {
185 $this->assertEquals(array(), save_plugin_config(array()));
186 }
187
188 /**
189 * Test validate_plugin_order with valid data.
190 */
191 public function testValidatePluginOrderValid()
192 {
193 $data = array(
194 'order_plugin1' => 2,
195 'plugin2' => 0,
196 'plugin3' => 0,
197 'order_plugin3' => 1,
198 'plugin4' => 0,
199 'order_plugin4' => 5,
200 );
201
202 $this->assertTrue(validate_plugin_order($data));
203 }
204
205 /**
206 * Test validate_plugin_order with invalid data.
207 */
208 public function testValidatePluginOrderInvalid()
209 {
210 $data = array(
211 'order_plugin1' => 2,
212 'order_plugin3' => 1,
213 'order_plugin4' => 1,
214 );
215
216 $this->assertFalse(validate_plugin_order($data));
217 }
218
219 /**
220 * Test load_plugin_parameter_values.
221 */
222 public function testLoadPluginParameterValues()
223 {
224 $plugins = array(
225 'plugin_name' => array(
226 'parameters' => array(
227 'param1' => true,
228 'param2' => false,
229 'param3' => '',
230 )
231 )
232 );
233
234 $parameters = array(
235 'param1' => 'value1',
236 'param2' => 'value2',
237 );
238
239 $result = load_plugin_parameter_values($plugins, $parameters);
240 $this->assertEquals('value1', $result['plugin_name']['parameters']['param1']);
241 $this->assertEquals('value2', $result['plugin_name']['parameters']['param2']);
242 $this->assertEquals('', $result['plugin_name']['parameters']['param3']);
243 }
244}
diff --git a/tests/FeedBuilderTest.php b/tests/FeedBuilderTest.php
index 069b1581..06a44506 100644
--- a/tests/FeedBuilderTest.php
+++ b/tests/FeedBuilderTest.php
@@ -76,7 +76,7 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase
76 // Test headers (RSS) 76 // Test headers (RSS)
77 $this->assertEquals(self::$RSS_LANGUAGE, $data['language']); 77 $this->assertEquals(self::$RSS_LANGUAGE, $data['language']);
78 $this->assertEmpty($data['pubsubhub_url']); 78 $this->assertEmpty($data['pubsubhub_url']);
79 $this->assertEquals('Tue, 10 Mar 2015 11:46:51 +0100', $data['last_update']); 79 $this->assertRegExp('/Wed, 03 Aug 2016 09:30:33 \+\d{4}/', $data['last_update']);
80 $this->assertEquals(true, $data['show_dates']); 80 $this->assertEquals(true, $data['show_dates']);
81 $this->assertEquals('http://host.tld/index.php?do=feed', $data['self_link']); 81 $this->assertEquals('http://host.tld/index.php?do=feed', $data['self_link']);
82 $this->assertEquals('http://host.tld/', $data['index_url']); 82 $this->assertEquals('http://host.tld/', $data['index_url']);
@@ -84,23 +84,30 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase
84 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); 84 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
85 85
86 // Test first link (note link) 86 // Test first link (note link)
87 $link = array_shift($data['links']); 87 $link = reset($data['links']);
88 $this->assertEquals('20150310_114651', $link['linkdate']); 88 $this->assertEquals(41, $link['id']);
89 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
89 $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); 90 $this->assertEquals('http://host.tld/?WDWyig', $link['guid']);
90 $this->assertEquals('http://host.tld/?WDWyig', $link['url']); 91 $this->assertEquals('http://host.tld/?WDWyig', $link['url']);
91 $this->assertEquals('Tue, 10 Mar 2015 11:46:51 +0100', $link['iso_date']); 92 $this->assertRegExp('/Tue, 10 Mar 2015 11:46:51 \+\d{4}/', $link['pub_iso_date']);
93 $pub = DateTime::createFromFormat(DateTime::RSS, $link['pub_iso_date']);
94 $up = DateTime::createFromFormat(DateTime::ATOM, $link['up_iso_date']);
95 $this->assertEquals($pub, $up);
92 $this->assertContains('Stallman has a beard', $link['description']); 96 $this->assertContains('Stallman has a beard', $link['description']);
93 $this->assertContains('Permalink', $link['description']); 97 $this->assertContains('Permalink', $link['description']);
94 $this->assertContains('http://host.tld/?WDWyig', $link['description']); 98 $this->assertContains('http://host.tld/?WDWyig', $link['description']);
95 $this->assertEquals(1, count($link['taglist'])); 99 $this->assertEquals(1, count($link['taglist']));
96 $this->assertEquals('stuff', $link['taglist'][0]); 100 $this->assertEquals('sTuff', $link['taglist'][0]);
97 101
98 // Test URL with external link. 102 // Test URL with external link.
99 $this->assertEquals('https://static.fsf.org/nosvn/faif-2.0.pdf', $data['links']['20150310_114633']['url']); 103 $this->assertEquals('https://static.fsf.org/nosvn/faif-2.0.pdf', $data['links'][8]['url']);
100 104
101 // Test multitags. 105 // Test multitags.
102 $this->assertEquals(5, count($data['links']['20141125_084734']['taglist'])); 106 $this->assertEquals(5, count($data['links'][6]['taglist']));
103 $this->assertEquals('css', $data['links']['20141125_084734']['taglist'][0]); 107 $this->assertEquals('css', $data['links'][6]['taglist'][0]);
108
109 // Test update date
110 $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']);
104 } 111 }
105 112
106 /** 113 /**
@@ -112,8 +119,10 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase
112 $feedBuilder->setLocale(self::$LOCALE); 119 $feedBuilder->setLocale(self::$LOCALE);
113 $data = $feedBuilder->buildData(); 120 $data = $feedBuilder->buildData();
114 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); 121 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
115 $link = array_shift($data['links']); 122 $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']);
116 $this->assertEquals('2015-03-10T11:46:51+01:00', $link['iso_date']); 123 $link = reset($data['links']);
124 $this->assertRegExp('/2015-03-10T11:46:51\+\d{2}:\d{2}/', $link['pub_iso_date']);
125 $this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['links'][8]['up_iso_date']);
117 } 126 }
118 127
119 /** 128 /**
@@ -130,7 +139,8 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase
130 $data = $feedBuilder->buildData(); 139 $data = $feedBuilder->buildData();
131 $this->assertEquals(1, count($data['links'])); 140 $this->assertEquals(1, count($data['links']));
132 $link = array_shift($data['links']); 141 $link = array_shift($data['links']);
133 $this->assertEquals('20150310_114651', $link['linkdate']); 142 $this->assertEquals(41, $link['id']);
143 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
134 } 144 }
135 145
136 /** 146 /**
@@ -146,7 +156,8 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase
146 $data = $feedBuilder->buildData(); 156 $data = $feedBuilder->buildData();
147 $this->assertEquals(1, count($data['links'])); 157 $this->assertEquals(1, count($data['links']));
148 $link = array_shift($data['links']); 158 $link = array_shift($data['links']);
149 $this->assertEquals('20150310_114651', $link['linkdate']); 159 $this->assertEquals(41, $link['id']);
160 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
150 } 161 }
151 162
152 /** 163 /**
@@ -162,15 +173,17 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase
162 $this->assertTrue($data['usepermalinks']); 173 $this->assertTrue($data['usepermalinks']);
163 // First link is a permalink 174 // First link is a permalink
164 $link = array_shift($data['links']); 175 $link = array_shift($data['links']);
165 $this->assertEquals('20150310_114651', $link['linkdate']); 176 $this->assertEquals(41, $link['id']);
177 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'), $link['created']);
166 $this->assertEquals('http://host.tld/?WDWyig', $link['guid']); 178 $this->assertEquals('http://host.tld/?WDWyig', $link['guid']);
167 $this->assertEquals('http://host.tld/?WDWyig', $link['url']); 179 $this->assertEquals('http://host.tld/?WDWyig', $link['url']);
168 $this->assertContains('Direct link', $link['description']); 180 $this->assertContains('Direct link', $link['description']);
169 $this->assertContains('http://host.tld/?WDWyig', $link['description']); 181 $this->assertContains('http://host.tld/?WDWyig', $link['description']);
170 // Second link is a direct link 182 // Second link is a direct link
171 $link = array_shift($data['links']); 183 $link = array_shift($data['links']);
172 $this->assertEquals('20150310_114633', $link['linkdate']); 184 $this->assertEquals(8, $link['id']);
173 $this->assertEquals('http://host.tld/?kLHmZg', $link['guid']); 185 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'), $link['created']);
186 $this->assertEquals('http://host.tld/?RttfEw', $link['guid']);
174 $this->assertEquals('https://static.fsf.org/nosvn/faif-2.0.pdf', $link['url']); 187 $this->assertEquals('https://static.fsf.org/nosvn/faif-2.0.pdf', $link['url']);
175 $this->assertContains('Direct link', $link['description']); 188 $this->assertContains('Direct link', $link['description']);
176 $this->assertContains('https://static.fsf.org/nosvn/faif-2.0.pdf', $link['description']); 189 $this->assertContains('https://static.fsf.org/nosvn/faif-2.0.pdf', $link['description']);
@@ -209,4 +222,38 @@ class FeedBuilderTest extends PHPUnit_Framework_TestCase
209 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links'])); 222 $this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
210 $this->assertEquals('http://pubsubhub.io', $data['pubsubhub_url']); 223 $this->assertEquals('http://pubsubhub.io', $data['pubsubhub_url']);
211 } 224 }
225
226 /**
227 * Test buildData when Shaarli is served from a subdirectory
228 */
229 public function testBuildDataServerSubdir()
230 {
231 $serverInfo = array(
232 'HTTPS' => 'Off',
233 'SERVER_NAME' => 'host.tld',
234 'SERVER_PORT' => '8080',
235 'SCRIPT_NAME' => '/~user/shaarli/index.php',
236 'REQUEST_URI' => '/~user/shaarli/index.php?do=feed',
237 );
238 $feedBuilder = new FeedBuilder(
239 self::$linkDB,
240 FeedBuilder::$FEED_ATOM,
241 $serverInfo,
242 null,
243 false
244 );
245 $feedBuilder->setLocale(self::$LOCALE);
246 $data = $feedBuilder->buildData();
247
248 $this->assertEquals(
249 'http://host.tld:8080/~user/shaarli/index.php?do=feed',
250 $data['self_link']
251 );
252
253 // Test first link (note link)
254 $link = array_shift($data['links']);
255 $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['guid']);
256 $this->assertEquals('http://host.tld:8080/~user/shaarli/?WDWyig', $link['url']);
257 $this->assertContains('http://host.tld:8080/~user/shaarli/?addtag=hashtag', $link['description']);
258 }
212} 259}
diff --git a/tests/HttpUtils/GetIpAdressFromProxyTest.php b/tests/HttpUtils/GetIpAdressFromProxyTest.php
new file mode 100644
index 00000000..6a74a45a
--- /dev/null
+++ b/tests/HttpUtils/GetIpAdressFromProxyTest.php
@@ -0,0 +1,58 @@
1<?php
2
3require_once 'application/HttpUtils.php';
4
5/**
6 * Unitary tests for getIpAddressFromProxy()
7 */
8class GetIpAdressFromProxyTest extends PHPUnit_Framework_TestCase {
9
10 /**
11 * Test without proxy
12 */
13 public function testWithoutProxy()
14 {
15 $this->assertFalse(getIpAddressFromProxy(array(), array()));
16 }
17
18 /**
19 * Test with a single IP in proxy header.
20 */
21 public function testWithOneForwardedIp()
22 {
23 $ip = '1.1.1.1';
24 $server = array('HTTP_X_FORWARDED_FOR' => $ip);
25 $this->assertEquals($ip, getIpAddressFromProxy($server, array()));
26 }
27
28 /**
29 * Test with a multiple IPs in proxy header.
30 */
31 public function testWithMultipleForwardedIp()
32 {
33 $ip = '1.1.1.1';
34 $ip2 = '2.2.2.2';
35
36 $server = array('HTTP_X_FORWARDED_FOR' => $ip .','. $ip2);
37 $this->assertEquals($ip2, getIpAddressFromProxy($server, array()));
38
39 $server = array('HTTP_X_FORWARDED_FOR' => $ip .' , '. $ip2);
40 $this->assertEquals($ip2, getIpAddressFromProxy($server, array()));
41 }
42
43 /**
44 * Test with a trusted IP address.
45 */
46 public function testWithTrustedIp()
47 {
48 $ip = '1.1.1.1';
49 $ip2 = '2.2.2.2';
50
51 $server = array('HTTP_X_FORWARDED_FOR' => $ip);
52 $this->assertFalse(getIpAddressFromProxy($server, array($ip)));
53
54 $server = array('HTTP_X_FORWARDED_FOR' => $ip .','. $ip2);
55 $this->assertEquals($ip2, getIpAddressFromProxy($server, array($ip)));
56 $this->assertFalse(getIpAddressFromProxy($server, array($ip, $ip2)));
57 }
58}
diff --git a/tests/LanguagesTest.php b/tests/LanguagesTest.php
new file mode 100644
index 00000000..79c136c8
--- /dev/null
+++ b/tests/LanguagesTest.php
@@ -0,0 +1,41 @@
1<?php
2
3require_once 'application/Languages.php';
4
5/**
6 * Class LanguagesTest.
7 */
8class LanguagesTest extends PHPUnit_Framework_TestCase
9{
10 /**
11 * Test t() with a simple non identified value.
12 */
13 public function testTranslateSingleNotID()
14 {
15 $text = 'abcdé 564 fgK';
16 $this->assertEquals($text, t($text));
17 }
18
19 /**
20 * Test t() with a non identified plural form.
21 */
22 public function testTranslatePluralNotID()
23 {
24 $text = '%s sandwich';
25 $nText = '%s sandwiches';
26 $this->assertEquals('0 sandwich', t($text, $nText));
27 $this->assertEquals('1 sandwich', t($text, $nText, 1));
28 $this->assertEquals('2 sandwiches', t($text, $nText, 2));
29 }
30
31 /**
32 * Test t() with a non identified invalid plural form.
33 */
34 public function testTranslatePluralNotIDInvalid()
35 {
36 $text = 'sandwich';
37 $nText = 'sandwiches';
38 $this->assertEquals('sandwich', t($text, $nText, 1));
39 $this->assertEquals('sandwiches', t($text, $nText, 2));
40 }
41}
diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php
index b055fe91..1f62a34a 100644
--- a/tests/LinkDBTest.php
+++ b/tests/LinkDBTest.php
@@ -101,7 +101,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
101 * Attempt to instantiate a LinkDB whereas the datastore is not writable 101 * Attempt to instantiate a LinkDB whereas the datastore is not writable
102 * 102 *
103 * @expectedException IOException 103 * @expectedException IOException
104 * @expectedExceptionMessageRegExp /Error accessing null/ 104 * @expectedExceptionMessageRegExp /Error accessing\nnull/
105 */ 105 */
106 public function testConstructDatastoreNotWriteable() 106 public function testConstructDatastoreNotWriteable()
107 { 107 {
@@ -117,7 +117,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
117 unlink(self::$testDatastore); 117 unlink(self::$testDatastore);
118 $this->assertFileNotExists(self::$testDatastore); 118 $this->assertFileNotExists(self::$testDatastore);
119 119
120 $checkDB = self::getMethod('_checkDB'); 120 $checkDB = self::getMethod('check');
121 $checkDB->invokeArgs($linkDB, array()); 121 $checkDB->invokeArgs($linkDB, array());
122 $this->assertFileExists(self::$testDatastore); 122 $this->assertFileExists(self::$testDatastore);
123 123
@@ -134,7 +134,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
134 $datastoreSize = filesize(self::$testDatastore); 134 $datastoreSize = filesize(self::$testDatastore);
135 $this->assertGreaterThan(0, $datastoreSize); 135 $this->assertGreaterThan(0, $datastoreSize);
136 136
137 $checkDB = self::getMethod('_checkDB'); 137 $checkDB = self::getMethod('check');
138 $checkDB->invokeArgs($linkDB, array()); 138 $checkDB->invokeArgs($linkDB, array());
139 139
140 // ensure the datastore is left unmodified 140 // ensure the datastore is left unmodified
@@ -180,21 +180,22 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
180 /** 180 /**
181 * Save the links to the DB 181 * Save the links to the DB
182 */ 182 */
183 public function testSaveDB() 183 public function testSave()
184 { 184 {
185 $testDB = new LinkDB(self::$testDatastore, true, false); 185 $testDB = new LinkDB(self::$testDatastore, true, false);
186 $dbSize = sizeof($testDB); 186 $dbSize = sizeof($testDB);
187 187
188 $link = array( 188 $link = array(
189 'id' => 42,
189 'title'=>'an additional link', 190 'title'=>'an additional link',
190 'url'=>'http://dum.my', 191 'url'=>'http://dum.my',
191 'description'=>'One more', 192 'description'=>'One more',
192 'private'=>0, 193 'private'=>0,
193 'linkdate'=>'20150518_190000', 194 'created'=> DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150518_190000'),
194 'tags'=>'unit test' 195 'tags'=>'unit test'
195 ); 196 );
196 $testDB[$link['linkdate']] = $link; 197 $testDB[$link['id']] = $link;
197 $testDB->savedb('tests'); 198 $testDB->save('tests');
198 199
199 $testDB = new LinkDB(self::$testDatastore, true, false); 200 $testDB = new LinkDB(self::$testDatastore, true, false);
200 $this->assertEquals($dbSize + 1, sizeof($testDB)); 201 $this->assertEquals($dbSize + 1, sizeof($testDB));
@@ -238,12 +239,12 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
238 public function testDays() 239 public function testDays()
239 { 240 {
240 $this->assertEquals( 241 $this->assertEquals(
241 array('20121206', '20130614', '20150310'), 242 array('20100310', '20121206', '20130614', '20150310'),
242 self::$publicLinkDB->days() 243 self::$publicLinkDB->days()
243 ); 244 );
244 245
245 $this->assertEquals( 246 $this->assertEquals(
246 array('20121206', '20130614', '20141125', '20150310'), 247 array('20100310', '20121206', '20130614', '20141125', '20150310'),
247 self::$privateLinkDB->days() 248 self::$privateLinkDB->days()
248 ); 249 );
249 } 250 }
@@ -256,7 +257,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
256 $link = self::$publicLinkDB->getLinkFromUrl('http://mediagoblin.org/'); 257 $link = self::$publicLinkDB->getLinkFromUrl('http://mediagoblin.org/');
257 258
258 $this->assertNotEquals(false, $link); 259 $this->assertNotEquals(false, $link);
259 $this->assertEquals( 260 $this->assertContains(
260 'A free software media publishing platform', 261 'A free software media publishing platform',
261 $link['description'] 262 $link['description']
262 ); 263 );
@@ -290,7 +291,11 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
290 'stallman' => 1, 291 'stallman' => 1,
291 'free' => 1, 292 'free' => 1,
292 '-exclude' => 1, 293 '-exclude' => 1,
293 'stuff' => 2, 294 'hashtag' => 2,
295 // The DB contains a link with `sTuff` and another one with `stuff` tag.
296 // They need to be grouped with the first case found - order by date DESC: `sTuff`.
297 'sTuff' => 2,
298 'ut' => 1,
294 ), 299 ),
295 self::$publicLinkDB->allTags() 300 self::$publicLinkDB->allTags()
296 ); 301 );
@@ -310,9 +315,15 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
310 'w3c' => 1, 315 'w3c' => 1,
311 'css' => 1, 316 'css' => 1,
312 'Mercurial' => 1, 317 'Mercurial' => 1,
313 'stuff' => 2, 318 'sTuff' => 2,
314 '-exclude' => 1, 319 '-exclude' => 1,
315 '.hidden' => 1, 320 '.hidden' => 1,
321 'hashtag' => 2,
322 'tag1' => 1,
323 'tag2' => 1,
324 'tag3' => 1,
325 'tag4' => 1,
326 'ut' => 1,
316 ), 327 ),
317 self::$privateLinkDB->allTags() 328 self::$privateLinkDB->allTags()
318 ); 329 );
@@ -403,6 +414,11 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
403 1, 414 1,
404 count(self::$publicLinkDB->filterHash($request)) 415 count(self::$publicLinkDB->filterHash($request))
405 ); 416 );
417 $request = smallHash('20150310_114633' . 8);
418 $this->assertEquals(
419 1,
420 count(self::$publicLinkDB->filterHash($request))
421 );
406 } 422 }
407 423
408 /** 424 /**
@@ -425,4 +441,23 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
425 { 441 {
426 self::$publicLinkDB->filterHash(''); 442 self::$publicLinkDB->filterHash('');
427 } 443 }
444
445 /**
446 * Test reorder with asc/desc parameter.
447 */
448 public function testReorderLinksDesc()
449 {
450 self::$privateLinkDB->reorder('ASC');
451 $linkIds = array(42, 4, 1, 0, 7, 6, 8, 41);
452 $cpt = 0;
453 foreach (self::$privateLinkDB as $key => $value) {
454 $this->assertEquals($linkIds[$cpt++], $key);
455 }
456 self::$privateLinkDB->reorder('DESC');
457 $linkIds = array_reverse($linkIds);
458 $cpt = 0;
459 foreach (self::$privateLinkDB as $key => $value) {
460 $this->assertEquals($linkIds[$cpt++], $key);
461 }
462 }
428} 463}
diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php
index 1620bb78..21d680a5 100644
--- a/tests/LinkFilterTest.php
+++ b/tests/LinkFilterTest.php
@@ -159,7 +159,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
159 159
160 $this->assertEquals( 160 $this->assertEquals(
161 'MediaGoblin', 161 'MediaGoblin',
162 $links['20130614_184135']['title'] 162 $links[7]['title']
163 ); 163 );
164 } 164 }
165 165
@@ -286,7 +286,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
286 ); 286 );
287 287
288 $this->assertEquals( 288 $this->assertEquals(
289 6, 289 7,
290 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '-revolution')) 290 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '-revolution'))
291 ); 291 );
292 } 292 }
@@ -346,7 +346,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
346 ); 346 );
347 347
348 $this->assertEquals( 348 $this->assertEquals(
349 6, 349 7,
350 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free')) 350 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free'))
351 ); 351 );
352 } 352 }
@@ -387,4 +387,30 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
387 )) 387 ))
388 ); 388 );
389 } 389 }
390
391 /**
392 * Filter links by #hashtag.
393 */
394 public function testFilterByHashtag()
395 {
396 $hashtag = 'hashtag';
397 $this->assertEquals(
398 3,
399 count(self::$linkFilter->filter(
400 LinkFilter::$FILTER_TAG,
401 $hashtag
402 ))
403 );
404
405 $hashtag = 'private';
406 $this->assertEquals(
407 1,
408 count(self::$linkFilter->filter(
409 LinkFilter::$FILTER_TAG,
410 $hashtag,
411 false,
412 true
413 ))
414 );
415 }
390} 416}
diff --git a/tests/LinkUtilsTest.php b/tests/LinkUtilsTest.php
index d1b022fd..7c0d4b0b 100644
--- a/tests/LinkUtilsTest.php
+++ b/tests/LinkUtilsTest.php
@@ -93,4 +93,92 @@ class LinkUtilsTest extends PHPUnit_Framework_TestCase
93 $refDB = new ReferenceLinkDB(); 93 $refDB = new ReferenceLinkDB();
94 $this->assertEquals($refDB->countPrivateLinks(), count_private($refDB->getLinks())); 94 $this->assertEquals($refDB->countPrivateLinks(), count_private($refDB->getLinks()));
95 } 95 }
96
97 /**
98 * Test text2clickable without a redirector being set.
99 */
100 public function testText2clickableWithoutRedirector()
101 {
102 $text = 'stuff http://hello.there/is=someone#here otherstuff';
103 $expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff';
104 $processedText = text2clickable($text, '');
105 $this->assertEquals($expectedText, $processedText);
106 }
107
108 /**
109 * Test text2clickable a redirector set.
110 */
111 public function testText2clickableWithRedirector()
112 {
113 $text = 'stuff http://hello.there/is=someone#here otherstuff';
114 $redirector = 'http://redirector.to';
115 $expectedText = 'stuff <a href="'.
116 $redirector .
117 urlencode('http://hello.there/is=someone#here') .
118 '">http://hello.there/is=someone#here</a> otherstuff';
119 $processedText = text2clickable($text, $redirector);
120 $this->assertEquals($expectedText, $processedText);
121 }
122
123 /**
124 * Test testSpace2nbsp.
125 */
126 public function testSpace2nbsp()
127 {
128 $text = ' Are you thrilled by flags ?'. PHP_EOL .' Really?';
129 $expectedText = '&nbsp; Are you &nbsp; thrilled &nbsp;by flags &nbsp; ?'. PHP_EOL .'&nbsp;Really?';
130 $processedText = space2nbsp($text);
131 $this->assertEquals($expectedText, $processedText);
132 }
133
134 /**
135 * Test hashtags auto-link.
136 */
137 public function testHashtagAutolink()
138 {
139 $index = 'http://domain.tld/';
140 $rawDescription = '#hashtag\n
141 # nothashtag\n
142 test#nothashtag #hashtag \#nothashtag\n
143 test #hashtag #hashtag test #hashtag.test\n
144 #hashtag #hashtag-nothashtag #hashtag_hashtag\n
145 What is #ашок anyway?\n
146 カタカナ #カタカナ」カタカナ\n';
147 $autolinkedDescription = hashtag_autolink($rawDescription, $index);
148
149 $this->assertContains($this->getHashtagLink('hashtag', $index), $autolinkedDescription);
150 $this->assertNotContains(' #hashtag', $autolinkedDescription);
151 $this->assertNotContains('>#nothashtag', $autolinkedDescription);
152 $this->assertContains($this->getHashtagLink('ашок', $index), $autolinkedDescription);
153 $this->assertContains($this->getHashtagLink('カタカナ', $index), $autolinkedDescription);
154 $this->assertContains($this->getHashtagLink('hashtag_hashtag', $index), $autolinkedDescription);
155 $this->assertNotContains($this->getHashtagLink('hashtag-nothashtag', $index), $autolinkedDescription);
156 }
157
158 /**
159 * Test hashtags auto-link without index URL.
160 */
161 public function testHashtagAutolinkNoIndex()
162 {
163 $rawDescription = 'blabla #hashtag x#nothashtag';
164 $autolinkedDescription = hashtag_autolink($rawDescription);
165
166 $this->assertContains($this->getHashtagLink('hashtag'), $autolinkedDescription);
167 $this->assertNotContains(' #hashtag', $autolinkedDescription);
168 $this->assertNotContains('>#nothashtag', $autolinkedDescription);
169 }
170
171 /**
172 * Util function to build an hashtag link.
173 *
174 * @param string $hashtag Hashtag name.
175 * @param string $index Index URL.
176 *
177 * @return string HTML hashtag link.
178 */
179 private function getHashtagLink($hashtag, $index = '')
180 {
181 $hashtagLink = '<a href="'. $index .'?addtag=$1" title="Hashtag $1">#$1</a>';
182 return str_replace('$1', $hashtag, $hashtagLink);
183 }
96} 184}
diff --git a/tests/NetscapeBookmarkUtilsTest.php b/tests/NetscapeBookmarkUtils/BookmarkExportTest.php
index 41e6d84c..6a47bbb9 100644
--- a/tests/NetscapeBookmarkUtilsTest.php
+++ b/tests/NetscapeBookmarkUtils/BookmarkExportTest.php
@@ -3,9 +3,9 @@
3require_once 'application/NetscapeBookmarkUtils.php'; 3require_once 'application/NetscapeBookmarkUtils.php';
4 4
5/** 5/**
6 * Netscape bookmark import and export 6 * Netscape bookmark export
7 */ 7 */
8class NetscapeBookmarkUtilsTest extends PHPUnit_Framework_TestCase 8class BookmarkExportTest extends PHPUnit_Framework_TestCase
9{ 9{
10 /** 10 /**
11 * @var string datastore to test write operations 11 * @var string datastore to test write operations
@@ -50,7 +50,7 @@ class NetscapeBookmarkUtilsTest extends PHPUnit_Framework_TestCase
50 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'all', false, ''); 50 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'all', false, '');
51 $this->assertEquals(self::$refDb->countLinks(), sizeof($links)); 51 $this->assertEquals(self::$refDb->countLinks(), sizeof($links));
52 foreach ($links as $link) { 52 foreach ($links as $link) {
53 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); 53 $date = $link['created'];
54 $this->assertEquals( 54 $this->assertEquals(
55 $date->getTimestamp(), 55 $date->getTimestamp(),
56 $link['timestamp'] 56 $link['timestamp']
@@ -70,7 +70,7 @@ class NetscapeBookmarkUtilsTest extends PHPUnit_Framework_TestCase
70 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'private', false, ''); 70 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'private', false, '');
71 $this->assertEquals(self::$refDb->countPrivateLinks(), sizeof($links)); 71 $this->assertEquals(self::$refDb->countPrivateLinks(), sizeof($links));
72 foreach ($links as $link) { 72 foreach ($links as $link) {
73 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); 73 $date = $link['created'];
74 $this->assertEquals( 74 $this->assertEquals(
75 $date->getTimestamp(), 75 $date->getTimestamp(),
76 $link['timestamp'] 76 $link['timestamp']
@@ -90,7 +90,7 @@ class NetscapeBookmarkUtilsTest extends PHPUnit_Framework_TestCase
90 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, ''); 90 $links = NetscapeBookmarkUtils::filterAndFormat(self::$linkDb, 'public', false, '');
91 $this->assertEquals(self::$refDb->countPublicLinks(), sizeof($links)); 91 $this->assertEquals(self::$refDb->countPublicLinks(), sizeof($links));
92 foreach ($links as $link) { 92 foreach ($links as $link) {
93 $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); 93 $date = $link['created'];
94 $this->assertEquals( 94 $this->assertEquals(
95 $date->getTimestamp(), 95 $date->getTimestamp(),
96 $link['timestamp'] 96 $link['timestamp']
diff --git a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
new file mode 100644
index 00000000..0ca07eac
--- /dev/null
+++ b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
@@ -0,0 +1,590 @@
1<?php
2
3require_once 'application/NetscapeBookmarkUtils.php';
4
5
6/**
7 * Utility function to load a file's metadata in a $_FILES-like array
8 *
9 * @param string $filename Basename of the file
10 *
11 * @return array A $_FILES-like array
12 */
13function file2array($filename)
14{
15 return array(
16 'filetoupload' => array(
17 'name' => $filename,
18 'tmp_name' => __DIR__ . '/input/' . $filename,
19 'size' => filesize(__DIR__ . '/input/' . $filename)
20 )
21 );
22}
23
24
25/**
26 * Netscape bookmark import
27 */
28class BookmarkImportTest extends PHPUnit_Framework_TestCase
29{
30 /**
31 * @var string datastore to test write operations
32 */
33 protected static $testDatastore = 'sandbox/datastore.php';
34
35 /**
36 * @var LinkDB private LinkDB instance
37 */
38 protected $linkDb = null;
39
40 /**
41 * @var string Dummy page cache
42 */
43 protected $pagecache = 'tests';
44
45 /**
46 * @var string Save the current timezone.
47 */
48 protected static $defaultTimeZone;
49
50 public static function setUpBeforeClass()
51 {
52 self::$defaultTimeZone = date_default_timezone_get();
53 // Timezone without DST for test consistency
54 date_default_timezone_set('Africa/Nairobi');
55 }
56
57 /**
58 * Resets test data before each test
59 */
60 protected function setUp()
61 {
62 if (file_exists(self::$testDatastore)) {
63 unlink(self::$testDatastore);
64 }
65 // start with an empty datastore
66 file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>');
67 $this->linkDb = new LinkDB(self::$testDatastore, true, false);
68 }
69
70 public static function tearDownAfterClass()
71 {
72 date_default_timezone_set(self::$defaultTimeZone);
73 }
74
75 /**
76 * Attempt to import bookmarks from an empty file
77 */
78 public function testImportEmptyData()
79 {
80 $files = file2array('empty.htm');
81 $this->assertEquals(
82 'File empty.htm (0 bytes) has an unknown file format.'
83 .' Nothing was imported.',
84 NetscapeBookmarkUtils::import(NULL, $files, NULL, NULL)
85 );
86 $this->assertEquals(0, count($this->linkDb));
87 }
88
89 /**
90 * Attempt to import bookmarks from a file with no Doctype
91 */
92 public function testImportNoDoctype()
93 {
94 $files = file2array('no_doctype.htm');
95 $this->assertEquals(
96 'File no_doctype.htm (350 bytes) has an unknown file format. Nothing was imported.',
97 NetscapeBookmarkUtils::import(NULL, $files, NULL, NULL)
98 );
99 $this->assertEquals(0, count($this->linkDb));
100 }
101
102 /**
103 * Ensure IE dumps are supported
104 */
105 public function testImportInternetExplorerEncoding()
106 {
107 $files = file2array('internet_explorer_encoding.htm');
108 $this->assertEquals(
109 'File internet_explorer_encoding.htm (356 bytes) was successfully processed:'
110 .' 1 links imported, 0 links overwritten, 0 links skipped.',
111 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
112 );
113 $this->assertEquals(1, count($this->linkDb));
114 $this->assertEquals(0, count_private($this->linkDb));
115
116 $this->assertEquals(
117 array(
118 'id' => 0,
119 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160618_203944'),
120 'title' => 'Hg Init a Mercurial tutorial by Joel Spolsky',
121 'url' => 'http://hginit.com/',
122 'description' => '',
123 'private' => 0,
124 'tags' => '',
125 'shorturl' => 'La37cg',
126 ),
127 $this->linkDb->getLinkFromUrl('http://hginit.com/')
128 );
129 }
130
131 /**
132 * Import bookmarks nested in a folder hierarchy
133 */
134 public function testImportNested()
135 {
136 $files = file2array('netscape_nested.htm');
137 $this->assertEquals(
138 'File netscape_nested.htm (1337 bytes) was successfully processed:'
139 .' 8 links imported, 0 links overwritten, 0 links skipped.',
140 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
141 );
142 $this->assertEquals(8, count($this->linkDb));
143 $this->assertEquals(2, count_private($this->linkDb));
144
145 $this->assertEquals(
146 array(
147 'id' => 0,
148 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235541'),
149 'title' => 'Nested 1',
150 'url' => 'http://nest.ed/1',
151 'description' => '',
152 'private' => 0,
153 'tags' => 'tag1 tag2',
154 'shorturl' => 'KyDNKA',
155 ),
156 $this->linkDb->getLinkFromUrl('http://nest.ed/1')
157 );
158 $this->assertEquals(
159 array(
160 'id' => 1,
161 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235542'),
162 'title' => 'Nested 1-1',
163 'url' => 'http://nest.ed/1-1',
164 'description' => '',
165 'private' => 0,
166 'tags' => 'folder1 tag1 tag2',
167 'shorturl' => 'T2LnXg',
168 ),
169 $this->linkDb->getLinkFromUrl('http://nest.ed/1-1')
170 );
171 $this->assertEquals(
172 array(
173 'id' => 2,
174 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235547'),
175 'title' => 'Nested 1-2',
176 'url' => 'http://nest.ed/1-2',
177 'description' => '',
178 'private' => 0,
179 'tags' => 'folder1 tag3 tag4',
180 'shorturl' => '46SZxA',
181 ),
182 $this->linkDb->getLinkFromUrl('http://nest.ed/1-2')
183 );
184 $this->assertEquals(
185 array(
186 'id' => 3,
187 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160202_202222'),
188 'title' => 'Nested 2-1',
189 'url' => 'http://nest.ed/2-1',
190 'description' => 'First link of the second section',
191 'private' => 1,
192 'tags' => 'folder2',
193 'shorturl' => '4UHOSw',
194 ),
195 $this->linkDb->getLinkFromUrl('http://nest.ed/2-1')
196 );
197 $this->assertEquals(
198 array(
199 'id' => 4,
200 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160119_230227'),
201 'title' => 'Nested 2-2',
202 'url' => 'http://nest.ed/2-2',
203 'description' => 'Second link of the second section',
204 'private' => 1,
205 'tags' => 'folder2',
206 'shorturl' => 'yfzwbw',
207 ),
208 $this->linkDb->getLinkFromUrl('http://nest.ed/2-2')
209 );
210 $this->assertEquals(
211 array(
212 'id' => 5,
213 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160202_202222'),
214 'title' => 'Nested 3-1',
215 'url' => 'http://nest.ed/3-1',
216 'description' => '',
217 'private' => 0,
218 'tags' => 'folder3 folder3-1 tag3',
219 'shorturl' => 'UwxIUQ',
220 ),
221 $this->linkDb->getLinkFromUrl('http://nest.ed/3-1')
222 );
223 $this->assertEquals(
224 array(
225 'id' => 6,
226 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160119_230227'),
227 'title' => 'Nested 3-2',
228 'url' => 'http://nest.ed/3-2',
229 'description' => '',
230 'private' => 0,
231 'tags' => 'folder3 folder3-1',
232 'shorturl' => 'p8dyZg',
233 ),
234 $this->linkDb->getLinkFromUrl('http://nest.ed/3-2')
235 );
236 $this->assertEquals(
237 array(
238 'id' => 7,
239 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160229_111541'),
240 'title' => 'Nested 2',
241 'url' => 'http://nest.ed/2',
242 'description' => '',
243 'private' => 0,
244 'tags' => 'tag4',
245 'shorturl' => 'Gt3Uug',
246 ),
247 $this->linkDb->getLinkFromUrl('http://nest.ed/2')
248 );
249 }
250
251 /**
252 * Import bookmarks with the default privacy setting (reuse from file)
253 *
254 * The $_POST array is not set.
255 */
256 public function testImportDefaultPrivacyNoPost()
257 {
258 $files = file2array('netscape_basic.htm');
259 $this->assertEquals(
260 'File netscape_basic.htm (482 bytes) was successfully processed:'
261 .' 2 links imported, 0 links overwritten, 0 links skipped.',
262 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
263 );
264
265 $this->assertEquals(2, count($this->linkDb));
266 $this->assertEquals(1, count_private($this->linkDb));
267
268 $this->assertEquals(
269 array(
270 'id' => 0,
271 // Old link - UTC+4 (note that TZ in the import file is ignored).
272 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20001010_135536'),
273 'title' => 'Secret stuff',
274 'url' => 'https://private.tld',
275 'description' => "Super-secret stuff you're not supposed to know about",
276 'private' => 1,
277 'tags' => 'private secret',
278 'shorturl' => 'EokDtA',
279 ),
280 $this->linkDb->getLinkFromUrl('https://private.tld')
281 );
282 $this->assertEquals(
283 array(
284 'id' => 1,
285 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235548'),
286 'title' => 'Public stuff',
287 'url' => 'http://public.tld',
288 'description' => '',
289 'private' => 0,
290 'tags' => 'public hello world',
291 'shorturl' => 'Er9ddA',
292 ),
293 $this->linkDb->getLinkFromUrl('http://public.tld')
294 );
295 }
296
297 /**
298 * Import bookmarks with the default privacy setting (reuse from file)
299 */
300 public function testImportKeepPrivacy()
301 {
302 $post = array('privacy' => 'default');
303 $files = file2array('netscape_basic.htm');
304 $this->assertEquals(
305 'File netscape_basic.htm (482 bytes) was successfully processed:'
306 .' 2 links imported, 0 links overwritten, 0 links skipped.',
307 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
308 );
309 $this->assertEquals(2, count($this->linkDb));
310 $this->assertEquals(1, count_private($this->linkDb));
311
312 $this->assertEquals(
313 array(
314 'id' => 0,
315 // Note that TZ in the import file is ignored.
316 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20001010_135536'),
317 'title' => 'Secret stuff',
318 'url' => 'https://private.tld',
319 'description' => "Super-secret stuff you're not supposed to know about",
320 'private' => 1,
321 'tags' => 'private secret',
322 'shorturl' => 'EokDtA',
323 ),
324 $this->linkDb->getLinkFromUrl('https://private.tld')
325 );
326 $this->assertEquals(
327 array(
328 'id' => 1,
329 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160225_235548'),
330 'title' => 'Public stuff',
331 'url' => 'http://public.tld',
332 'description' => '',
333 'private' => 0,
334 'tags' => 'public hello world',
335 'shorturl' => 'Er9ddA',
336 ),
337 $this->linkDb->getLinkFromUrl('http://public.tld')
338 );
339 }
340
341 /**
342 * Import links as public
343 */
344 public function testImportAsPublic()
345 {
346 $post = array('privacy' => 'public');
347 $files = file2array('netscape_basic.htm');
348 $this->assertEquals(
349 'File netscape_basic.htm (482 bytes) was successfully processed:'
350 .' 2 links imported, 0 links overwritten, 0 links skipped.',
351 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
352 );
353 $this->assertEquals(2, count($this->linkDb));
354 $this->assertEquals(0, count_private($this->linkDb));
355 $this->assertEquals(
356 0,
357 $this->linkDb[0]['private']
358 );
359 $this->assertEquals(
360 0,
361 $this->linkDb[1]['private']
362 );
363 }
364
365 /**
366 * Import links as private
367 */
368 public function testImportAsPrivate()
369 {
370 $post = array('privacy' => 'private');
371 $files = file2array('netscape_basic.htm');
372 $this->assertEquals(
373 'File netscape_basic.htm (482 bytes) was successfully processed:'
374 .' 2 links imported, 0 links overwritten, 0 links skipped.',
375 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
376 );
377 $this->assertEquals(2, count($this->linkDb));
378 $this->assertEquals(2, count_private($this->linkDb));
379 $this->assertEquals(
380 1,
381 $this->linkDb['0']['private']
382 );
383 $this->assertEquals(
384 1,
385 $this->linkDb['1']['private']
386 );
387 }
388
389 /**
390 * Overwrite private links so they become public
391 */
392 public function testOverwriteAsPublic()
393 {
394 $files = file2array('netscape_basic.htm');
395
396 // import links as private
397 $post = array('privacy' => 'private');
398 $this->assertEquals(
399 'File netscape_basic.htm (482 bytes) was successfully processed:'
400 .' 2 links imported, 0 links overwritten, 0 links skipped.',
401 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
402 );
403 $this->assertEquals(2, count($this->linkDb));
404 $this->assertEquals(2, count_private($this->linkDb));
405 $this->assertEquals(
406 1,
407 $this->linkDb[0]['private']
408 );
409 $this->assertEquals(
410 1,
411 $this->linkDb[1]['private']
412 );
413 // re-import as public, enable overwriting
414 $post = array(
415 'privacy' => 'public',
416 'overwrite' => 'true'
417 );
418 $this->assertEquals(
419 'File netscape_basic.htm (482 bytes) was successfully processed:'
420 .' 2 links imported, 2 links overwritten, 0 links skipped.',
421 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
422 );
423 $this->assertEquals(2, count($this->linkDb));
424 $this->assertEquals(0, count_private($this->linkDb));
425 $this->assertEquals(
426 0,
427 $this->linkDb[0]['private']
428 );
429 $this->assertEquals(
430 0,
431 $this->linkDb[1]['private']
432 );
433 }
434
435 /**
436 * Overwrite public links so they become private
437 */
438 public function testOverwriteAsPrivate()
439 {
440 $files = file2array('netscape_basic.htm');
441
442 // import links as public
443 $post = array('privacy' => 'public');
444 $this->assertEquals(
445 'File netscape_basic.htm (482 bytes) was successfully processed:'
446 .' 2 links imported, 0 links overwritten, 0 links skipped.',
447 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
448 );
449 $this->assertEquals(2, count($this->linkDb));
450 $this->assertEquals(0, count_private($this->linkDb));
451 $this->assertEquals(
452 0,
453 $this->linkDb['0']['private']
454 );
455 $this->assertEquals(
456 0,
457 $this->linkDb['1']['private']
458 );
459
460 // re-import as private, enable overwriting
461 $post = array(
462 'privacy' => 'private',
463 'overwrite' => 'true'
464 );
465 $this->assertEquals(
466 'File netscape_basic.htm (482 bytes) was successfully processed:'
467 .' 2 links imported, 2 links overwritten, 0 links skipped.',
468 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
469 );
470 $this->assertEquals(2, count($this->linkDb));
471 $this->assertEquals(2, count_private($this->linkDb));
472 $this->assertEquals(
473 1,
474 $this->linkDb['0']['private']
475 );
476 $this->assertEquals(
477 1,
478 $this->linkDb['1']['private']
479 );
480 }
481
482 /**
483 * Attept to import the same links twice without enabling overwriting
484 */
485 public function testSkipOverwrite()
486 {
487 $post = array('privacy' => 'public');
488 $files = file2array('netscape_basic.htm');
489 $this->assertEquals(
490 'File netscape_basic.htm (482 bytes) was successfully processed:'
491 .' 2 links imported, 0 links overwritten, 0 links skipped.',
492 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
493 );
494 $this->assertEquals(2, count($this->linkDb));
495 $this->assertEquals(0, count_private($this->linkDb));
496
497 // re-import as private, DO NOT enable overwriting
498 $post = array('privacy' => 'private');
499 $this->assertEquals(
500 'File netscape_basic.htm (482 bytes) was successfully processed:'
501 .' 0 links imported, 0 links overwritten, 2 links skipped.',
502 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
503 );
504 $this->assertEquals(2, count($this->linkDb));
505 $this->assertEquals(0, count_private($this->linkDb));
506 }
507
508 /**
509 * Add user-specified tags to all imported bookmarks
510 */
511 public function testSetDefaultTags()
512 {
513 $post = array(
514 'privacy' => 'public',
515 'default_tags' => 'tag1,tag2 tag3'
516 );
517 $files = file2array('netscape_basic.htm');
518 $this->assertEquals(
519 'File netscape_basic.htm (482 bytes) was successfully processed:'
520 .' 2 links imported, 0 links overwritten, 0 links skipped.',
521 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
522 );
523 $this->assertEquals(2, count($this->linkDb));
524 $this->assertEquals(0, count_private($this->linkDb));
525 $this->assertEquals(
526 'tag1 tag2 tag3 private secret',
527 $this->linkDb['0']['tags']
528 );
529 $this->assertEquals(
530 'tag1 tag2 tag3 public hello world',
531 $this->linkDb['1']['tags']
532 );
533 }
534
535 /**
536 * The user-specified tags contain characters to be escaped
537 */
538 public function testSanitizeDefaultTags()
539 {
540 $post = array(
541 'privacy' => 'public',
542 'default_tags' => 'tag1&,tag2 "tag3"'
543 );
544 $files = file2array('netscape_basic.htm');
545 $this->assertEquals(
546 'File netscape_basic.htm (482 bytes) was successfully processed:'
547 .' 2 links imported, 0 links overwritten, 0 links skipped.',
548 NetscapeBookmarkUtils::import($post, $files, $this->linkDb, $this->pagecache)
549 );
550 $this->assertEquals(2, count($this->linkDb));
551 $this->assertEquals(0, count_private($this->linkDb));
552 $this->assertEquals(
553 'tag1&amp; tag2 &quot;tag3&quot; private secret',
554 $this->linkDb['0']['tags']
555 );
556 $this->assertEquals(
557 'tag1&amp; tag2 &quot;tag3&quot; public hello world',
558 $this->linkDb['1']['tags']
559 );
560 }
561
562 /**
563 * Ensure each imported bookmark has a unique id
564 *
565 * See https://github.com/shaarli/Shaarli/issues/351
566 */
567 public function testImportSameDate()
568 {
569 $files = file2array('same_date.htm');
570 $this->assertEquals(
571 'File same_date.htm (453 bytes) was successfully processed:'
572 .' 3 links imported, 0 links overwritten, 0 links skipped.',
573 NetscapeBookmarkUtils::import(array(), $files, $this->linkDb, $this->pagecache)
574 );
575 $this->assertEquals(3, count($this->linkDb));
576 $this->assertEquals(0, count_private($this->linkDb));
577 $this->assertEquals(
578 0,
579 $this->linkDb[0]['id']
580 );
581 $this->assertEquals(
582 1,
583 $this->linkDb[1]['id']
584 );
585 $this->assertEquals(
586 2,
587 $this->linkDb[2]['id']
588 );
589 }
590}
diff --git a/tests/NetscapeBookmarkUtils/input/empty.htm b/tests/NetscapeBookmarkUtils/input/empty.htm
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/NetscapeBookmarkUtils/input/empty.htm
diff --git a/tests/NetscapeBookmarkUtils/input/internet_explorer_encoding.htm b/tests/NetscapeBookmarkUtils/input/internet_explorer_encoding.htm
new file mode 100644
index 00000000..18703cf6
--- /dev/null
+++ b/tests/NetscapeBookmarkUtils/input/internet_explorer_encoding.htm
@@ -0,0 +1,9 @@
1<!DOCTYPE NETSCAPE-Bookmark-file-1>
2<!-- This is an automatically generated file.
3It will be read and overwritten.
4Do Not Edit! -->
5<TITLE>Bookmarks</TITLE>
6<H1>Bookmarks</H1>
7<DL><p>
8 <DT><A HREF="http://hginit.com/" ADD_DATE="1466271584" LAST_VISIT="1466271584" LAST_MODIFIED="1466271584" >Hg Init a Mercurial tutorial by Joel Spolsky</A>
9</DL><p>
diff --git a/tests/NetscapeBookmarkUtils/input/netscape_basic.htm b/tests/NetscapeBookmarkUtils/input/netscape_basic.htm
new file mode 100644
index 00000000..affe0cf8
--- /dev/null
+++ b/tests/NetscapeBookmarkUtils/input/netscape_basic.htm
@@ -0,0 +1,11 @@
1<!DOCTYPE NETSCAPE-Bookmark-file-1>
2<!-- This is an automatically generated file.
3It will be read and overwritten.
4Do Not Edit! -->
5<TITLE>Bookmarks</TITLE>
6<H1>Bookmarks</H1>
7<DL><p>
8<DT><A HREF="https://private.tld" ADD_DATE="10/Oct/2000:13:55:36 +0300" PRIVATE="1" TAGS="private secret">Secret stuff</A>
9<DD>Super-secret stuff you're not supposed to know about
10<DT><A HREF="http://public.tld" ADD_DATE="1456433748" PRIVATE="0" TAGS="public hello world">Public stuff</A>
11</DL><p>
diff --git a/tests/NetscapeBookmarkUtils/input/netscape_nested.htm b/tests/NetscapeBookmarkUtils/input/netscape_nested.htm
new file mode 100644
index 00000000..b486fe18
--- /dev/null
+++ b/tests/NetscapeBookmarkUtils/input/netscape_nested.htm
@@ -0,0 +1,31 @@
1<!DOCTYPE NETSCAPE-Bookmark-file-1>
2<!-- This is an automatically generated file.
3It will be read and overwritten.
4Do Not Edit! -->
5<TITLE>Bookmarks</TITLE>
6<H1>Bookmarks</H1>
7<DL><p>
8 <DT><A HREF="http://nest.ed/1" ADD_DATE="1456433741" PRIVATE="0" TAGS="tag1,tag2">Nested 1</A>
9 <DT><H3 ADD_DATE="1456433722" LAST_MODIFIED="1456433739">Folder1</H3>
10 <DL><p>
11 <DT><A HREF="http://nest.ed/1-1" ADD_DATE="1456433742" PRIVATE="0" TAGS="tag1,tag2">Nested 1-1</A>
12 <DT><A HREF="http://nest.ed/1-2" ADD_DATE="1456433747" PRIVATE="0" TAGS="tag3,tag4">Nested 1-2</A>
13 </DL><p>
14 <DT><H3 ADD_DATE="1456433722">Folder2</H3>
15 <DD>This second folder contains wonderful links!
16 <DL><p>
17 <DT><A HREF="http://nest.ed/2-1" ADD_DATE="1454433742" PRIVATE="1">Nested 2-1</A>
18 <DD>First link of the second section
19 <DT><A HREF="http://nest.ed/2-2" ADD_DATE="1453233747" PRIVATE="1">Nested 2-2</A>
20 <DD>Second link of the second section
21 </DL><p>
22 <DT><H3>Folder3</H3>
23 <DL><p>
24 <DT><H3>Folder3-1</H3>
25 <DL><p>
26 <DT><A HREF="http://nest.ed/3-1" ADD_DATE="1454433742" PRIVATE="0" TAGS="tag3">Nested 3-1</A>
27 <DT><A HREF="http://nest.ed/3-2" ADD_DATE="1453233747" PRIVATE="0">Nested 3-2</A>
28 </DL><p>
29 </DL><p>
30 <DT><A HREF="http://nest.ed/2" ADD_DATE="1456733741" PRIVATE="0" TAGS="tag4">Nested 2</A>
31</DL><p>
diff --git a/tests/NetscapeBookmarkUtils/input/no_doctype.htm b/tests/NetscapeBookmarkUtils/input/no_doctype.htm
new file mode 100644
index 00000000..766d398b
--- /dev/null
+++ b/tests/NetscapeBookmarkUtils/input/no_doctype.htm
@@ -0,0 +1,7 @@
1<TITLE>Bookmarks</TITLE>
2<H1>Bookmarks</H1>
3<DL><p>
4<DT><A HREF="https://private.tld" ADD_DATE="10/Oct/2000:13:55:36 +0300" PRIVATE="1" TAGS="private secret">Secret stuff</A>
5<DD>Super-secret stuff you're not supposed to know about
6<DT><A HREF="http://public.tld" ADD_DATE="1456433748" PRIVATE="0" TAGS="public hello world">Public stuff</A>
7</DL><p>
diff --git a/tests/NetscapeBookmarkUtils/input/same_date.htm b/tests/NetscapeBookmarkUtils/input/same_date.htm
new file mode 100644
index 00000000..9d58a582
--- /dev/null
+++ b/tests/NetscapeBookmarkUtils/input/same_date.htm
@@ -0,0 +1,11 @@
1<!DOCTYPE NETSCAPE-Bookmark-file-1>
2<!-- This is an automatically generated file.
3It will be read and overwritten.
4Do Not Edit! -->
5<TITLE>Bookmarks</TITLE>
6<H1>Bookmarks</H1>
7<DL><p>
8<DT><A HREF="https://fir.st" ADD_DATE="1456433748" PRIVATE="0">Today's first link</A>
9<DT><A HREF="https://seco.nd" ADD_DATE="1456433748" PRIVATE="0">Today's second link</A>
10<DT><A HREF="https://thi.rd" ADD_DATE="1456433748" PRIVATE="0">Today's third link</A>
11</DL><p>
diff --git a/tests/PluginManagerTest.php b/tests/PluginManagerTest.php
index 348082c7..ddf48185 100644
--- a/tests/PluginManagerTest.php
+++ b/tests/PluginManagerTest.php
@@ -24,29 +24,38 @@ class PluginManagerTest extends PHPUnit_Framework_TestCase
24 private static $pluginName = 'test'; 24 private static $pluginName = 'test';
25 25
26 /** 26 /**
27 * @var PluginManager $pluginManager Plugin Mananger instance.
28 */
29 protected $pluginManager;
30
31 public function setUp()
32 {
33 $conf = new ConfigManager('');
34 $this->pluginManager = new PluginManager($conf);
35 }
36
37 /**
27 * Test plugin loading and hook execution. 38 * Test plugin loading and hook execution.
28 * 39 *
29 * @return void 40 * @return void
30 */ 41 */
31 public function testPlugin() 42 public function testPlugin()
32 { 43 {
33 $pluginManager = PluginManager::getInstance();
34
35 PluginManager::$PLUGINS_PATH = self::$pluginPath; 44 PluginManager::$PLUGINS_PATH = self::$pluginPath;
36 $pluginManager->load(array(self::$pluginName)); 45 $this->pluginManager->load(array(self::$pluginName));
37 46
38 $this->assertTrue(function_exists('hook_test_random')); 47 $this->assertTrue(function_exists('hook_test_random'));
39 48
40 $data = array(0 => 'woot'); 49 $data = array(0 => 'woot');
41 $pluginManager->executeHooks('random', $data); 50 $this->pluginManager->executeHooks('random', $data);
42 $this->assertEquals('woot', $data[1]); 51 $this->assertEquals('woot', $data[1]);
43 52
44 $data = array(0 => 'woot'); 53 $data = array(0 => 'woot');
45 $pluginManager->executeHooks('random', $data, array('target' => 'test')); 54 $this->pluginManager->executeHooks('random', $data, array('target' => 'test'));
46 $this->assertEquals('page test', $data[1]); 55 $this->assertEquals('page test', $data[1]);
47 56
48 $data = array(0 => 'woot'); 57 $data = array(0 => 'woot');
49 $pluginManager->executeHooks('random', $data, array('loggedin' => true)); 58 $this->pluginManager->executeHooks('random', $data, array('loggedin' => true));
50 $this->assertEquals('loggedin', $data[1]); 59 $this->assertEquals('loggedin', $data[1]);
51 } 60 }
52 61
@@ -57,11 +66,8 @@ class PluginManagerTest extends PHPUnit_Framework_TestCase
57 */ 66 */
58 public function testPluginNotFound() 67 public function testPluginNotFound()
59 { 68 {
60 $pluginManager = PluginManager::getInstance(); 69 $this->pluginManager->load(array());
61 70 $this->pluginManager->load(array('nope', 'renope'));
62 $pluginManager->load(array());
63
64 $pluginManager->load(array('nope', 'renope'));
65 } 71 }
66 72
67 /** 73 /**
@@ -69,17 +75,21 @@ class PluginManagerTest extends PHPUnit_Framework_TestCase
69 */ 75 */
70 public function testGetPluginsMeta() 76 public function testGetPluginsMeta()
71 { 77 {
72 $pluginManager = PluginManager::getInstance();
73
74 PluginManager::$PLUGINS_PATH = self::$pluginPath; 78 PluginManager::$PLUGINS_PATH = self::$pluginPath;
75 $pluginManager->load(array(self::$pluginName)); 79 $this->pluginManager->load(array(self::$pluginName));
76 80
77 $expectedParameters = array( 81 $expectedParameters = array(
78 'pop' => '', 82 'pop' => array(
79 'hip' => '', 83 'value' => '',
84 'desc' => 'pop description',
85 ),
86 'hip' => array(
87 'value' => '',
88 'desc' => '',
89 ),
80 ); 90 );
81 $meta = $pluginManager->getPluginsMeta(); 91 $meta = $this->pluginManager->getPluginsMeta();
82 $this->assertEquals('test plugin', $meta[self::$pluginName]['description']); 92 $this->assertEquals('test plugin', $meta[self::$pluginName]['description']);
83 $this->assertEquals($expectedParameters, $meta[self::$pluginName]['parameters']); 93 $this->assertEquals($expectedParameters, $meta[self::$pluginName]['parameters']);
84 } 94 }
85} \ No newline at end of file 95}
diff --git a/tests/Updater/DummyUpdater.php b/tests/Updater/DummyUpdater.php
index e9ef2aaa..a0be4413 100644
--- a/tests/Updater/DummyUpdater.php
+++ b/tests/Updater/DummyUpdater.php
@@ -11,14 +11,14 @@ class DummyUpdater extends Updater
11 /** 11 /**
12 * Object constructor. 12 * Object constructor.
13 * 13 *
14 * @param array $doneUpdates Updates which are already done. 14 * @param array $doneUpdates Updates which are already done.
15 * @param array $config Shaarli's configuration array. 15 * @param LinkDB $linkDB LinkDB instance.
16 * @param LinkDB $linkDB LinkDB instance. 16 * @param ConfigManager $conf Configuration Manager instance.
17 * @param boolean $isLoggedIn True if the user is logged in. 17 * @param boolean $isLoggedIn True if the user is logged in.
18 */ 18 */
19 public function __construct($doneUpdates, $config, $linkDB, $isLoggedIn) 19 public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn)
20 { 20 {
21 parent::__construct($doneUpdates, $config, $linkDB, $isLoggedIn); 21 parent::__construct($doneUpdates, $linkDB, $conf, $isLoggedIn);
22 22
23 // Retrieve all update methods. 23 // Retrieve all update methods.
24 // For unit test, only retrieve final methods, 24 // For unit test, only retrieve final methods,
diff --git a/tests/Updater/UpdaterTest.php b/tests/Updater/UpdaterTest.php
index a29d9067..a3e8a4d2 100644
--- a/tests/Updater/UpdaterTest.php
+++ b/tests/Updater/UpdaterTest.php
@@ -1,5 +1,6 @@
1<?php 1<?php
2 2
3require_once 'application/config/ConfigManager.php';
3require_once 'tests/Updater/DummyUpdater.php'; 4require_once 'tests/Updater/DummyUpdater.php';
4 5
5/** 6/**
@@ -9,58 +10,26 @@ require_once 'tests/Updater/DummyUpdater.php';
9class UpdaterTest extends PHPUnit_Framework_TestCase 10class UpdaterTest extends PHPUnit_Framework_TestCase
10{ 11{
11 /** 12 /**
12 * @var array Configuration input set. 13 * @var string Path to test datastore.
13 */ 14 */
14 private static $configFields; 15 protected static $testDatastore = 'sandbox/datastore.php';
15 16
16 /** 17 /**
17 * @var string Path to test datastore. 18 * @var string Config file path (without extension).
18 */ 19 */
19 protected static $testDatastore = 'sandbox/datastore.php'; 20 protected static $configFile = 'tests/utils/config/configJson';
20 21
21 /** 22 /**
22 * Executed before each test. 23 * @var ConfigManager
23 */ 24 */
24 public function setUp() 25 protected $conf;
25 {
26 self::$configFields = array(
27 'login' => 'login',
28 'hash' => 'hash',
29 'salt' => 'salt',
30 'timezone' => 'Europe/Paris',
31 'title' => 'title',
32 'titleLink' => 'titleLink',
33 'redirector' => '',
34 'disablesessionprotection' => false,
35 'privateLinkByDefault' => false,
36 'config' => array(
37 'CONFIG_FILE' => 'tests/Updater/config.php',
38 'DATADIR' => 'tests/Updater',
39 'PAGECACHE' => 'sandbox/pagecache',
40 'config1' => 'config1data',
41 'config2' => 'config2data',
42 )
43 );
44 }
45 26
46 /** 27 /**
47 * Executed after each test. 28 * Executed before each test.
48 *
49 * @return void
50 */ 29 */
51 public function tearDown() 30 public function setUp()
52 { 31 {
53 if (is_file(self::$configFields['config']['CONFIG_FILE'])) { 32 $this->conf = new ConfigManager(self::$configFile);
54 unlink(self::$configFields['config']['CONFIG_FILE']);
55 }
56
57 if (is_file(self::$configFields['config']['DATADIR'] . '/options.php')) {
58 unlink(self::$configFields['config']['DATADIR'] . '/options.php');
59 }
60
61 if (is_file(self::$configFields['config']['DATADIR'] . '/updates.json')) {
62 unlink(self::$configFields['config']['DATADIR'] . '/updates.json');
63 }
64 } 33 }
65 34
66 /** 35 /**
@@ -69,9 +38,10 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
69 public function testReadEmptyUpdatesFile() 38 public function testReadEmptyUpdatesFile()
70 { 39 {
71 $this->assertEquals(array(), read_updates_file('')); 40 $this->assertEquals(array(), read_updates_file(''));
72 $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.json'; 41 $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
73 touch($updatesFile); 42 touch($updatesFile);
74 $this->assertEquals(array(), read_updates_file($updatesFile)); 43 $this->assertEquals(array(), read_updates_file($updatesFile));
44 unlink($updatesFile);
75 } 45 }
76 46
77 /** 47 /**
@@ -79,7 +49,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
79 */ 49 */
80 public function testReadWriteUpdatesFile() 50 public function testReadWriteUpdatesFile()
81 { 51 {
82 $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.json'; 52 $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
83 $updatesMethods = array('m1', 'm2', 'm3'); 53 $updatesMethods = array('m1', 'm2', 'm3');
84 54
85 write_updates_file($updatesFile, $updatesMethods); 55 write_updates_file($updatesFile, $updatesMethods);
@@ -91,6 +61,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
91 write_updates_file($updatesFile, $updatesMethods); 61 write_updates_file($updatesFile, $updatesMethods);
92 $readMethods = read_updates_file($updatesFile); 62 $readMethods = read_updates_file($updatesFile);
93 $this->assertEquals($readMethods, $updatesMethods); 63 $this->assertEquals($readMethods, $updatesMethods);
64 unlink($updatesFile);
94 } 65 }
95 66
96 /** 67 /**
@@ -112,10 +83,15 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
112 */ 83 */
113 public function testWriteUpdatesFileNotWritable() 84 public function testWriteUpdatesFileNotWritable()
114 { 85 {
115 $updatesFile = self::$configFields['config']['DATADIR'] . '/updates.json'; 86 $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
116 touch($updatesFile); 87 touch($updatesFile);
117 chmod($updatesFile, 0444); 88 chmod($updatesFile, 0444);
118 @write_updates_file($updatesFile, array('test')); 89 try {
90 @write_updates_file($updatesFile, array('test'));
91 } catch (Exception $e) {
92 unlink($updatesFile);
93 throw $e;
94 }
119 } 95 }
120 96
121 /** 97 /**
@@ -131,10 +107,10 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
131 'updateMethodDummy3', 107 'updateMethodDummy3',
132 'updateMethodException', 108 'updateMethodException',
133 ); 109 );
134 $updater = new DummyUpdater($updates, array(), array(), true); 110 $updater = new DummyUpdater($updates, array(), $this->conf, true);
135 $this->assertEquals(array(), $updater->update()); 111 $this->assertEquals(array(), $updater->update());
136 112
137 $updater = new DummyUpdater(array(), array(), array(), false); 113 $updater = new DummyUpdater(array(), array(), $this->conf, false);
138 $this->assertEquals(array(), $updater->update()); 114 $this->assertEquals(array(), $updater->update());
139 } 115 }
140 116
@@ -149,7 +125,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
149 'updateMethodDummy2', 125 'updateMethodDummy2',
150 'updateMethodDummy3', 126 'updateMethodDummy3',
151 ); 127 );
152 $updater = new DummyUpdater($updates, array(), array(), true); 128 $updater = new DummyUpdater($updates, array(), $this->conf, true);
153 $this->assertEquals($expectedUpdates, $updater->update()); 129 $this->assertEquals($expectedUpdates, $updater->update());
154 } 130 }
155 131
@@ -165,7 +141,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
165 ); 141 );
166 $expectedUpdate = array('updateMethodDummy2'); 142 $expectedUpdate = array('updateMethodDummy2');
167 143
168 $updater = new DummyUpdater($updates, array(), array(), true); 144 $updater = new DummyUpdater($updates, array(), $this->conf, true);
169 $this->assertEquals($expectedUpdate, $updater->update()); 145 $this->assertEquals($expectedUpdate, $updater->update());
170 } 146 }
171 147
@@ -182,7 +158,7 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
182 'updateMethodDummy3', 158 'updateMethodDummy3',
183 ); 159 );
184 160
185 $updater = new DummyUpdater($updates, array(), array(), true); 161 $updater = new DummyUpdater($updates, array(), $this->conf, true);
186 $updater->update(); 162 $updater->update();
187 } 163 }
188 164
@@ -195,26 +171,28 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
195 */ 171 */
196 public function testUpdateMergeDeprecatedConfig() 172 public function testUpdateMergeDeprecatedConfig()
197 { 173 {
198 // init 174 $this->conf->setConfigFile('tests/utils/config/configPhp');
199 writeConfig(self::$configFields, true); 175 $this->conf->reset();
200 $configCopy = self::$configFields;
201 $invert = !$configCopy['privateLinkByDefault'];
202 $configCopy['privateLinkByDefault'] = $invert;
203 176
204 // Use writeConfig to create a options.php 177 $optionsFile = 'tests/Updater/options.php';
205 $configCopy['config']['CONFIG_FILE'] = 'tests/Updater/options.php'; 178 $options = '<?php
206 writeConfig($configCopy, true); 179$GLOBALS[\'privateLinkByDefault\'] = true;';
180 file_put_contents($optionsFile, $options);
207 181
208 $this->assertTrue(is_file($configCopy['config']['CONFIG_FILE'])); 182 // tmp config file.
183 $this->conf->setConfigFile('tests/Updater/config');
209 184
210 // merge configs 185 // merge configs
211 $updater = new Updater(array(), self::$configFields, array(), true); 186 $updater = new Updater(array(), array(), $this->conf, true);
187 // This writes a new config file in tests/Updater/config.php
212 $updater->updateMethodMergeDeprecatedConfigFile(); 188 $updater->updateMethodMergeDeprecatedConfigFile();
213 189
214 // make sure updated field is changed 190 // make sure updated field is changed
215 include self::$configFields['config']['CONFIG_FILE']; 191 $this->conf->reload();
216 $this->assertEquals($invert, $GLOBALS['privateLinkByDefault']); 192 $this->assertTrue($this->conf->get('privacy.default_private_links'));
217 $this->assertFalse(is_file($configCopy['config']['CONFIG_FILE'])); 193 $this->assertFalse(is_file($optionsFile));
194 // Delete the generated file.
195 unlink($this->conf->getConfigFileExt());
218 } 196 }
219 197
220 /** 198 /**
@@ -222,23 +200,254 @@ class UpdaterTest extends PHPUnit_Framework_TestCase
222 */ 200 */
223 public function testMergeDeprecatedConfigNoFile() 201 public function testMergeDeprecatedConfigNoFile()
224 { 202 {
225 writeConfig(self::$configFields, true); 203 $updater = new Updater(array(), array(), $this->conf, true);
226
227 $updater = new Updater(array(), self::$configFields, array(), true);
228 $updater->updateMethodMergeDeprecatedConfigFile(); 204 $updater->updateMethodMergeDeprecatedConfigFile();
229 205
230 include self::$configFields['config']['CONFIG_FILE']; 206 $this->assertEquals('root', $this->conf->get('credentials.login'));
231 $this->assertEquals(self::$configFields['login'], $GLOBALS['login']);
232 } 207 }
233 208
209 /**
210 * Test renameDashTags update method.
211 */
234 public function testRenameDashTags() 212 public function testRenameDashTags()
235 { 213 {
236 $refDB = new ReferenceLinkDB(); 214 $refDB = new ReferenceLinkDB();
237 $refDB->write(self::$testDatastore); 215 $refDB->write(self::$testDatastore);
238 $linkDB = new LinkDB(self::$testDatastore, true, false); 216 $linkDB = new LinkDB(self::$testDatastore, true, false);
217
239 $this->assertEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); 218 $this->assertEmpty($linkDB->filterSearch(array('searchtags' => 'exclude')));
240 $updater = new Updater(array(), self::$configFields, $linkDB, true); 219 $updater = new Updater(array(), $linkDB, $this->conf, true);
241 $updater->updateMethodRenameDashTags(); 220 $updater->updateMethodRenameDashTags();
242 $this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude'))); 221 $this->assertNotEmpty($linkDB->filterSearch(array('searchtags' => 'exclude')));
243 } 222 }
223
224 /**
225 * Convert old PHP config file to JSON config.
226 */
227 public function testConfigToJson()
228 {
229 $configFile = 'tests/utils/config/configPhp';
230 $this->conf->setConfigFile($configFile);
231 $this->conf->reset();
232
233 // The ConfigIO is initialized with ConfigPhp.
234 $this->assertTrue($this->conf->getConfigIO() instanceof ConfigPhp);
235
236 $updater = new Updater(array(), array(), $this->conf, false);
237 $done = $updater->updateMethodConfigToJson();
238 $this->assertTrue($done);
239
240 // The ConfigIO has been updated to ConfigJson.
241 $this->assertTrue($this->conf->getConfigIO() instanceof ConfigJson);
242 $this->assertTrue(file_exists($this->conf->getConfigFileExt()));
243
244 // Check JSON config data.
245 $this->conf->reload();
246 $this->assertEquals('root', $this->conf->get('credentials.login'));
247 $this->assertEquals('lala', $this->conf->get('redirector.url'));
248 $this->assertEquals('data/datastore.php', $this->conf->get('resource.datastore'));
249 $this->assertEquals('1', $this->conf->get('plugins.WALLABAG_VERSION'));
250
251 rename($configFile . '.save.php', $configFile . '.php');
252 unlink($this->conf->getConfigFileExt());
253 }
254
255 /**
256 * Launch config conversion update with an existing JSON file => nothing to do.
257 */
258 public function testConfigToJsonNothingToDo()
259 {
260 $filetime = filemtime($this->conf->getConfigFileExt());
261 $updater = new Updater(array(), array(), $this->conf, false);
262 $done = $updater->updateMethodConfigToJson();
263 $this->assertTrue($done);
264 $expected = filemtime($this->conf->getConfigFileExt());
265 $this->assertEquals($expected, $filetime);
266 }
267
268 /**
269 * Test escapeUnescapedConfig with valid data.
270 */
271 public function testEscapeConfig()
272 {
273 $sandbox = 'sandbox/config';
274 copy(self::$configFile .'.json.php', $sandbox .'.json.php');
275 $this->conf = new ConfigManager($sandbox);
276 $title = '<script>alert("title");</script>';
277 $headerLink = '<script>alert("header_link");</script>';
278 $redirectorUrl = '<script>alert("redirector");</script>';
279 $this->conf->set('general.title', $title);
280 $this->conf->set('general.header_link', $headerLink);
281 $this->conf->set('redirector.url', $redirectorUrl);
282 $updater = new Updater(array(), array(), $this->conf, true);
283 $done = $updater->updateMethodEscapeUnescapedConfig();
284 $this->assertTrue($done);
285 $this->conf->reload();
286 $this->assertEquals(escape($title), $this->conf->get('general.title'));
287 $this->assertEquals(escape($headerLink), $this->conf->get('general.header_link'));
288 $this->assertEquals(escape($redirectorUrl), $this->conf->get('redirector.url'));
289 unlink($sandbox .'.json.php');
290 }
291
292 /**
293 * Test updateMethodDatastoreIds().
294 */
295 public function testDatastoreIds()
296 {
297 $links = array(
298 '20121206_182539' => array(
299 'linkdate' => '20121206_182539',
300 'title' => 'Geek and Poke',
301 'url' => 'http://geek-and-poke.com/',
302 'description' => 'desc',
303 'tags' => 'dev cartoon tag1 tag2 tag3 tag4 ',
304 'updated' => '20121206_190301',
305 'private' => false,
306 ),
307 '20121206_172539' => array(
308 'linkdate' => '20121206_172539',
309 'title' => 'UserFriendly - Samba',
310 'url' => 'http://ars.userfriendly.org/cartoons/?id=20010306',
311 'description' => '',
312 'tags' => 'samba cartoon web',
313 'private' => false,
314 ),
315 '20121206_142300' => array(
316 'linkdate' => '20121206_142300',
317 'title' => 'UserFriendly - Web Designer',
318 'url' => 'http://ars.userfriendly.org/cartoons/?id=20121206',
319 'description' => 'Naming conventions... #private',
320 'tags' => 'samba cartoon web',
321 'private' => true,
322 ),
323 );
324 $refDB = new ReferenceLinkDB();
325 $refDB->setLinks($links);
326 $refDB->write(self::$testDatastore);
327 $linkDB = new LinkDB(self::$testDatastore, true, false);
328
329 $checksum = hash_file('sha1', self::$testDatastore);
330
331 $this->conf->set('resource.data_dir', 'sandbox');
332 $this->conf->set('resource.datastore', self::$testDatastore);
333
334 $updater = new Updater(array(), $linkDB, $this->conf, true);
335 $this->assertTrue($updater->updateMethodDatastoreIds());
336
337 $linkDB = new LinkDB(self::$testDatastore, true, false);
338
339 $backup = glob($this->conf->get('resource.data_dir') . '/datastore.'. date('YmdH') .'*.php');
340 $backup = $backup[0];
341
342 $this->assertFileExists($backup);
343 $this->assertEquals($checksum, hash_file('sha1', $backup));
344 unlink($backup);
345
346 $this->assertEquals(3, count($linkDB));
347 $this->assertTrue(isset($linkDB[0]));
348 $this->assertFalse(isset($linkDB[0]['linkdate']));
349 $this->assertEquals(0, $linkDB[0]['id']);
350 $this->assertEquals('UserFriendly - Web Designer', $linkDB[0]['title']);
351 $this->assertEquals('http://ars.userfriendly.org/cartoons/?id=20121206', $linkDB[0]['url']);
352 $this->assertEquals('Naming conventions... #private', $linkDB[0]['description']);
353 $this->assertEquals('samba cartoon web', $linkDB[0]['tags']);
354 $this->assertTrue($linkDB[0]['private']);
355 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_142300'), $linkDB[0]['created']);
356
357 $this->assertTrue(isset($linkDB[1]));
358 $this->assertFalse(isset($linkDB[1]['linkdate']));
359 $this->assertEquals(1, $linkDB[1]['id']);
360 $this->assertEquals('UserFriendly - Samba', $linkDB[1]['title']);
361 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_172539'), $linkDB[1]['created']);
362
363 $this->assertTrue(isset($linkDB[2]));
364 $this->assertFalse(isset($linkDB[2]['linkdate']));
365 $this->assertEquals(2, $linkDB[2]['id']);
366 $this->assertEquals('Geek and Poke', $linkDB[2]['title']);
367 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_182539'), $linkDB[2]['created']);
368 $this->assertEquals(DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_190301'), $linkDB[2]['updated']);
369 }
370
371 /**
372 * Test updateMethodDatastoreIds() with the update already applied: nothing to do.
373 */
374 public function testDatastoreIdsNothingToDo()
375 {
376 $refDB = new ReferenceLinkDB();
377 $refDB->write(self::$testDatastore);
378 $linkDB = new LinkDB(self::$testDatastore, true, false);
379
380 $this->conf->set('resource.data_dir', 'sandbox');
381 $this->conf->set('resource.datastore', self::$testDatastore);
382
383 $checksum = hash_file('sha1', self::$testDatastore);
384 $updater = new Updater(array(), $linkDB, $this->conf, true);
385 $this->assertTrue($updater->updateMethodDatastoreIds());
386 $this->assertEquals($checksum, hash_file('sha1', self::$testDatastore));
387 }
388
389 /**
390 * Test updateMethodEscapeMarkdown with markdown plugin enabled
391 * => setting markdown_escape set to false.
392 */
393 public function testEscapeMarkdownSettingToFalse()
394 {
395 $sandboxConf = 'sandbox/config';
396 copy(self::$configFile . '.json.php', $sandboxConf . '.json.php');
397 $this->conf = new ConfigManager($sandboxConf);
398
399 $this->conf->set('general.enabled_plugins', array('markdown'));
400 $updater = new Updater(array(), array(), $this->conf, true);
401 $this->assertTrue($updater->updateMethodEscapeMarkdown());
402 $this->assertFalse($this->conf->get('security.markdown_escape'));
403
404 // reload from file
405 $this->conf = new ConfigManager($sandboxConf);
406 $this->assertFalse($this->conf->get('security.markdown_escape'));
407 }
408
409 /**
410 * Test updateMethodEscapeMarkdown with markdown plugin disabled
411 * => setting markdown_escape set to true.
412 */
413 public function testEscapeMarkdownSettingToTrue()
414 {
415 $sandboxConf = 'sandbox/config';
416 copy(self::$configFile . '.json.php', $sandboxConf . '.json.php');
417 $this->conf = new ConfigManager($sandboxConf);
418
419 $this->conf->set('general.enabled_plugins', array());
420 $updater = new Updater(array(), array(), $this->conf, true);
421 $this->assertTrue($updater->updateMethodEscapeMarkdown());
422 $this->assertTrue($this->conf->get('security.markdown_escape'));
423
424 // reload from file
425 $this->conf = new ConfigManager($sandboxConf);
426 $this->assertTrue($this->conf->get('security.markdown_escape'));
427 }
428
429 /**
430 * Test updateMethodEscapeMarkdown with nothing to do (setting already enabled)
431 */
432 public function testEscapeMarkdownSettingNothingToDoEnabled()
433 {
434 $sandboxConf = 'sandbox/config';
435 copy(self::$configFile . '.json.php', $sandboxConf . '.json.php');
436 $this->conf = new ConfigManager($sandboxConf);
437 $this->conf->set('security.markdown_escape', true);
438 $updater = new Updater(array(), array(), $this->conf, true);
439 $this->assertTrue($updater->updateMethodEscapeMarkdown());
440 $this->assertTrue($this->conf->get('security.markdown_escape'));
441 }
442
443 /**
444 * Test updateMethodEscapeMarkdown with nothing to do (setting already disabled)
445 */
446 public function testEscapeMarkdownSettingNothingToDoDisabled()
447 {
448 $this->conf->set('security.markdown_escape', false);
449 $updater = new Updater(array(), array(), $this->conf, true);
450 $this->assertTrue($updater->updateMethodEscapeMarkdown());
451 $this->assertFalse($this->conf->get('security.markdown_escape'));
452 }
244} 453}
diff --git a/tests/Url/UrlTest.php b/tests/Url/UrlTest.php
index ce82265e..05862372 100644
--- a/tests/Url/UrlTest.php
+++ b/tests/Url/UrlTest.php
@@ -85,6 +85,7 @@ class UrlTest extends PHPUnit_Framework_TestCase
85 $this->assertUrlIsCleaned('?utm_term=1n4l'); 85 $this->assertUrlIsCleaned('?utm_term=1n4l');
86 86
87 $this->assertUrlIsCleaned('?xtor=some-url'); 87 $this->assertUrlIsCleaned('?xtor=some-url');
88 $this->assertUrlIsCleaned('?PHPSESSID=012345678910111213');
88 } 89 }
89 90
90 /** 91 /**
@@ -183,9 +184,9 @@ class UrlTest extends PHPUnit_Framework_TestCase
183 } 184 }
184 185
185 /** 186 /**
186 * Test IndToAscii. 187 * Test International Domain Name to ASCII conversion
187 */ 188 */
188 function testIndToAscii() 189 function testIdnToAscii()
189 { 190 {
190 $ind = 'http://www.académie-française.fr/'; 191 $ind = 'http://www.académie-française.fr/';
191 $expected = 'http://www.xn--acadmie-franaise-npb1a.fr/'; 192 $expected = 'http://www.xn--acadmie-franaise-npb1a.fr/';
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php
index 3073b5eb..6a7870c4 100644
--- a/tests/UtilsTest.php
+++ b/tests/UtilsTest.php
@@ -253,41 +253,4 @@ class UtilsTest extends PHPUnit_Framework_TestCase
253 is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') 253 is_session_id_valid('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
254 ); 254 );
255 } 255 }
256
257 /**
258 * Test text2clickable without a redirector being set.
259 */
260 public function testText2clickableWithoutRedirector()
261 {
262 $text = 'stuff http://hello.there/is=someone#here otherstuff';
263 $expectedText = 'stuff <a href="http://hello.there/is=someone#here">http://hello.there/is=someone#here</a> otherstuff';
264 $processedText = text2clickable($text, '');
265 $this->assertEquals($expectedText, $processedText);
266 }
267
268 /**
269 * Test text2clickable a redirector set.
270 */
271 public function testText2clickableWithRedirector()
272 {
273 $text = 'stuff http://hello.there/is=someone#here otherstuff';
274 $redirector = 'http://redirector.to';
275 $expectedText = 'stuff <a href="'.
276 $redirector .
277 urlencode('http://hello.there/is=someone#here') .
278 '">http://hello.there/is=someone#here</a> otherstuff';
279 $processedText = text2clickable($text, $redirector);
280 $this->assertEquals($expectedText, $processedText);
281 }
282
283 /**
284 * Test testSpace2nbsp.
285 */
286 public function testSpace2nbsp()
287 {
288 $text = ' Are you thrilled by flags ?'. PHP_EOL .' Really?';
289 $expectedText = '&nbsp; Are you &nbsp; thrilled &nbsp;by flags &nbsp; ?'. PHP_EOL .'&nbsp;Really?';
290 $processedText = space2nbsp($text);
291 $this->assertEquals($expectedText, $processedText);
292 }
293} 256}
diff --git a/tests/config/ConfigJsonTest.php b/tests/config/ConfigJsonTest.php
new file mode 100644
index 00000000..07f6ab49
--- /dev/null
+++ b/tests/config/ConfigJsonTest.php
@@ -0,0 +1,133 @@
1<?php
2
3require_once 'application/config/ConfigJson.php';
4
5/**
6 * Class ConfigJsonTest
7 */
8class ConfigJsonTest extends PHPUnit_Framework_TestCase
9{
10 /**
11 * @var ConfigJson
12 */
13 protected $configIO;
14
15 public function setUp()
16 {
17 $this->configIO = new ConfigJson();
18 }
19
20 /**
21 * Read a simple existing config file.
22 */
23 public function testRead()
24 {
25 $conf = $this->configIO->read('tests/utils/config/configJson.json.php');
26 $this->assertEquals('root', $conf['credentials']['login']);
27 $this->assertEquals('lala', $conf['redirector']['url']);
28 $this->assertEquals('tests/utils/config/datastore.php', $conf['resource']['datastore']);
29 $this->assertEquals('1', $conf['plugins']['WALLABAG_VERSION']);
30 }
31
32 /**
33 * Read a non existent config file -> empty array.
34 */
35 public function testReadNonExistent()
36 {
37 $this->assertEquals(array(), $this->configIO->read('nope'));
38 }
39
40 /**
41 * Read a non existent config file -> empty array.
42 *
43 * @expectedException Exception
44 * @expectedExceptionMessage An error occurred while parsing JSON file: error code #4
45 */
46 public function testReadInvalidJson()
47 {
48 $this->configIO->read('tests/utils/config/configInvalid.json.php');
49 }
50
51 /**
52 * Write a new config file.
53 */
54 public function testWriteNew()
55 {
56 $dataFile = 'tests/utils/config/configWrite.json.php';
57 $data = array(
58 'credentials' => array(
59 'login' => 'root',
60 ),
61 'resource' => array(
62 'datastore' => 'data/datastore.php',
63 ),
64 'redirector' => array(
65 'url' => 'lala',
66 ),
67 'plugins' => array(
68 'WALLABAG_VERSION' => '1',
69 )
70 );
71 $this->configIO->write($dataFile, $data);
72 // PHP 5.3 doesn't support json pretty print.
73 if (defined('JSON_PRETTY_PRINT')) {
74 $expected = '{
75 "credentials": {
76 "login": "root"
77 },
78 "resource": {
79 "datastore": "data\/datastore.php"
80 },
81 "redirector": {
82 "url": "lala"
83 },
84 "plugins": {
85 "WALLABAG_VERSION": "1"
86 }
87}';
88 } else {
89 $expected = '{"credentials":{"login":"root"},"resource":{"datastore":"data\/datastore.php"},"redirector":{"url":"lala"},"plugins":{"WALLABAG_VERSION":"1"}}';
90 }
91 $expected = ConfigJson::getPhpHeaders() . $expected . ConfigJson::getPhpSuffix();
92 $this->assertEquals($expected, file_get_contents($dataFile));
93 unlink($dataFile);
94 }
95
96 /**
97 * Overwrite an existing setting.
98 */
99 public function testOverwrite()
100 {
101 $source = 'tests/utils/config/configJson.json.php';
102 $dest = 'tests/utils/config/configOverwrite.json.php';
103 copy($source, $dest);
104 $conf = $this->configIO->read($dest);
105 $conf['redirector']['url'] = 'blabla';
106 $this->configIO->write($dest, $conf);
107 $conf = $this->configIO->read($dest);
108 $this->assertEquals('blabla', $conf['redirector']['url']);
109 unlink($dest);
110 }
111
112 /**
113 * Write to invalid path.
114 *
115 * @expectedException IOException
116 */
117 public function testWriteInvalidArray()
118 {
119 $conf = array('conf' => 'value');
120 @$this->configIO->write(array(), $conf);
121 }
122
123 /**
124 * Write to invalid path.
125 *
126 * @expectedException IOException
127 */
128 public function testWriteInvalidBlank()
129 {
130 $conf = array('conf' => 'value');
131 @$this->configIO->write('', $conf);
132 }
133}
diff --git a/tests/config/ConfigManagerTest.php b/tests/config/ConfigManagerTest.php
new file mode 100644
index 00000000..436e3d67
--- /dev/null
+++ b/tests/config/ConfigManagerTest.php
@@ -0,0 +1,172 @@
1<?php
2
3/**
4 * Unit tests for Class ConfigManagerTest
5 *
6 * Note: it only test the manager with ConfigJson,
7 * ConfigPhp is only a workaround to handle the transition to JSON type.
8 */
9class ConfigManagerTest extends PHPUnit_Framework_TestCase
10{
11 /**
12 * @var ConfigManager
13 */
14 protected $conf;
15
16 public function setUp()
17 {
18 $this->conf = new ConfigManager('tests/utils/config/configJson');
19 }
20
21 /**
22 * Simple config test:
23 * 1. Set settings.
24 * 2. Check settings value.
25 */
26 public function testSetGet()
27 {
28 $this->conf->set('paramInt', 42);
29 $this->conf->set('paramString', 'value1');
30 $this->conf->set('paramBool', false);
31 $this->conf->set('paramArray', array('foo' => 'bar'));
32 $this->conf->set('paramNull', null);
33
34 $this->assertEquals(42, $this->conf->get('paramInt'));
35 $this->assertEquals('value1', $this->conf->get('paramString'));
36 $this->assertFalse($this->conf->get('paramBool'));
37 $this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray'));
38 $this->assertEquals(null, $this->conf->get('paramNull'));
39 }
40
41 /**
42 * Set/write/get config test:
43 * 1. Set settings.
44 * 2. Write it to the config file.
45 * 3. Read the file.
46 * 4. Check settings value.
47 */
48 public function testSetWriteGet()
49 {
50 $this->conf->set('paramInt', 42);
51 $this->conf->set('paramString', 'value1');
52 $this->conf->set('paramBool', false);
53 $this->conf->set('paramArray', array('foo' => 'bar'));
54 $this->conf->set('paramNull', null);
55
56 $this->conf->setConfigFile('tests/utils/config/configTmp');
57 $this->conf->write(true);
58 $this->conf->reload();
59 unlink($this->conf->getConfigFileExt());
60
61 $this->assertEquals(42, $this->conf->get('paramInt'));
62 $this->assertEquals('value1', $this->conf->get('paramString'));
63 $this->assertFalse($this->conf->get('paramBool'));
64 $this->assertEquals(array('foo' => 'bar'), $this->conf->get('paramArray'));
65 $this->assertEquals(null, $this->conf->get('paramNull'));
66 }
67
68 /**
69 * Test set/write/get with nested keys.
70 */
71 public function testSetWriteGetNested()
72 {
73 $this->conf->set('foo.bar.key.stuff', 'testSetWriteGetNested');
74
75 $this->conf->setConfigFile('tests/utils/config/configTmp');
76 $this->conf->write(true);
77 $this->conf->reload();
78 unlink($this->conf->getConfigFileExt());
79
80 $this->assertEquals('testSetWriteGetNested', $this->conf->get('foo.bar.key.stuff'));
81 }
82
83 /**
84 * Set with an empty key.
85 *
86 * @expectedException Exception
87 * @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*#
88 */
89 public function testSetEmptyKey()
90 {
91 $this->conf->set('', 'stuff');
92 }
93
94 /**
95 * Set with an array key.
96 *
97 * @expectedException Exception
98 * @expectedExceptionMessageRegExp #^Invalid setting key parameter. String expected, got.*#
99 */
100 public function testSetArrayKey()
101 {
102 $this->conf->set(array('foo' => 'bar'), 'stuff');
103 }
104
105 /**
106 * Try to write the config without mandatory parameter (e.g. 'login').
107 *
108 * @expectedException MissingFieldConfigException
109 */
110 public function testWriteMissingParameter()
111 {
112 $this->conf->setConfigFile('tests/utils/config/configTmp');
113 $this->assertFalse(file_exists($this->conf->getConfigFileExt()));
114 $this->conf->reload();
115
116 $this->conf->write(true);
117 }
118
119 /**
120 * Try to get non existent config keys.
121 */
122 public function testGetNonExistent()
123 {
124 $this->assertEquals('', $this->conf->get('nope.test'));
125 $this->assertEquals('default', $this->conf->get('nope.test', 'default'));
126 }
127
128 /**
129 * Test the 'exists' method with existent values.
130 */
131 public function testExistsOk()
132 {
133 $this->assertTrue($this->conf->exists('credentials.login'));
134 $this->assertTrue($this->conf->exists('config.foo'));
135 }
136
137 /**
138 * Test the 'exists' method with non existent or invalid values.
139 */
140 public function testExistsKo()
141 {
142 $this->assertFalse($this->conf->exists('nope'));
143 $this->assertFalse($this->conf->exists('nope.nope'));
144 $this->assertFalse($this->conf->exists(''));
145 $this->assertFalse($this->conf->exists(false));
146 }
147
148 /**
149 * Reset the ConfigManager instance.
150 */
151 public function testReset()
152 {
153 $confIO = $this->conf->getConfigIO();
154 $this->conf->reset();
155 $this->assertFalse($confIO === $this->conf->getConfigIO());
156 }
157
158 /**
159 * Reload the config from file.
160 */
161 public function testReload()
162 {
163 $this->conf->setConfigFile('tests/utils/config/configTmp');
164 $newConf = ConfigJson::getPhpHeaders() . '{ "key": "value" }';
165 file_put_contents($this->conf->getConfigFileExt(), $newConf);
166 $this->conf->reload();
167 unlink($this->conf->getConfigFileExt());
168 // Previous conf no longer exists, and new values have been loaded.
169 $this->assertFalse($this->conf->exists('credentials.login'));
170 $this->assertEquals('value', $this->conf->get('key'));
171 }
172}
diff --git a/tests/config/ConfigPhpTest.php b/tests/config/ConfigPhpTest.php
new file mode 100644
index 00000000..58cd8d2a
--- /dev/null
+++ b/tests/config/ConfigPhpTest.php
@@ -0,0 +1,82 @@
1<?php
2
3require_once 'application/config/ConfigPhp.php';
4
5/**
6 * Class ConfigPhpTest
7 */
8class ConfigPhpTest extends PHPUnit_Framework_TestCase
9{
10 /**
11 * @var ConfigPhp
12 */
13 protected $configIO;
14
15 public function setUp()
16 {
17 $this->configIO = new ConfigPhp();
18 }
19
20 /**
21 * Read a simple existing config file.
22 */
23 public function testRead()
24 {
25 $conf = $this->configIO->read('tests/utils/config/configPhp.php');
26 $this->assertEquals('root', $conf['login']);
27 $this->assertEquals('lala', $conf['redirector']);
28 $this->assertEquals('data/datastore.php', $conf['config']['DATASTORE']);
29 $this->assertEquals('1', $conf['plugins']['WALLABAG_VERSION']);
30 }
31
32 /**
33 * Read a non existent config file -> empty array.
34 */
35 public function testReadNonExistent()
36 {
37 $this->assertEquals(array(), $this->configIO->read('nope'));
38 }
39
40 /**
41 * Write a new config file.
42 */
43 public function testWriteNew()
44 {
45 $dataFile = 'tests/utils/config/configWrite.php';
46 $data = array(
47 'login' => 'root',
48 'redirector' => 'lala',
49 'config' => array(
50 'DATASTORE' => 'data/datastore.php',
51 ),
52 'plugins' => array(
53 'WALLABAG_VERSION' => '1',
54 )
55 );
56 $this->configIO->write($dataFile, $data);
57 $expected = '<?php
58$GLOBALS[\'login\'] = \'root\';
59$GLOBALS[\'redirector\'] = \'lala\';
60$GLOBALS[\'config\'][\'DATASTORE\'] = \'data/datastore.php\';
61$GLOBALS[\'plugins\'][\'WALLABAG_VERSION\'] = \'1\';
62';
63 $this->assertEquals($expected, file_get_contents($dataFile));
64 unlink($dataFile);
65 }
66
67 /**
68 * Overwrite an existing setting.
69 */
70 public function testOverwrite()
71 {
72 $source = 'tests/utils/config/configPhp.php';
73 $dest = 'tests/utils/config/configOverwrite.php';
74 copy($source, $dest);
75 $conf = $this->configIO->read($dest);
76 $conf['redirector'] = 'blabla';
77 $this->configIO->write($dest, $conf);
78 $conf = $this->configIO->read($dest);
79 $this->assertEquals('blabla', $conf['redirector']);
80 unlink($dest);
81 }
82}
diff --git a/tests/config/ConfigPluginTest.php b/tests/config/ConfigPluginTest.php
new file mode 100644
index 00000000..3b37cd79
--- /dev/null
+++ b/tests/config/ConfigPluginTest.php
@@ -0,0 +1,121 @@
1<?php
2/**
3 * Config' tests
4 */
5
6require_once 'application/config/ConfigPlugin.php';
7
8/**
9 * Unitary tests for Shaarli config related functions
10 */
11class ConfigPluginTest extends PHPUnit_Framework_TestCase
12{
13 /**
14 * Test save_plugin_config with valid data.
15 *
16 * @throws PluginConfigOrderException
17 */
18 public function testSavePluginConfigValid()
19 {
20 $data = array(
21 'order_plugin1' => 2, // no plugin related
22 'plugin2' => 0, // new - at the end
23 'plugin3' => 0, // 2nd
24 'order_plugin3' => 8,
25 'plugin4' => 0, // 1st
26 'order_plugin4' => 5,
27 );
28
29 $expected = array(
30 'plugin3',
31 'plugin4',
32 'plugin2',
33 );
34
35 $out = save_plugin_config($data);
36 $this->assertEquals($expected, $out);
37 }
38
39 /**
40 * Test save_plugin_config with invalid data.
41 *
42 * @expectedException PluginConfigOrderException
43 */
44 public function testSavePluginConfigInvalid()
45 {
46 $data = array(
47 'plugin2' => 0,
48 'plugin3' => 0,
49 'order_plugin3' => 0,
50 'plugin4' => 0,
51 'order_plugin4' => 0,
52 );
53
54 save_plugin_config($data);
55 }
56
57 /**
58 * Test save_plugin_config without data.
59 */
60 public function testSavePluginConfigEmpty()
61 {
62 $this->assertEquals(array(), save_plugin_config(array()));
63 }
64
65 /**
66 * Test validate_plugin_order with valid data.
67 */
68 public function testValidatePluginOrderValid()
69 {
70 $data = array(
71 'order_plugin1' => 2,
72 'plugin2' => 0,
73 'plugin3' => 0,
74 'order_plugin3' => 1,
75 'plugin4' => 0,
76 'order_plugin4' => 5,
77 );
78
79 $this->assertTrue(validate_plugin_order($data));
80 }
81
82 /**
83 * Test validate_plugin_order with invalid data.
84 */
85 public function testValidatePluginOrderInvalid()
86 {
87 $data = array(
88 'order_plugin1' => 2,
89 'order_plugin3' => 1,
90 'order_plugin4' => 1,
91 );
92
93 $this->assertFalse(validate_plugin_order($data));
94 }
95
96 /**
97 * Test load_plugin_parameter_values.
98 */
99 public function testLoadPluginParameterValues()
100 {
101 $plugins = array(
102 'plugin_name' => array(
103 'parameters' => array(
104 'param1' => array('value' => true),
105 'param2' => array('value' => false),
106 'param3' => array('value' => ''),
107 )
108 )
109 );
110
111 $parameters = array(
112 'param1' => 'value1',
113 'param2' => 'value2',
114 );
115
116 $result = load_plugin_parameter_values($plugins, $parameters);
117 $this->assertEquals('value1', $result['plugin_name']['parameters']['param1']['value']);
118 $this->assertEquals('value2', $result['plugin_name']['parameters']['param2']['value']);
119 $this->assertEquals('', $result['plugin_name']['parameters']['param3']['value']);
120 }
121}
diff --git a/tests/plugins/PluginArchiveorgTest.php b/tests/plugins/PluginArchiveorgTest.php
index dbc52bc8..4daa4c9d 100644
--- a/tests/plugins/PluginArchiveorgTest.php
+++ b/tests/plugins/PluginArchiveorgTest.php
@@ -7,8 +7,8 @@
7require_once 'plugins/archiveorg/archiveorg.php'; 7require_once 'plugins/archiveorg/archiveorg.php';
8 8
9/** 9/**
10 * Class PlugQrcodeTest 10 * Class PluginArchiveorgTest
11 * Unit test for the QR-Code plugin 11 * Unit test for the archiveorg plugin
12 */ 12 */
13class PluginArchiveorgTest extends PHPUnit_Framework_TestCase 13class PluginArchiveorgTest extends PHPUnit_Framework_TestCase
14{ 14{
@@ -21,21 +21,25 @@ class PluginArchiveorgTest extends PHPUnit_Framework_TestCase
21 } 21 }
22 22
23 /** 23 /**
24 * Test render_linklist hook. 24 * Test render_linklist hook on external links.
25 */ 25 */
26 function testArchiveorgLinklist() 26 function testArchiveorgLinklistOnExternalLinks()
27 { 27 {
28 $str = 'http://randomstr.com/test'; 28 $str = 'http://randomstr.com/test';
29
29 $data = array( 30 $data = array(
30 'title' => $str, 31 'title' => $str,
31 'links' => array( 32 'links' => array(
32 array( 33 array(
33 'url' => $str, 34 'url' => $str,
35 'private' => 0,
36 'real_url' => $str
34 ) 37 )
35 ) 38 )
36 ); 39 );
37 40
38 $data = hook_archiveorg_render_linklist($data); 41 $data = hook_archiveorg_render_linklist($data);
42
39 $link = $data['links'][0]; 43 $link = $data['links'][0];
40 // data shouldn't be altered 44 // data shouldn't be altered
41 $this->assertEquals($str, $data['title']); 45 $this->assertEquals($str, $data['title']);
@@ -44,5 +48,95 @@ class PluginArchiveorgTest extends PHPUnit_Framework_TestCase
44 // plugin data 48 // plugin data
45 $this->assertEquals(1, count($link['link_plugin'])); 49 $this->assertEquals(1, count($link['link_plugin']));
46 $this->assertNotFalse(strpos($link['link_plugin'][0], $str)); 50 $this->assertNotFalse(strpos($link['link_plugin'][0], $str));
51
52 }
53
54 /**
55 * Test render_linklist hook on internal links.
56 */
57 function testArchiveorgLinklistOnInternalLinks()
58 {
59 $internalLink1 = 'http://shaarli.shaarli/?qvMAqg';
60 $internalLinkRealURL1 = '?qvMAqg';
61
62 $internalLink2 = 'http://shaarli.shaarli/?2_7zww';
63 $internalLinkRealURL2 = '?2_7zww';
64
65 $internalLink3 = 'http://shaarli.shaarli/?z7u-_Q';
66 $internalLinkRealURL3 = '?z7u-_Q';
67
68 $data = array(
69 'title' => $internalLink1,
70 'links' => array(
71 array(
72 'url' => $internalLink1,
73 'private' => 0,
74 'real_url' => $internalLinkRealURL1
75 ),
76 array(
77 'url' => $internalLink1,
78 'private' => 1,
79 'real_url' => $internalLinkRealURL1
80 ),
81 array(
82 'url' => $internalLink2,
83 'private' => 0,
84 'real_url' => $internalLinkRealURL2
85 ),
86 array(
87 'url' => $internalLink2,
88 'private' => 1,
89 'real_url' => $internalLinkRealURL2
90 ),
91 array(
92 'url' => $internalLink3,
93 'private' => 0,
94 'real_url' => $internalLinkRealURL3
95 ),
96 array(
97 'url' => $internalLink3,
98 'private' => 1,
99 'real_url' => $internalLinkRealURL3
100 )
101 )
102 );
103
104
105 $data = hook_archiveorg_render_linklist($data);
106
107 // Case n°1: first link type, public
108 $link = $data['links'][0];
109
110 $this->assertEquals(1, count($link['link_plugin']));
111 $this->assertNotFalse(strpos($link['link_plugin'][0], $internalLink1));
112
113 // Case n°2: first link type, private
114 $link = $data['links'][1];
115
116 $this->assertArrayNotHasKey('link_plugin', $link);
117
118 // Case n°3: second link type, public
119 $link = $data['links'][2];
120
121 $this->assertEquals(1, count($link['link_plugin']));
122 $this->assertNotFalse(strpos($link['link_plugin'][0], $internalLink2));
123
124 // Case n°4: second link type, private
125 $link = $data['links'][3];
126
127 $this->assertArrayNotHasKey('link_plugin', $link);
128
129 // Case n°5: third link type, public
130 $link = $data['links'][4];
131
132 $this->assertEquals(1, count($link['link_plugin']));
133 $this->assertNotFalse(strpos($link['link_plugin'][0], $internalLink3));
134
135 // Case n°6: third link type, private
136 $link = $data['links'][5];
137
138 $this->assertArrayNotHasKey('link_plugin', $link);
139
47 } 140 }
141
48} 142}
diff --git a/tests/plugins/PluginIssoTest.php b/tests/plugins/PluginIssoTest.php
new file mode 100644
index 00000000..6b7904dd
--- /dev/null
+++ b/tests/plugins/PluginIssoTest.php
@@ -0,0 +1,151 @@
1<?php
2
3require_once 'plugins/isso/isso.php';
4
5/**
6 * Class PluginIssoTest
7 *
8 * Test the Isso plugin (comment system).
9 */
10class PluginIssoTest extends PHPUnit_Framework_TestCase
11{
12 /**
13 * Reset plugin path
14 */
15 function setUp()
16 {
17 PluginManager::$PLUGINS_PATH = 'plugins';
18 }
19
20 /**
21 * Test Isso init without errors.
22 */
23 function testWallabagInitNoError()
24 {
25 $conf = new ConfigManager('');
26 $conf->set('plugins.ISSO_SERVER', 'value');
27 $errors = isso_init($conf);
28 $this->assertEmpty($errors);
29 }
30
31 /**
32 * Test Isso init with errors.
33 */
34 function testWallabagInitError()
35 {
36 $conf = new ConfigManager('');
37 $errors = isso_init($conf);
38 $this->assertNotEmpty($errors);
39 }
40
41 /**
42 * Test render_linklist hook with valid settings to display the comment form.
43 */
44 function testIssoDisplayed()
45 {
46 $conf = new ConfigManager('');
47 $conf->set('plugins.ISSO_SERVER', 'value');
48
49 $str = 'http://randomstr.com/test';
50 $date = '20161118_100001';
51 $data = array(
52 'title' => $str,
53 'links' => array(
54 array(
55 'id' => 12,
56 'url' => $str,
57 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date),
58 )
59 )
60 );
61
62 $data = hook_isso_render_linklist($data, $conf);
63
64 // data shouldn't be altered
65 $this->assertEquals($str, $data['title']);
66 $this->assertEquals($str, $data['links'][0]['url']);
67
68 // plugin data
69 $this->assertEquals(1, count($data['plugin_end_zone']));
70 $this->assertNotFalse(strpos(
71 $data['plugin_end_zone'][0],
72 'data-isso-id="'. $data['links'][0]['id'] .'"'
73 ));
74 $this->assertNotFalse(strpos(
75 $data['plugin_end_zone'][0],
76 'data-title="'. $data['links'][0]['id'] .'"'
77 ));
78 $this->assertNotFalse(strpos($data['plugin_end_zone'][0], 'embed.min.js'));
79 }
80
81 /**
82 * Test isso plugin when multiple links are displayed (shouldn't be displayed).
83 */
84 function testIssoMultipleLinks()
85 {
86 $conf = new ConfigManager('');
87 $conf->set('plugins.ISSO_SERVER', 'value');
88
89 $str = 'http://randomstr.com/test';
90 $date1 = '20161118_100001';
91 $date2 = '20161118_100002';
92 $data = array(
93 'title' => $str,
94 'links' => array(
95 array(
96 'id' => 12,
97 'url' => $str,
98 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date1),
99 ),
100 array(
101 'id' => 13,
102 'url' => $str . '2',
103 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date2),
104 ),
105 )
106 );
107
108 $processed = hook_isso_render_linklist($data, $conf);
109 // data shouldn't be altered
110 $this->assertEquals($data, $processed);
111 }
112
113 /**
114 * Test isso plugin when using search (shouldn't be displayed).
115 */
116 function testIssoNotDisplayedWhenSearch()
117 {
118 $conf = new ConfigManager('');
119 $conf->set('plugins.ISSO_SERVER', 'value');
120
121 $str = 'http://randomstr.com/test';
122 $date = '20161118_100001';
123 $data = array(
124 'title' => $str,
125 'links' => array(
126 array(
127 'id' => 12,
128 'url' => $str,
129 'created' => DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $date),
130 )
131 ),
132 'search_term' => $str
133 );
134
135 $processed = hook_isso_render_linklist($data, $conf);
136
137 // data shouldn't be altered
138 $this->assertEquals($data, $processed);
139 }
140
141 /**
142 * Test isso plugin without server configuration (shouldn't be displayed).
143 */
144 function testIssoWithoutConf()
145 {
146 $data = 'abc';
147 $conf = new ConfigManager('');
148 $processed = hook_isso_render_linklist($data, $conf);
149 $this->assertEquals($data, $processed);
150 }
151}
diff --git a/tests/plugins/PluginMarkdownTest.php b/tests/plugins/PluginMarkdownTest.php
index fa7e1d52..f1e1acf8 100644
--- a/tests/plugins/PluginMarkdownTest.php
+++ b/tests/plugins/PluginMarkdownTest.php
@@ -8,17 +8,23 @@ require_once 'application/Utils.php';
8require_once 'plugins/markdown/markdown.php'; 8require_once 'plugins/markdown/markdown.php';
9 9
10/** 10/**
11 * Class PlugQrcodeTest 11 * Class PluginMarkdownTest
12 * Unit test for the QR-Code plugin 12 * Unit test for the Markdown plugin
13 */ 13 */
14class PluginMarkdownTest extends PHPUnit_Framework_TestCase 14class PluginMarkdownTest extends PHPUnit_Framework_TestCase
15{ 15{
16 /** 16 /**
17 * @var ConfigManager instance.
18 */
19 protected $conf;
20
21 /**
17 * Reset plugin path 22 * Reset plugin path
18 */ 23 */
19 function setUp() 24 function setUp()
20 { 25 {
21 PluginManager::$PLUGINS_PATH = 'plugins'; 26 PluginManager::$PLUGINS_PATH = 'plugins';
27 $this->conf = new ConfigManager('tests/utils/config/configJson');
22 } 28 }
23 29
24 /** 30 /**
@@ -36,7 +42,7 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
36 ), 42 ),
37 ); 43 );
38 44
39 $data = hook_markdown_render_linklist($data); 45 $data = hook_markdown_render_linklist($data, $this->conf);
40 $this->assertNotFalse(strpos($data['links'][0]['description'], '<h1>')); 46 $this->assertNotFalse(strpos($data['links'][0]['description'], '<h1>'));
41 $this->assertNotFalse(strpos($data['links'][0]['description'], '<p>')); 47 $this->assertNotFalse(strpos($data['links'][0]['description'], '<p>'));
42 } 48 }
@@ -61,7 +67,7 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
61 ), 67 ),
62 ); 68 );
63 69
64 $data = hook_markdown_render_daily($data); 70 $data = hook_markdown_render_daily($data, $this->conf);
65 $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '<h1>')); 71 $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '<h1>'));
66 $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '<p>')); 72 $this->assertNotFalse(strpos($data['cols'][0][0]['formatedDescription'], '<p>'));
67 } 73 }
@@ -110,6 +116,8 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
110 $output = escape($input); 116 $output = escape($input);
111 $input .= '<a href="#" onmouseHover="alert(\'xss\');" attr="tt">link</a>'; 117 $input .= '<a href="#" onmouseHover="alert(\'xss\');" attr="tt">link</a>';
112 $output .= '<a href="#" attr="tt">link</a>'; 118 $output .= '<a href="#" attr="tt">link</a>';
119 $input .= '<a href="#" onmouseHover=alert(\'xss\'); attr="tt">link</a>';
120 $output .= '<a href="#" attr="tt">link</a>';
113 $this->assertEquals($output, sanitize_html($input)); 121 $this->assertEquals($output, sanitize_html($input));
114 // Do not touch escaped HTML. 122 // Do not touch escaped HTML.
115 $input = escape($input); 123 $input = escape($input);
@@ -125,12 +133,16 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
125 $data = array( 133 $data = array(
126 'links' => array(array( 134 'links' => array(array(
127 'description' => $str, 135 'description' => $str,
128 'tags' => NO_MD_TAG 136 'tags' => NO_MD_TAG,
137 'taglist' => array(NO_MD_TAG),
129 )) 138 ))
130 ); 139 );
131 140
132 $data = hook_markdown_render_linklist($data); 141 $processed = hook_markdown_render_linklist($data, $this->conf);
133 $this->assertEquals($str, $data['links'][0]['description']); 142 $this->assertEquals($str, $processed['links'][0]['description']);
143
144 $processed = hook_markdown_render_feed($data, $this->conf);
145 $this->assertEquals($str, $processed['links'][0]['description']);
134 146
135 $data = array( 147 $data = array(
136 // Columns data 148 // Columns data
@@ -140,13 +152,82 @@ class PluginMarkdownTest extends PHPUnit_Framework_TestCase
140 // nth link 152 // nth link
141 0 => array( 153 0 => array(
142 'formatedDescription' => $str, 154 'formatedDescription' => $str,
143 'tags' => NO_MD_TAG 155 'tags' => NO_MD_TAG,
156 'taglist' => array(),
144 ), 157 ),
145 ), 158 ),
146 ), 159 ),
147 ); 160 );
148 161
149 $data = hook_markdown_render_daily($data); 162 $data = hook_markdown_render_daily($data, $this->conf);
150 $this->assertEquals($str, $data['cols'][0][0]['formatedDescription']); 163 $this->assertEquals($str, $data['cols'][0][0]['formatedDescription']);
151 } 164 }
165
166 /**
167 * Test that a close value to nomarkdown is not understand as nomarkdown (previous value `.nomarkdown`).
168 */
169 function testNoMarkdownNotExcactlyMatching()
170 {
171 $str = 'All _work_ and `no play` makes Jack a *dull* boy.';
172 $data = array(
173 'links' => array(array(
174 'description' => $str,
175 'tags' => '.' . NO_MD_TAG,
176 'taglist' => array('.'. NO_MD_TAG),
177 ))
178 );
179
180 $data = hook_markdown_render_feed($data, $this->conf);
181 $this->assertContains('<em>', $data['links'][0]['description']);
182 }
183
184 /**
185 * Test hashtag links processed with markdown.
186 */
187 function testMarkdownHashtagLinks()
188 {
189 $md = file_get_contents('tests/plugins/resources/markdown.md');
190 $md = format_description($md);
191 $html = file_get_contents('tests/plugins/resources/markdown.html');
192
193 $data = process_markdown($md);
194 $this->assertEquals($html, $data);
195 }
196
197 /**
198 * Make sure that the HTML tags are escaped.
199 */
200 public function testMarkdownWithHtmlEscape()
201 {
202 $md = '**strong** <strong>strong</strong>';
203 $html = '<div class="markdown"><p><strong>strong</strong> &lt;strong&gt;strong&lt;/strong&gt;</p></div>';
204 $data = array(
205 'links' => array(
206 0 => array(
207 'description' => $md,
208 ),
209 ),
210 );
211 $data = hook_markdown_render_linklist($data, $this->conf);
212 $this->assertEquals($html, $data['links'][0]['description']);
213 }
214
215 /**
216 * Make sure that the HTML tags aren't escaped with the setting set to false.
217 */
218 public function testMarkdownWithHtmlNoEscape()
219 {
220 $this->conf->set('security.markdown_escape', false);
221 $md = '**strong** <strong>strong</strong>';
222 $html = '<div class="markdown"><p><strong>strong</strong> <strong>strong</strong></p></div>';
223 $data = array(
224 'links' => array(
225 0 => array(
226 'description' => $md,
227 ),
228 ),
229 );
230 $data = hook_markdown_render_linklist($data, $this->conf);
231 $this->assertEquals($html, $data['links'][0]['description']);
232 }
152} 233}
diff --git a/tests/plugins/PluginReadityourselfTest.php b/tests/plugins/PluginReadityourselfTest.php
index 8bf17bf1..532db146 100644
--- a/tests/plugins/PluginReadityourselfTest.php
+++ b/tests/plugins/PluginReadityourselfTest.php
@@ -21,11 +21,33 @@ class PluginReadityourselfTest extends PHPUnit_Framework_TestCase
21 } 21 }
22 22
23 /** 23 /**
24 * Test Readityourself init without errors.
25 */
26 function testReadityourselfInitNoError()
27 {
28 $conf = new ConfigManager('');
29 $conf->set('plugins.READITYOUSELF_URL', 'value');
30 $errors = readityourself_init($conf);
31 $this->assertEmpty($errors);
32 }
33
34 /**
35 * Test Readityourself init with errors.
36 */
37 function testReadityourselfInitError()
38 {
39 $conf = new ConfigManager('');
40 $errors = readityourself_init($conf);
41 $this->assertNotEmpty($errors);
42 }
43
44 /**
24 * Test render_linklist hook. 45 * Test render_linklist hook.
25 */ 46 */
26 function testReadityourselfLinklist() 47 function testReadityourselfLinklist()
27 { 48 {
28 $GLOBALS['plugins']['READITYOUSELF_URL'] = 'value'; 49 $conf = new ConfigManager('');
50 $conf->set('plugins.READITYOUSELF_URL', 'value');
29 $str = 'http://randomstr.com/test'; 51 $str = 'http://randomstr.com/test';
30 $data = array( 52 $data = array(
31 'title' => $str, 53 'title' => $str,
@@ -36,7 +58,7 @@ class PluginReadityourselfTest extends PHPUnit_Framework_TestCase
36 ) 58 )
37 ); 59 );
38 60
39 $data = hook_readityourself_render_linklist($data); 61 $data = hook_readityourself_render_linklist($data, $conf);
40 $link = $data['links'][0]; 62 $link = $data['links'][0];
41 // data shouldn't be altered 63 // data shouldn't be altered
42 $this->assertEquals($str, $data['title']); 64 $this->assertEquals($str, $data['title']);
@@ -52,7 +74,8 @@ class PluginReadityourselfTest extends PHPUnit_Framework_TestCase
52 */ 74 */
53 function testReadityourselfLinklistWithoutConfig() 75 function testReadityourselfLinklistWithoutConfig()
54 { 76 {
55 unset($GLOBALS['plugins']['READITYOUSELF_URL']); 77 $conf = new ConfigManager('');
78 $conf->set('plugins.READITYOUSELF_URL', null);
56 $str = 'http://randomstr.com/test'; 79 $str = 'http://randomstr.com/test';
57 $data = array( 80 $data = array(
58 'title' => $str, 81 'title' => $str,
@@ -63,7 +86,7 @@ class PluginReadityourselfTest extends PHPUnit_Framework_TestCase
63 ) 86 )
64 ); 87 );
65 88
66 $data = hook_readityourself_render_linklist($data); 89 $data = hook_readityourself_render_linklist($data, $conf);
67 $link = $data['links'][0]; 90 $link = $data['links'][0];
68 // data shouldn't be altered 91 // data shouldn't be altered
69 $this->assertEquals($str, $data['title']); 92 $this->assertEquals($str, $data['title']);
diff --git a/tests/plugins/PluginWallabagTest.php b/tests/plugins/PluginWallabagTest.php
index 5d3a60e0..2c268cbd 100644
--- a/tests/plugins/PluginWallabagTest.php
+++ b/tests/plugins/PluginWallabagTest.php
@@ -21,11 +21,33 @@ class PluginWallabagTest extends PHPUnit_Framework_TestCase
21 } 21 }
22 22
23 /** 23 /**
24 * Test wallabag init without errors.
25 */
26 function testWallabagInitNoError()
27 {
28 $conf = new ConfigManager('');
29 $conf->set('plugins.WALLABAG_URL', 'value');
30 $errors = wallabag_init($conf);
31 $this->assertEmpty($errors);
32 }
33
34 /**
35 * Test wallabag init with errors.
36 */
37 function testWallabagInitError()
38 {
39 $conf = new ConfigManager('');
40 $errors = wallabag_init($conf);
41 $this->assertNotEmpty($errors);
42 }
43
44 /**
24 * Test render_linklist hook. 45 * Test render_linklist hook.
25 */ 46 */
26 function testWallabagLinklist() 47 function testWallabagLinklist()
27 { 48 {
28 $GLOBALS['plugins']['WALLABAG_URL'] = 'value'; 49 $conf = new ConfigManager('');
50 $conf->set('plugins.WALLABAG_URL', 'value');
29 $str = 'http://randomstr.com/test'; 51 $str = 'http://randomstr.com/test';
30 $data = array( 52 $data = array(
31 'title' => $str, 53 'title' => $str,
@@ -36,7 +58,7 @@ class PluginWallabagTest extends PHPUnit_Framework_TestCase
36 ) 58 )
37 ); 59 );
38 60
39 $data = hook_wallabag_render_linklist($data); 61 $data = hook_wallabag_render_linklist($data, $conf);
40 $link = $data['links'][0]; 62 $link = $data['links'][0];
41 // data shouldn't be altered 63 // data shouldn't be altered
42 $this->assertEquals($str, $data['title']); 64 $this->assertEquals($str, $data['title']);
@@ -45,7 +67,6 @@ class PluginWallabagTest extends PHPUnit_Framework_TestCase
45 // plugin data 67 // plugin data
46 $this->assertEquals(1, count($link['link_plugin'])); 68 $this->assertEquals(1, count($link['link_plugin']));
47 $this->assertNotFalse(strpos($link['link_plugin'][0], urlencode($str))); 69 $this->assertNotFalse(strpos($link['link_plugin'][0], urlencode($str)));
48 $this->assertNotFalse(strpos($link['link_plugin'][0], $GLOBALS['plugins']['WALLABAG_URL'])); 70 $this->assertNotFalse(strpos($link['link_plugin'][0], $conf->get('plugins.WALLABAG_URL')));
49 } 71 }
50} 72}
51
diff --git a/tests/plugins/resources/markdown.html b/tests/plugins/resources/markdown.html
new file mode 100644
index 00000000..07a5a32e
--- /dev/null
+++ b/tests/plugins/resources/markdown.html
@@ -0,0 +1,24 @@
1<div class="markdown"><ul>
2<li>test:
3<ul>
4<li><a href="http://link.tld">zero</a></li>
5<li><a href="http://link.tld">two</a></li>
6<li><a href="http://link.tld">three</a></li>
7</ul></li>
8</ul>
9<ol>
10<li><a href="http://link.tld">zero</a>
11<ol>
12<li><a href="http://link.tld">two</a></li>
13<li><a href="http://link.tld">three</a></li>
14<li><a href="http://link.tld">four</a></li>
15<li>foo &lt;a href=&quot;?addtag=foobar&quot; title=&quot;Hashtag foobar&quot;&gt;#foobar&lt;/a&gt;</li>
16</ol></li>
17</ol>
18<p>&lt;a href=&quot;?addtag=foobar&quot; title=&quot;Hashtag foobar&quot;&gt;#foobar&lt;/a&gt; foo <code>lol #foo</code> &lt;a href=&quot;?addtag=bar&quot; title=&quot;Hashtag bar&quot;&gt;#bar&lt;/a&gt;</p>
19<p>fsdfs <a href="http://link.tld">http://link.tld</a> &lt;a href=&quot;?addtag=foobar&quot; title=&quot;Hashtag foobar&quot;&gt;#foobar&lt;/a&gt; <code>http://link.tld</code></p>
20<pre><code>http://link.tld #foobar
21next #foo</code></pre>
22<p>Block:</p>
23<pre><code>lorem ipsum #foobar http://link.tld
24#foobar http://link.tld</code></pre></div> \ No newline at end of file
diff --git a/tests/plugins/resources/markdown.md b/tests/plugins/resources/markdown.md
new file mode 100644
index 00000000..0b8be7c5
--- /dev/null
+++ b/tests/plugins/resources/markdown.md
@@ -0,0 +1,24 @@
1* test:
2 * [zero](http://link.tld)
3 + [two](http://link.tld)
4 - [three](http://link.tld)
5
61. [zero](http://link.tld)
7 2. [two](http://link.tld)
8 3. [three](http://link.tld)
9 4. [four](http://link.tld)
10 5. foo #foobar
11
12#foobar foo `lol #foo` #bar
13
14fsdfs http://link.tld #foobar `http://link.tld`
15
16 http://link.tld #foobar
17 next #foo
18
19Block:
20
21```
22lorem ipsum #foobar http://link.tld
23#foobar http://link.tld
24``` \ No newline at end of file
diff --git a/tests/plugins/test/test.meta b/tests/plugins/test/test.meta
index ab999ed4..26f243f0 100644
--- a/tests/plugins/test/test.meta
+++ b/tests/plugins/test/test.meta
@@ -1,2 +1,4 @@
1description="test plugin" 1description="test plugin"
2parameters="pop;hip" \ No newline at end of file 2parameters="pop;hip"
3parameter.pop="pop description"
4parameter.hip= \ No newline at end of file
diff --git a/tests/utils/ReferenceLinkDB.php b/tests/utils/ReferenceLinkDB.php
index dc4f5dfa..36d58c68 100644
--- a/tests/utils/ReferenceLinkDB.php
+++ b/tests/utils/ReferenceLinkDB.php
@@ -4,7 +4,7 @@
4 */ 4 */
5class ReferenceLinkDB 5class ReferenceLinkDB
6{ 6{
7 public static $NB_LINKS_TOTAL = 7; 7 public static $NB_LINKS_TOTAL = 8;
8 8
9 private $_links = array(); 9 private $_links = array();
10 private $_publicCount = 0; 10 private $_publicCount = 0;
@@ -13,86 +13,111 @@ class ReferenceLinkDB
13 /** 13 /**
14 * Populates the test DB with reference data 14 * Populates the test DB with reference data
15 */ 15 */
16 function __construct() 16 public function __construct()
17 { 17 {
18 $this->addLink( 18 $this->addLink(
19 41,
19 'Link title: @website', 20 'Link title: @website',
20 '?WDWyig', 21 '?WDWyig',
21 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this.', 22 'Stallman has a beard and is part of the Free Software Foundation (or not). Seriously, read this. #hashtag',
22 0, 23 0,
23 '20150310_114651', 24 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114651'),
24 'stuff' 25 'sTuff',
26 null,
27 'WDWyig'
25 ); 28 );
26 29
27 $this->addLink( 30 $this->addLink(
31 42,
32 'Note: I have a big ID but an old date',
33 '?WDWyig',
34 'Used to test links reordering.',
35 0,
36 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20100310_101010'),
37 'ut'
38 );
39
40 $this->addLink(
41 8,
28 'Free as in Freedom 2.0 @website', 42 'Free as in Freedom 2.0 @website',
29 'https://static.fsf.org/nosvn/faif-2.0.pdf', 43 'https://static.fsf.org/nosvn/faif-2.0.pdf',
30 'Richard Stallman and the Free Software Revolution. Read this.', 44 'Richard Stallman and the Free Software Revolution. Read this. #hashtag',
31 0, 45 0,
32 '20150310_114633', 46 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20150310_114633'),
33 'free gnu software stallman -exclude stuff' 47 'free gnu software stallman -exclude stuff hashtag',
48 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20160803_093033')
34 ); 49 );
35 50
36 $this->addLink( 51 $this->addLink(
52 7,
37 'MediaGoblin', 53 'MediaGoblin',
38 'http://mediagoblin.org/', 54 'http://mediagoblin.org/',
39 'A free software media publishing platform', 55 'A free software media publishing platform #hashtagOther',
40 0, 56 0,
41 '20130614_184135', 57 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20130614_184135'),
42 'gnu media web .hidden' 58 'gnu media web .hidden hashtag',
59 null,
60 'IuWvgA'
43 ); 61 );
44 62
45 $this->addLink( 63 $this->addLink(
64 6,
46 'w3c-markup-validator', 65 'w3c-markup-validator',
47 'https://dvcs.w3.org/hg/markup-validator/summary', 66 'https://dvcs.w3.org/hg/markup-validator/summary',
48 'Mercurial repository for the W3C Validator', 67 'Mercurial repository for the W3C Validator #private',
49 1, 68 1,
50 '20141125_084734', 69 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20141125_084734'),
51 'css html w3c web Mercurial' 70 'css html w3c web Mercurial'
52 ); 71 );
53 72
54 $this->addLink( 73 $this->addLink(
74 4,
55 'UserFriendly - Web Designer', 75 'UserFriendly - Web Designer',
56 'http://ars.userfriendly.org/cartoons/?id=20121206', 76 'http://ars.userfriendly.org/cartoons/?id=20121206',
57 'Naming conventions...', 77 'Naming conventions... #private',
58 0, 78 0,
59 '20121206_142300', 79 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_142300'),
60 'dev cartoon web' 80 'dev cartoon web'
61 ); 81 );
62 82
63 $this->addLink( 83 $this->addLink(
84 1,
64 'UserFriendly - Samba', 85 'UserFriendly - Samba',
65 'http://ars.userfriendly.org/cartoons/?id=20010306', 86 'http://ars.userfriendly.org/cartoons/?id=20010306',
66 'Tropical printing', 87 'Tropical printing',
67 0, 88 0,
68 '20121206_172539', 89 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_172539'),
69 'samba cartoon web' 90 'samba cartoon web'
70 ); 91 );
71 92
72 $this->addLink( 93 $this->addLink(
94 0,
73 'Geek and Poke', 95 'Geek and Poke',
74 'http://geek-and-poke.com/', 96 'http://geek-and-poke.com/',
75 '', 97 '',
76 1, 98 1,
77 '20121206_182539', 99 DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_182539'),
78 'dev cartoon' 100 'dev cartoon tag1 tag2 tag3 tag4 '
79 ); 101 );
80 } 102 }
81 103
82 /** 104 /**
83 * Adds a new link 105 * Adds a new link
84 */ 106 */
85 protected function addLink($title, $url, $description, $private, $date, $tags) 107 protected function addLink($id, $title, $url, $description, $private, $date, $tags, $updated = '', $shorturl = '')
86 { 108 {
87 $link = array( 109 $link = array(
110 'id' => $id,
88 'title' => $title, 111 'title' => $title,
89 'url' => $url, 112 'url' => $url,
90 'description' => $description, 113 'description' => $description,
91 'private' => $private, 114 'private' => $private,
92 'linkdate' => $date,
93 'tags' => $tags, 115 'tags' => $tags,
116 'created' => $date,
117 'updated' => $updated,
118 'shorturl' => $shorturl ? $shorturl : smallHash($date->format(LinkDB::LINK_DATE_FORMAT) . $id),
94 ); 119 );
95 $this->_links[$date] = $link; 120 $this->_links[$id] = $link;
96 121
97 if ($private) { 122 if ($private) {
98 $this->_privateCount++; 123 $this->_privateCount++;
@@ -140,4 +165,14 @@ class ReferenceLinkDB
140 { 165 {
141 return $this->_links; 166 return $this->_links;
142 } 167 }
168
169 /**
170 * Setter to override link creation.
171 *
172 * @param array $links List of links.
173 */
174 public function setLinks($links)
175 {
176 $this->_links = $links;
177 }
143} 178}
diff --git a/tests/utils/config/configInvalid.json.php b/tests/utils/config/configInvalid.json.php
new file mode 100644
index 00000000..e39d640a
--- /dev/null
+++ b/tests/utils/config/configInvalid.json.php
@@ -0,0 +1,5 @@
1<?php /*
2{
3 bad: bad,
4}
5*/ ?>
diff --git a/tests/utils/config/configJson.json.php b/tests/utils/config/configJson.json.php
new file mode 100644
index 00000000..06a302e8
--- /dev/null
+++ b/tests/utils/config/configJson.json.php
@@ -0,0 +1,34 @@
1<?php /*
2{
3 "credentials": {
4 "login":"root",
5 "hash":"hash",
6 "salt":"salt"
7 },
8 "security": {
9 "session_protection_disabled":false
10 },
11 "general": {
12 "timezone":"Europe\/Paris",
13 "title": "Shaarli",
14 "header_link": "?"
15 },
16 "privacy": {
17 "default_private_links":true
18 },
19 "redirector": {
20 "url":"lala"
21 },
22 "config": {
23 "foo": "bar"
24 },
25 "resource": {
26 "datastore": "tests\/utils\/config\/datastore.php",
27 "data_dir": "tests\/utils\/config"
28 },
29 "plugins": {
30 "WALLABAG_VERSION": 1
31 }
32}
33*/ ?>
34
diff --git a/tests/utils/config/configPhp.php b/tests/utils/config/configPhp.php
new file mode 100644
index 00000000..0e034175
--- /dev/null
+++ b/tests/utils/config/configPhp.php
@@ -0,0 +1,14 @@
1<?php
2$GLOBALS['login'] = 'root';
3$GLOBALS['hash'] = 'hash';
4$GLOBALS['salt'] = 'salt';
5$GLOBALS['timezone'] = 'Europe/Paris';
6$GLOBALS['title'] = 'title';
7$GLOBALS['titleLink'] = 'titleLink';
8$GLOBALS['redirector'] = 'lala';
9$GLOBALS['disablesessionprotection'] = false;
10$GLOBALS['privateLinkByDefault'] = false;
11$GLOBALS['config']['DATADIR'] = 'tests/Updater';
12$GLOBALS['config']['PAGECACHE'] = 'sandbox/pagecache';
13$GLOBALS['config']['DATASTORE'] = 'data/datastore.php';
14$GLOBALS['plugins']['WALLABAG_VERSION'] = '1';