LinkDBTest.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. /**
  3. * Link datastore tests
  4. */
  5. require_once 'application/Cache.php';
  6. require_once 'application/FileUtils.php';
  7. require_once 'application/LinkDB.php';
  8. require_once 'application/Utils.php';
  9. require_once 'tests/utils/ReferenceLinkDB.php';
  10. /**
  11. * Unitary tests for LinkDB
  12. */
  13. class LinkDBTest extends PHPUnit_Framework_TestCase
  14. {
  15. // datastore to test write operations
  16. protected static $testDatastore = 'sandbox/datastore.php';
  17. protected static $refDB = null;
  18. protected static $publicLinkDB = null;
  19. protected static $privateLinkDB = null;
  20. /**
  21. * Instantiates public and private LinkDBs with test data
  22. *
  23. * The reference datastore contains public and private links that
  24. * will be used to test LinkDB's methods:
  25. * - access filtering (public/private),
  26. * - link searches:
  27. * - by day,
  28. * - by tag,
  29. * - by text,
  30. * - etc.
  31. */
  32. public static function setUpBeforeClass()
  33. {
  34. self::$refDB = new ReferenceLinkDB();
  35. self::$refDB->write(self::$testDatastore);
  36. self::$publicLinkDB = new LinkDB(self::$testDatastore, false, false);
  37. self::$privateLinkDB = new LinkDB(self::$testDatastore, true, false);
  38. }
  39. /**
  40. * Resets test data for each test
  41. */
  42. protected function setUp()
  43. {
  44. if (file_exists(self::$testDatastore)) {
  45. unlink(self::$testDatastore);
  46. }
  47. }
  48. /**
  49. * Allows to test LinkDB's private methods
  50. *
  51. * @see
  52. * https://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
  53. * http://stackoverflow.com/a/2798203
  54. */
  55. protected static function getMethod($name)
  56. {
  57. $class = new ReflectionClass('LinkDB');
  58. $method = $class->getMethod($name);
  59. $method->setAccessible(true);
  60. return $method;
  61. }
  62. /**
  63. * Instantiate LinkDB objects - logged in user
  64. */
  65. public function testConstructLoggedIn()
  66. {
  67. new LinkDB(self::$testDatastore, true, false);
  68. $this->assertFileExists(self::$testDatastore);
  69. }
  70. /**
  71. * Instantiate LinkDB objects - logged out or public instance
  72. */
  73. public function testConstructLoggedOut()
  74. {
  75. new LinkDB(self::$testDatastore, false, false);
  76. $this->assertFileExists(self::$testDatastore);
  77. }
  78. /**
  79. * Attempt to instantiate a LinkDB whereas the datastore is not writable
  80. *
  81. * @expectedException IOException
  82. * @expectedExceptionMessageRegExp /Error accessing null/
  83. */
  84. public function testConstructDatastoreNotWriteable()
  85. {
  86. new LinkDB('null/store.db', false, false);
  87. }
  88. /**
  89. * The DB doesn't exist, ensure it is created with dummy content
  90. */
  91. public function testCheckDBNew()
  92. {
  93. $linkDB = new LinkDB(self::$testDatastore, false, false);
  94. unlink(self::$testDatastore);
  95. $this->assertFileNotExists(self::$testDatastore);
  96. $checkDB = self::getMethod('_checkDB');
  97. $checkDB->invokeArgs($linkDB, array());
  98. $this->assertFileExists(self::$testDatastore);
  99. // ensure the correct data has been written
  100. $this->assertGreaterThan(0, filesize(self::$testDatastore));
  101. }
  102. /**
  103. * The DB exists, don't do anything
  104. */
  105. public function testCheckDBLoad()
  106. {
  107. $linkDB = new LinkDB(self::$testDatastore, false, false);
  108. $datastoreSize = filesize(self::$testDatastore);
  109. $this->assertGreaterThan(0, $datastoreSize);
  110. $checkDB = self::getMethod('_checkDB');
  111. $checkDB->invokeArgs($linkDB, array());
  112. // ensure the datastore is left unmodified
  113. $this->assertEquals(
  114. $datastoreSize,
  115. filesize(self::$testDatastore)
  116. );
  117. }
  118. /**
  119. * Load an empty DB
  120. */
  121. public function testReadEmptyDB()
  122. {
  123. file_put_contents(self::$testDatastore, '<?php /* S7QysKquBQA= */ ?>');
  124. $emptyDB = new LinkDB(self::$testDatastore, false, false);
  125. $this->assertEquals(0, sizeof($emptyDB));
  126. $this->assertEquals(0, count($emptyDB));
  127. }
  128. /**
  129. * Load public links from the DB
  130. */
  131. public function testReadPublicDB()
  132. {
  133. $this->assertEquals(
  134. self::$refDB->countPublicLinks(),
  135. sizeof(self::$publicLinkDB)
  136. );
  137. }
  138. /**
  139. * Load public and private links from the DB
  140. */
  141. public function testReadPrivateDB()
  142. {
  143. $this->assertEquals(
  144. self::$refDB->countLinks(),
  145. sizeof(self::$privateLinkDB)
  146. );
  147. }
  148. /**
  149. * Save the links to the DB
  150. */
  151. public function testSaveDB()
  152. {
  153. $testDB = new LinkDB(self::$testDatastore, true, false);
  154. $dbSize = sizeof($testDB);
  155. $link = array(
  156. 'title'=>'an additional link',
  157. 'url'=>'http://dum.my',
  158. 'description'=>'One more',
  159. 'private'=>0,
  160. 'linkdate'=>'20150518_190000',
  161. 'tags'=>'unit test'
  162. );
  163. $testDB[$link['linkdate']] = $link;
  164. $testDB->savedb('tests');
  165. $testDB = new LinkDB(self::$testDatastore, true, false);
  166. $this->assertEquals($dbSize + 1, sizeof($testDB));
  167. }
  168. /**
  169. * Count existing links
  170. */
  171. public function testCount()
  172. {
  173. $this->assertEquals(
  174. self::$refDB->countPublicLinks(),
  175. self::$publicLinkDB->count()
  176. );
  177. $this->assertEquals(
  178. self::$refDB->countLinks(),
  179. self::$privateLinkDB->count()
  180. );
  181. }
  182. /**
  183. * Count existing links - public links hidden
  184. */
  185. public function testCountHiddenPublic()
  186. {
  187. $linkDB = new LinkDB(self::$testDatastore, false, true);
  188. $this->assertEquals(
  189. 0,
  190. $linkDB->count()
  191. );
  192. $this->assertEquals(
  193. 0,
  194. $linkDB->count()
  195. );
  196. }
  197. /**
  198. * List the days for which links have been posted
  199. */
  200. public function testDays()
  201. {
  202. $this->assertEquals(
  203. array('20121206', '20130614', '20150310'),
  204. self::$publicLinkDB->days()
  205. );
  206. $this->assertEquals(
  207. array('20121206', '20130614', '20141125', '20150310'),
  208. self::$privateLinkDB->days()
  209. );
  210. }
  211. /**
  212. * The URL corresponds to an existing entry in the DB
  213. */
  214. public function testGetKnownLinkFromURL()
  215. {
  216. $link = self::$publicLinkDB->getLinkFromUrl('http://mediagoblin.org/');
  217. $this->assertNotEquals(false, $link);
  218. $this->assertEquals(
  219. 'A free software media publishing platform',
  220. $link['description']
  221. );
  222. }
  223. /**
  224. * The URL is not in the DB
  225. */
  226. public function testGetUnknownLinkFromURL()
  227. {
  228. $this->assertEquals(
  229. false,
  230. self::$publicLinkDB->getLinkFromUrl('http://dev.null')
  231. );
  232. }
  233. /**
  234. * Lists all tags
  235. */
  236. public function testAllTags()
  237. {
  238. $this->assertEquals(
  239. array(
  240. 'web' => 3,
  241. 'cartoon' => 2,
  242. 'gnu' => 2,
  243. 'dev' => 1,
  244. 'samba' => 1,
  245. 'media' => 1,
  246. 'software' => 1,
  247. 'stallman' => 1,
  248. 'free' => 1
  249. ),
  250. self::$publicLinkDB->allTags()
  251. );
  252. $this->assertEquals(
  253. array(
  254. 'web' => 4,
  255. 'cartoon' => 3,
  256. 'gnu' => 2,
  257. 'dev' => 2,
  258. 'samba' => 1,
  259. 'media' => 1,
  260. 'software' => 1,
  261. 'stallman' => 1,
  262. 'free' => 1,
  263. 'html' => 1,
  264. 'w3c' => 1,
  265. 'css' => 1,
  266. 'Mercurial' => 1
  267. ),
  268. self::$privateLinkDB->allTags()
  269. );
  270. }
  271. /**
  272. * Test real_url without redirector.
  273. */
  274. public function testLinkRealUrlWithoutRedirector()
  275. {
  276. $db = new LinkDB(self::$testDatastore, false, false);
  277. foreach($db as $link) {
  278. $this->assertEquals($link['url'], $link['real_url']);
  279. }
  280. }
  281. /**
  282. * Test real_url with redirector.
  283. */
  284. public function testLinkRealUrlWithRedirector()
  285. {
  286. $redirector = 'http://redirector.to?';
  287. $db = new LinkDB(self::$testDatastore, false, false, $redirector);
  288. foreach($db as $link) {
  289. $this->assertStringStartsWith($redirector, $link['real_url']);
  290. }
  291. }
  292. /**
  293. * Test filter with string.
  294. */
  295. public function testFilterString()
  296. {
  297. $tags = 'dev cartoon';
  298. $this->assertEquals(
  299. 2,
  300. count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false))
  301. );
  302. }
  303. /**
  304. * Test filter with string.
  305. */
  306. public function testFilterArray()
  307. {
  308. $tags = array('dev', 'cartoon');
  309. $this->assertEquals(
  310. 2,
  311. count(self::$privateLinkDB->filter(LinkFilter::$FILTER_TAG, $tags, true, false))
  312. );
  313. }
  314. }