Merge "Add optional jQuery event delegates in Confirmable"
[lhc/web/wiklou.git] / tests / phpunit / includes / watcheditem / WatchedItemStoreIntegrationTest.php
1 <?php
2
3 use MediaWiki\MediaWikiServices;
4 use Wikimedia\TestingAccessWrapper;
5
6 /**
7 * @author Addshore
8 *
9 * @group Database
10 *
11 * @covers WatchedItemStore
12 */
13 class WatchedItemStoreIntegrationTest extends MediaWikiTestCase {
14
15 public function setUp() {
16 parent::setUp();
17 self::$users['WatchedItemStoreIntegrationTestUser']
18 = new TestUser( 'WatchedItemStoreIntegrationTestUser' );
19 }
20
21 private function getUser() {
22 return self::$users['WatchedItemStoreIntegrationTestUser']->getUser();
23 }
24
25 public function testWatchAndUnWatchItem() {
26 $user = $this->getUser();
27 $title = Title::newFromText( 'WatchedItemStoreIntegrationTestPage' );
28 $store = MediaWikiServices::getInstance()->getWatchedItemStore();
29 // Cleanup after previous tests
30 $store->removeWatch( $user, $title );
31 $initialWatchers = $store->countWatchers( $title );
32 $initialUserWatchedItems = $store->countWatchedItems( $user );
33
34 $this->assertFalse(
35 $store->isWatched( $user, $title ),
36 'Page should not initially be watched'
37 );
38
39 $store->addWatch( $user, $title );
40 $this->assertTrue(
41 $store->isWatched( $user, $title ),
42 'Page should be watched'
43 );
44 $this->assertEquals( $initialUserWatchedItems + 1, $store->countWatchedItems( $user ) );
45 $watchedItemsForUser = $store->getWatchedItemsForUser( $user );
46 $this->assertCount( $initialUserWatchedItems + 1, $watchedItemsForUser );
47 $watchedItemsForUserHasExpectedItem = false;
48 foreach ( $watchedItemsForUser as $watchedItem ) {
49 if (
50 $watchedItem->getUser()->equals( $user ) &&
51 $watchedItem->getLinkTarget() == $title->getTitleValue()
52 ) {
53 $watchedItemsForUserHasExpectedItem = true;
54 }
55 }
56 $this->assertTrue(
57 $watchedItemsForUserHasExpectedItem,
58 'getWatchedItemsForUser should contain the page'
59 );
60 $this->assertEquals( $initialWatchers + 1, $store->countWatchers( $title ) );
61 $this->assertEquals(
62 $initialWatchers + 1,
63 $store->countWatchersMultiple( [ $title ] )[$title->getNamespace()][$title->getDBkey()]
64 );
65 $this->assertEquals(
66 [ 0 => [ 'WatchedItemStoreIntegrationTestPage' => $initialWatchers + 1 ] ],
67 $store->countWatchersMultiple( [ $title ], [ 'minimumWatchers' => $initialWatchers + 1 ] )
68 );
69 $this->assertEquals(
70 [ 0 => [ 'WatchedItemStoreIntegrationTestPage' => 0 ] ],
71 $store->countWatchersMultiple( [ $title ], [ 'minimumWatchers' => $initialWatchers + 2 ] )
72 );
73 $this->assertEquals(
74 [ $title->getNamespace() => [ $title->getDBkey() => null ] ],
75 $store->getNotificationTimestampsBatch( $user, [ $title ] )
76 );
77
78 $store->removeWatch( $user, $title );
79 $this->assertFalse(
80 $store->isWatched( $user, $title ),
81 'Page should be unwatched'
82 );
83 $this->assertEquals( $initialUserWatchedItems, $store->countWatchedItems( $user ) );
84 $watchedItemsForUser = $store->getWatchedItemsForUser( $user );
85 $this->assertCount( $initialUserWatchedItems, $watchedItemsForUser );
86 $watchedItemsForUserHasExpectedItem = false;
87 foreach ( $watchedItemsForUser as $watchedItem ) {
88 if (
89 $watchedItem->getUser()->equals( $user ) &&
90 $watchedItem->getLinkTarget() == $title->getTitleValue()
91 ) {
92 $watchedItemsForUserHasExpectedItem = true;
93 }
94 }
95 $this->assertFalse(
96 $watchedItemsForUserHasExpectedItem,
97 'getWatchedItemsForUser should not contain the page'
98 );
99 $this->assertEquals( $initialWatchers, $store->countWatchers( $title ) );
100 $this->assertEquals(
101 $initialWatchers,
102 $store->countWatchersMultiple( [ $title ] )[$title->getNamespace()][$title->getDBkey()]
103 );
104 $this->assertEquals(
105 [ $title->getNamespace() => [ $title->getDBkey() => false ] ],
106 $store->getNotificationTimestampsBatch( $user, [ $title ] )
107 );
108 }
109
110 public function testWatchBatchAndClearItems() {
111 $user = $this->getUser();
112 $title1 = Title::newFromText( 'WatchedItemStoreIntegrationTestPage1' );
113 $title2 = Title::newFromText( 'WatchedItemStoreIntegrationTestPage2' );
114 $store = MediaWikiServices::getInstance()->getWatchedItemStore();
115
116 $store->addWatchBatchForUser( $user, [ $title1, $title2 ] );
117
118 $this->assertTrue( $store->isWatched( $user, $title1 ) );
119 $this->assertTrue( $store->isWatched( $user, $title2 ) );
120
121 $store->clearUserWatchedItems( $user );
122
123 $this->assertFalse( $store->isWatched( $user, $title1 ) );
124 $this->assertFalse( $store->isWatched( $user, $title2 ) );
125 }
126
127 public function testUpdateResetAndSetNotificationTimestamp() {
128 $user = $this->getUser();
129 $otherUser = ( new TestUser( 'WatchedItemStoreIntegrationTestUser_otherUser' ) )->getUser();
130 $title = Title::newFromText( 'WatchedItemStoreIntegrationTestPage' );
131 $store = MediaWikiServices::getInstance()->getWatchedItemStore();
132 $store->addWatch( $user, $title );
133 $this->assertNull( $store->loadWatchedItem( $user, $title )->getNotificationTimestamp() );
134 $initialVisitingWatchers = $store->countVisitingWatchers( $title, '20150202020202' );
135 $initialUnreadNotifications = $store->countUnreadNotifications( $user );
136
137 $store->updateNotificationTimestamp( $otherUser, $title, '20150202010101' );
138 $this->assertEquals(
139 '20150202010101',
140 $store->loadWatchedItem( $user, $title )->getNotificationTimestamp()
141 );
142 $this->assertEquals(
143 [ $title->getNamespace() => [ $title->getDBkey() => '20150202010101' ] ],
144 $store->getNotificationTimestampsBatch( $user, [ $title ] )
145 );
146 $this->assertEquals(
147 $initialVisitingWatchers - 1,
148 $store->countVisitingWatchers( $title, '20150202020202' )
149 );
150 $this->assertEquals(
151 $initialVisitingWatchers - 1,
152 $store->countVisitingWatchersMultiple(
153 [ [ $title, '20150202020202' ] ]
154 )[$title->getNamespace()][$title->getDBkey()]
155 );
156 $this->assertEquals(
157 $initialUnreadNotifications + 1,
158 $store->countUnreadNotifications( $user )
159 );
160 $this->assertSame(
161 true,
162 $store->countUnreadNotifications( $user, $initialUnreadNotifications + 1 )
163 );
164
165 $this->assertTrue( $store->resetNotificationTimestamp( $user, $title ) );
166 $this->assertNull( $store->getWatchedItem( $user, $title )->getNotificationTimestamp() );
167 $this->assertEquals(
168 [ $title->getNamespace() => [ $title->getDBkey() => null ] ],
169 $store->getNotificationTimestampsBatch( $user, [ $title ] )
170 );
171
172 // Run the job queue
173 JobQueueGroup::destroySingletons();
174 $jobs = new RunJobs;
175 $jobs->loadParamsAndArgs( null, [ 'quiet' => true ], null );
176 $jobs->execute();
177
178 $this->assertEquals(
179 $initialVisitingWatchers,
180 $store->countVisitingWatchers( $title, '20150202020202' )
181 );
182 $this->assertEquals(
183 $initialVisitingWatchers,
184 $store->countVisitingWatchersMultiple(
185 [ [ $title, '20150202020202' ] ]
186 )[$title->getNamespace()][$title->getDBkey()]
187 );
188 $this->assertEquals(
189 [ 0 => [ 'WatchedItemStoreIntegrationTestPage' => $initialVisitingWatchers ] ],
190 $store->countVisitingWatchersMultiple(
191 [ [ $title, '20150202020202' ] ], $initialVisitingWatchers
192 )
193 );
194 $this->assertEquals(
195 [ 0 => [ 'WatchedItemStoreIntegrationTestPage' => 0 ] ],
196 $store->countVisitingWatchersMultiple(
197 [ [ $title, '20150202020202' ] ], $initialVisitingWatchers + 1
198 )
199 );
200
201 // setNotificationTimestampsForUser specifying a title
202 $this->assertTrue(
203 $store->setNotificationTimestampsForUser( $user, '20100202020202', [ $title ] )
204 );
205 $this->assertEquals(
206 '20100202020202',
207 $store->getWatchedItem( $user, $title )->getNotificationTimestamp()
208 );
209
210 // setNotificationTimestampsForUser not specifying a title
211 // This will try to use a DeferredUpdate; disable that
212 $mockCallback = function ( $callback ) {
213 $callback();
214 };
215 $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
216 $this->assertTrue(
217 $store->setNotificationTimestampsForUser( $user, '20110202020202' )
218 );
219 // Because the operation above is normally deferred, it doesn't clear the cache
220 // Clear the cache manually
221 $wrappedStore = TestingAccessWrapper::newFromObject( $store );
222 $wrappedStore->uncacheUser( $user );
223 $this->assertEquals(
224 '20110202020202',
225 $store->getWatchedItem( $user, $title )->getNotificationTimestamp()
226 );
227 }
228
229 public function testDuplicateAllAssociatedEntries() {
230 $user = $this->getUser();
231 $titleOld = Title::newFromText( 'WatchedItemStoreIntegrationTestPageOld' );
232 $titleNew = Title::newFromText( 'WatchedItemStoreIntegrationTestPageNew' );
233 $store = MediaWikiServices::getInstance()->getWatchedItemStore();
234 $store->addWatch( $user, $titleOld->getSubjectPage() );
235 $store->addWatch( $user, $titleOld->getTalkPage() );
236 // Cleanup after previous tests
237 $store->removeWatch( $user, $titleNew->getSubjectPage() );
238 $store->removeWatch( $user, $titleNew->getTalkPage() );
239
240 $store->duplicateAllAssociatedEntries( $titleOld, $titleNew );
241
242 $this->assertTrue( $store->isWatched( $user, $titleOld->getSubjectPage() ) );
243 $this->assertTrue( $store->isWatched( $user, $titleOld->getTalkPage() ) );
244 $this->assertTrue( $store->isWatched( $user, $titleNew->getSubjectPage() ) );
245 $this->assertTrue( $store->isWatched( $user, $titleNew->getTalkPage() ) );
246 }
247
248 }