RCCacheEntryFactoryTest.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php
  2. use MediaWiki\Linker\LinkRenderer;
  3. use MediaWiki\MediaWikiServices;
  4. /**
  5. * @covers RCCacheEntryFactory
  6. *
  7. * @group Database
  8. *
  9. * @author Katie Filbert < aude.wiki@gmail.com >
  10. */
  11. class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
  12. /**
  13. * @var TestRecentChangesHelper
  14. */
  15. private $testRecentChangesHelper;
  16. /**
  17. * @var LinkRenderer
  18. */
  19. private $linkRenderer;
  20. public function __construct( $name = null, array $data = [], $dataName = '' ) {
  21. parent::__construct( $name, $data, $dataName );
  22. $this->testRecentChangesHelper = new TestRecentChangesHelper();
  23. }
  24. protected function setUp() {
  25. parent::setUp();
  26. $this->setMwGlobals( [
  27. 'wgArticlePath' => '/wiki/$1'
  28. ] );
  29. $this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
  30. }
  31. public function testNewFromRecentChange() {
  32. $user = $this->getMutableTestUser()->getUser();
  33. $recentChange = $this->testRecentChangesHelper->makeEditRecentChange(
  34. $user,
  35. 'Xyz',
  36. 5, // curid
  37. 191, // thisid
  38. 190, // lastid
  39. '20131103212153',
  40. 0, // counter
  41. 0 // number of watching users
  42. );
  43. $cacheEntryFactory = new RCCacheEntryFactory(
  44. $this->getContext(),
  45. $this->getMessages(),
  46. $this->linkRenderer
  47. );
  48. $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, false );
  49. $this->assertInstanceOf( RCCacheEntry::class, $cacheEntry );
  50. $this->assertEquals( false, $cacheEntry->watched, 'watched' );
  51. $this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
  52. $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
  53. $this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
  54. $this->assertUserLinks( $user->getName(), $cacheEntry );
  55. $this->assertTitleLink( 'Xyz', $cacheEntry );
  56. $diff = [ 'curid' => 5, 'diff' => 191, 'oldid' => 190 ];
  57. $cur = [ 'curid' => 5, 'diff' => 0, 'oldid' => 191 ];
  58. $this->assertQueryLink( 'cur', $cur, $cacheEntry->curlink );
  59. $this->assertQueryLink( 'prev', $diff, $cacheEntry->lastlink );
  60. $this->assertQueryLink( 'diff', $diff, $cacheEntry->difflink );
  61. }
  62. public function testNewForDeleteChange() {
  63. $user = $this->getMutableTestUser()->getUser();
  64. $recentChange = $this->testRecentChangesHelper->makeLogRecentChange(
  65. 'delete',
  66. 'delete',
  67. $user,
  68. 'Abc',
  69. '20131103212153',
  70. 0, // counter
  71. 0 // number of watching users
  72. );
  73. $cacheEntryFactory = new RCCacheEntryFactory(
  74. $this->getContext(),
  75. $this->getMessages(),
  76. $this->linkRenderer
  77. );
  78. $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, false );
  79. $this->assertInstanceOf( RCCacheEntry::class, $cacheEntry );
  80. $this->assertEquals( false, $cacheEntry->watched, 'watched' );
  81. $this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
  82. $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
  83. $this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
  84. $this->assertDeleteLogLink( $cacheEntry );
  85. $this->assertUserLinks( $user->getName(), $cacheEntry );
  86. $this->assertEquals( 'cur', $cacheEntry->curlink, 'cur link for delete log or rev' );
  87. $this->assertEquals( 'diff', $cacheEntry->difflink, 'diff link for delete log or rev' );
  88. $this->assertEquals( 'prev', $cacheEntry->lastlink, 'pref link for delete log or rev' );
  89. }
  90. public function testNewForRevUserDeleteChange() {
  91. $user = $this->getMutableTestUser()->getUser();
  92. $recentChange = $this->testRecentChangesHelper->makeDeletedEditRecentChange(
  93. $user,
  94. 'Zzz',
  95. '20131103212153',
  96. 191, // thisid
  97. 190, // lastid
  98. '20131103212153',
  99. 0, // counter
  100. 0 // number of watching users
  101. );
  102. $cacheEntryFactory = new RCCacheEntryFactory(
  103. $this->getContext(),
  104. $this->getMessages(),
  105. $this->linkRenderer
  106. );
  107. $cacheEntry = $cacheEntryFactory->newFromRecentChange( $recentChange, false );
  108. $this->assertInstanceOf( RCCacheEntry::class, $cacheEntry );
  109. $this->assertEquals( false, $cacheEntry->watched, 'watched' );
  110. $this->assertEquals( '21:21', $cacheEntry->timestamp, 'timestamp' );
  111. $this->assertEquals( 0, $cacheEntry->numberofWatchingusers, 'watching users' );
  112. $this->assertEquals( false, $cacheEntry->unpatrolled, 'unpatrolled' );
  113. $this->assertRevDel( $cacheEntry );
  114. $this->assertTitleLink( 'Zzz', $cacheEntry );
  115. $this->assertEquals( 'cur', $cacheEntry->curlink, 'cur link for delete log or rev' );
  116. $this->assertEquals( 'diff', $cacheEntry->difflink, 'diff link for delete log or rev' );
  117. $this->assertEquals( 'prev', $cacheEntry->lastlink, 'pref link for delete log or rev' );
  118. }
  119. private function assertValidHTML( $actual ) {
  120. // Throws if invalid
  121. $doc = PHPUnit_Util_XML::load( $actual, /* isHtml */ true );
  122. }
  123. private function assertUserLinks( $user, $cacheEntry ) {
  124. $this->assertValidHTML( $cacheEntry->userlink );
  125. $this->assertRegExp(
  126. '#^<a .*class="new mw-userlink".*><bdi>' . $user . '</bdi></a>#',
  127. $cacheEntry->userlink,
  128. 'verify user link'
  129. );
  130. $this->assertValidHTML( $cacheEntry->usertalklink );
  131. $this->assertRegExp(
  132. '#^ <span class="mw-usertoollinks">\(.*<a .+>talk</a>.*\)</span>#',
  133. $cacheEntry->usertalklink,
  134. 'verify user talk link'
  135. );
  136. $this->assertValidHTML( $cacheEntry->usertalklink );
  137. $this->assertRegExp(
  138. '#^ <span class="mw-usertoollinks">\(.*<a .+>contribs</a>.*\)</span>$#',
  139. $cacheEntry->usertalklink,
  140. 'verify user tool links'
  141. );
  142. }
  143. private function assertDeleteLogLink( $cacheEntry ) {
  144. $this->assertEquals(
  145. '(<a href="/wiki/Special:Log/delete" title="Special:Log/delete">Deletion log</a>)',
  146. $cacheEntry->link,
  147. 'verify deletion log link'
  148. );
  149. $this->assertValidHTML( $cacheEntry->link );
  150. }
  151. private function assertRevDel( $cacheEntry ) {
  152. $this->assertEquals(
  153. ' <span class="history-deleted">(username removed)</span>',
  154. $cacheEntry->userlink,
  155. 'verify user link for change with deleted revision and user'
  156. );
  157. $this->assertValidHTML( $cacheEntry->userlink );
  158. }
  159. private function assertTitleLink( $title, $cacheEntry ) {
  160. $this->assertEquals(
  161. '<a href="/wiki/' . $title . '" title="' . $title . '">' . $title . '</a>',
  162. $cacheEntry->link,
  163. 'verify title link'
  164. );
  165. $this->assertValidHTML( $cacheEntry->link );
  166. }
  167. private function assertQueryLink( $content, $params, $link ) {
  168. $this->assertRegExp(
  169. "#^<a .+>$content</a>$#",
  170. $link,
  171. 'verify query link element'
  172. );
  173. $this->assertValidHTML( $link );
  174. foreach ( $params as $key => $value ) {
  175. $this->assertRegExp( '/' . $key . '=' . $value . '/', $link, "verify $key link params" );
  176. }
  177. }
  178. private function getMessages() {
  179. return [
  180. 'cur' => 'cur',
  181. 'diff' => 'diff',
  182. 'hist' => 'hist',
  183. 'enhancedrc-history' => 'history',
  184. 'last' => 'prev',
  185. 'blocklink' => 'block',
  186. 'history' => 'Page history',
  187. 'semicolon-separator' => '; ',
  188. 'pipe-separator' => ' | '
  189. ];
  190. }
  191. private function getContext() {
  192. $user = $this->getMutableTestUser()->getUser();
  193. $context = $this->testRecentChangesHelper->getTestContext( $user );
  194. $title = Title::newFromText( 'RecentChanges', NS_SPECIAL );
  195. $context->setTitle( $title );
  196. return $context;
  197. }
  198. }