LinkFilterTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. <?php
  2. require_once 'application/LinkFilter.php';
  3. /**
  4. * Class LinkFilterTest.
  5. */
  6. class LinkFilterTest extends PHPUnit_Framework_TestCase
  7. {
  8. /**
  9. * @var LinkFilter instance.
  10. */
  11. protected static $linkFilter;
  12. /**
  13. * @var ReferenceLinkDB instance
  14. */
  15. protected static $refDB;
  16. /**
  17. * Instanciate linkFilter with ReferenceLinkDB data.
  18. */
  19. public static function setUpBeforeClass()
  20. {
  21. self::$refDB = new ReferenceLinkDB();
  22. self::$linkFilter = new LinkFilter(self::$refDB->getLinks());
  23. }
  24. /**
  25. * Blank filter.
  26. */
  27. public function testFilter()
  28. {
  29. $this->assertEquals(
  30. self::$refDB->countLinks(),
  31. count(self::$linkFilter->filter('', ''))
  32. );
  33. $this->assertEquals(
  34. self::$refDB->countLinks(),
  35. count(self::$linkFilter->filter('', '', 'all'))
  36. );
  37. $this->assertEquals(
  38. self::$refDB->countLinks(),
  39. count(self::$linkFilter->filter('', '', 'randomstr'))
  40. );
  41. // Private only.
  42. $this->assertEquals(
  43. self::$refDB->countPrivateLinks(),
  44. count(self::$linkFilter->filter('', '', false, 'private'))
  45. );
  46. // Public only.
  47. $this->assertEquals(
  48. self::$refDB->countPublicLinks(),
  49. count(self::$linkFilter->filter('', '', false, 'public'))
  50. );
  51. $this->assertEquals(
  52. ReferenceLinkDB::$NB_LINKS_TOTAL,
  53. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, ''))
  54. );
  55. // Untagged only
  56. $this->assertEquals(
  57. self::$refDB->countUntaggedLinks(),
  58. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, false))
  59. );
  60. $this->assertEquals(
  61. ReferenceLinkDB::$NB_LINKS_TOTAL,
  62. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, ''))
  63. );
  64. }
  65. /**
  66. * Filter links using a tag
  67. */
  68. public function testFilterOneTag()
  69. {
  70. $this->assertEquals(
  71. 4,
  72. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false))
  73. );
  74. $this->assertEquals(
  75. 4,
  76. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'all'))
  77. );
  78. $this->assertEquals(
  79. 4,
  80. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'default-blabla'))
  81. );
  82. // Private only.
  83. $this->assertEquals(
  84. 1,
  85. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'private'))
  86. );
  87. // Public only.
  88. $this->assertEquals(
  89. 3,
  90. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'public'))
  91. );
  92. }
  93. /**
  94. * Filter links using a tag - case-sensitive
  95. */
  96. public function testFilterCaseSensitiveTag()
  97. {
  98. $this->assertEquals(
  99. 0,
  100. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'mercurial', true))
  101. );
  102. $this->assertEquals(
  103. 1,
  104. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'Mercurial', true))
  105. );
  106. }
  107. /**
  108. * Filter links using a tag combination
  109. */
  110. public function testFilterMultipleTags()
  111. {
  112. $this->assertEquals(
  113. 2,
  114. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'dev cartoon', false))
  115. );
  116. }
  117. /**
  118. * Filter links using a non-existent tag
  119. */
  120. public function testFilterUnknownTag()
  121. {
  122. $this->assertEquals(
  123. 0,
  124. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'null', false))
  125. );
  126. }
  127. /**
  128. * Return links for a given day
  129. */
  130. public function testFilterDay()
  131. {
  132. $this->assertEquals(
  133. 4,
  134. count(self::$linkFilter->filter(LinkFilter::$FILTER_DAY, '20121206'))
  135. );
  136. }
  137. /**
  138. * 404 - day not found
  139. */
  140. public function testFilterUnknownDay()
  141. {
  142. $this->assertEquals(
  143. 0,
  144. count(self::$linkFilter->filter(LinkFilter::$FILTER_DAY, '19700101'))
  145. );
  146. }
  147. /**
  148. * Use an invalid date format
  149. * @expectedException Exception
  150. * @expectedExceptionMessageRegExp /Invalid date format/
  151. */
  152. public function testFilterInvalidDayWithChars()
  153. {
  154. self::$linkFilter->filter(LinkFilter::$FILTER_DAY, 'Rainy day, dream away');
  155. }
  156. /**
  157. * Use an invalid date format
  158. * @expectedException Exception
  159. * @expectedExceptionMessageRegExp /Invalid date format/
  160. */
  161. public function testFilterInvalidDayDigits()
  162. {
  163. self::$linkFilter->filter(LinkFilter::$FILTER_DAY, '20');
  164. }
  165. /**
  166. * Retrieve a link entry with its hash
  167. */
  168. public function testFilterSmallHash()
  169. {
  170. $links = self::$linkFilter->filter(LinkFilter::$FILTER_HASH, 'IuWvgA');
  171. $this->assertEquals(
  172. 1,
  173. count($links)
  174. );
  175. $this->assertEquals(
  176. 'MediaGoblin',
  177. $links[7]['title']
  178. );
  179. }
  180. /**
  181. * No link for this hash
  182. *
  183. * @expectedException LinkNotFoundException
  184. */
  185. public function testFilterUnknownSmallHash()
  186. {
  187. self::$linkFilter->filter(LinkFilter::$FILTER_HASH, 'Iblaah');
  188. }
  189. /**
  190. * Full-text search - no result found.
  191. */
  192. public function testFilterFullTextNoResult()
  193. {
  194. $this->assertEquals(
  195. 0,
  196. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'azertyuiop'))
  197. );
  198. }
  199. /**
  200. * Full-text search - result from a link's URL
  201. */
  202. public function testFilterFullTextURL()
  203. {
  204. $this->assertEquals(
  205. 2,
  206. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars.userfriendly.org'))
  207. );
  208. $this->assertEquals(
  209. 2,
  210. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'ars org'))
  211. );
  212. }
  213. /**
  214. * Full-text search - result from a link's title only
  215. */
  216. public function testFilterFullTextTitle()
  217. {
  218. // use miscellaneous cases
  219. $this->assertEquals(
  220. 2,
  221. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'userfriendly -'))
  222. );
  223. $this->assertEquals(
  224. 2,
  225. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'UserFriendly -'))
  226. );
  227. $this->assertEquals(
  228. 2,
  229. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'uSeRFrIendlY -'))
  230. );
  231. // use miscellaneous case and offset
  232. $this->assertEquals(
  233. 2,
  234. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'RFrIendL'))
  235. );
  236. }
  237. /**
  238. * Full-text search - result from the link's description only
  239. */
  240. public function testFilterFullTextDescription()
  241. {
  242. $this->assertEquals(
  243. 1,
  244. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'publishing media'))
  245. );
  246. $this->assertEquals(
  247. 1,
  248. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'mercurial w3c'))
  249. );
  250. $this->assertEquals(
  251. 3,
  252. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '"free software"'))
  253. );
  254. }
  255. /**
  256. * Full-text search - result from the link's tags only
  257. */
  258. public function testFilterFullTextTags()
  259. {
  260. $this->assertEquals(
  261. 6,
  262. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web'))
  263. );
  264. $this->assertEquals(
  265. 6,
  266. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'all'))
  267. );
  268. $this->assertEquals(
  269. 6,
  270. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'bla'))
  271. );
  272. // Private only.
  273. $this->assertEquals(
  274. 1,
  275. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'private'))
  276. );
  277. // Public only.
  278. $this->assertEquals(
  279. 5,
  280. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'public'))
  281. );
  282. }
  283. /**
  284. * Full-text search - result set from mixed sources
  285. */
  286. public function testFilterFullTextMixed()
  287. {
  288. $this->assertEquals(
  289. 3,
  290. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'free software'))
  291. );
  292. }
  293. /**
  294. * Full-text search - test exclusion with '-'.
  295. */
  296. public function testExcludeSearch()
  297. {
  298. $this->assertEquals(
  299. 1,
  300. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'free -gnu'))
  301. );
  302. $this->assertEquals(
  303. ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
  304. count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '-revolution'))
  305. );
  306. }
  307. /**
  308. * Full-text search - test AND, exact terms and exclusion combined, across fields.
  309. */
  310. public function testMultiSearch()
  311. {
  312. $this->assertEquals(
  313. 2,
  314. count(self::$linkFilter->filter(
  315. LinkFilter::$FILTER_TEXT,
  316. '"Free Software " stallman "read this" @website stuff'
  317. ))
  318. );
  319. $this->assertEquals(
  320. 1,
  321. count(self::$linkFilter->filter(
  322. LinkFilter::$FILTER_TEXT,
  323. '"free software " stallman "read this" -beard @website stuff'
  324. ))
  325. );
  326. }
  327. /**
  328. * Full-text search - make sure that exact search won't work across fields.
  329. */
  330. public function testSearchExactTermMultiFieldsKo()
  331. {
  332. $this->assertEquals(
  333. 0,
  334. count(self::$linkFilter->filter(
  335. LinkFilter::$FILTER_TEXT,
  336. '"designer naming"'
  337. ))
  338. );
  339. $this->assertEquals(
  340. 0,
  341. count(self::$linkFilter->filter(
  342. LinkFilter::$FILTER_TEXT,
  343. '"designernaming"'
  344. ))
  345. );
  346. }
  347. /**
  348. * Tag search with exclusion.
  349. */
  350. public function testTagFilterWithExclusion()
  351. {
  352. $this->assertEquals(
  353. 1,
  354. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'gnu -free'))
  355. );
  356. $this->assertEquals(
  357. ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
  358. count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free'))
  359. );
  360. }
  361. /**
  362. * Test crossed search (terms + tags).
  363. */
  364. public function testFilterCrossedSearch()
  365. {
  366. $terms = '"Free Software " stallman "read this" @website stuff';
  367. $tags = 'free';
  368. $this->assertEquals(
  369. 1,
  370. count(self::$linkFilter->filter(
  371. LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
  372. array($tags, $terms)
  373. ))
  374. );
  375. $this->assertEquals(
  376. 2,
  377. count(self::$linkFilter->filter(
  378. LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
  379. array('', $terms)
  380. ))
  381. );
  382. $this->assertEquals(
  383. 1,
  384. count(self::$linkFilter->filter(
  385. LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
  386. array(false, 'PSR-2')
  387. ))
  388. );
  389. $this->assertEquals(
  390. 1,
  391. count(self::$linkFilter->filter(
  392. LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
  393. array($tags, '')
  394. ))
  395. );
  396. $this->assertEquals(
  397. ReferenceLinkDB::$NB_LINKS_TOTAL,
  398. count(self::$linkFilter->filter(
  399. LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
  400. ''
  401. ))
  402. );
  403. }
  404. /**
  405. * Filter links by #hashtag.
  406. */
  407. public function testFilterByHashtag()
  408. {
  409. $hashtag = 'hashtag';
  410. $this->assertEquals(
  411. 3,
  412. count(self::$linkFilter->filter(
  413. LinkFilter::$FILTER_TAG,
  414. $hashtag
  415. ))
  416. );
  417. $hashtag = 'private';
  418. $this->assertEquals(
  419. 1,
  420. count(self::$linkFilter->filter(
  421. LinkFilter::$FILTER_TAG,
  422. $hashtag,
  423. false,
  424. 'private'
  425. ))
  426. );
  427. }
  428. }