Refactor ApiTestCase to get token from ApiQueryTokens
[lhc/web/wiklou.git] / tests / phpunit / includes / api / ApiQueryWatchlistRawIntegrationTest.php
1 <?php
2
3 use MediaWiki\MediaWikiServices;
4
5 /**
6 * @group API
7 * @group Database
8 * @group medium
9 *
10 * @covers ApiQueryWatchlistRaw
11 */
12 class ApiQueryWatchlistRawIntegrationTest extends ApiTestCase {
13
14 protected function setUp() {
15 parent::setUp();
16 self::$users['ApiQueryWatchlistRawIntegrationTestUser']
17 = $this->getMutableTestUser();
18 self::$users['ApiQueryWatchlistRawIntegrationTestUser2']
19 = $this->getMutableTestUser();
20 $this->doLogin( 'ApiQueryWatchlistRawIntegrationTestUser' );
21 }
22
23 private function getLoggedInTestUser() {
24 return self::$users['ApiQueryWatchlistRawIntegrationTestUser']->getUser();
25 }
26
27 private function getNotLoggedInTestUser() {
28 return self::$users['ApiQueryWatchlistRawIntegrationTestUser2']->getUser();
29 }
30
31 private function getWatchedItemStore() {
32 return MediaWikiServices::getInstance()->getWatchedItemStore();
33 }
34
35 private function doListWatchlistRawRequest( array $params = [] ) {
36 return $this->doApiRequest( array_merge(
37 [ 'action' => 'query', 'list' => 'watchlistraw' ],
38 $params
39 ) );
40 }
41
42 private function doGeneratorWatchlistRawRequest( array $params = [] ) {
43 return $this->doApiRequest( array_merge(
44 [ 'action' => 'query', 'generator' => 'watchlistraw' ],
45 $params
46 ) );
47 }
48
49 private function getItemsFromApiResponse( array $response ) {
50 return $response[0]['watchlistraw'];
51 }
52
53 public function testListWatchlistRaw_returnsWatchedItems() {
54 $store = $this->getWatchedItemStore();
55 $store->addWatch(
56 $this->getLoggedInTestUser(),
57 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage' )
58 );
59
60 $result = $this->doListWatchlistRawRequest();
61
62 $this->assertArrayHasKey( 'watchlistraw', $result[0] );
63
64 $this->assertEquals(
65 [
66 [
67 'ns' => 0,
68 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
69 ],
70 ],
71 $this->getItemsFromApiResponse( $result )
72 );
73 }
74
75 public function testPropChanged_addsNotificationTimestamp() {
76 $target = new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage' );
77 $otherUser = $this->getNotLoggedInTestUser();
78
79 $store = $this->getWatchedItemStore();
80
81 $store->addWatch( $this->getLoggedInTestUser(), $target );
82 $store->updateNotificationTimestamp(
83 $otherUser,
84 $target,
85 '20151212010101'
86 );
87
88 $result = $this->doListWatchlistRawRequest( [ 'wrprop' => 'changed' ] );
89
90 $this->assertEquals(
91 [
92 [
93 'ns' => 0,
94 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
95 'changed' => '2015-12-12T01:01:01Z',
96 ],
97 ],
98 $this->getItemsFromApiResponse( $result )
99 );
100 }
101
102 public function testNamespaceParam() {
103 $store = $this->getWatchedItemStore();
104
105 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
106 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage' ),
107 new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage' ),
108 ] );
109
110 $result = $this->doListWatchlistRawRequest( [ 'wrnamespace' => '0' ] );
111
112 $this->assertEquals(
113 [
114 [
115 'ns' => 0,
116 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
117 ],
118 ],
119 $this->getItemsFromApiResponse( $result )
120 );
121 }
122
123 public function testShowChangedParams() {
124 $subjectTarget = new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage' );
125 $talkTarget = new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage' );
126 $otherUser = $this->getNotLoggedInTestUser();
127
128 $store = $this->getWatchedItemStore();
129
130 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
131 $subjectTarget,
132 $talkTarget,
133 ] );
134 $store->updateNotificationTimestamp(
135 $otherUser,
136 $subjectTarget,
137 '20151212010101'
138 );
139
140 $resultChanged = $this->doListWatchlistRawRequest(
141 [ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService::FILTER_CHANGED ]
142 );
143 $resultNotChanged = $this->doListWatchlistRawRequest(
144 [ 'wrprop' => 'changed', 'wrshow' => WatchedItemQueryService::FILTER_NOT_CHANGED ]
145 );
146
147 $this->assertEquals(
148 [
149 [
150 'ns' => 0,
151 'title' => 'ApiQueryWatchlistRawIntegrationTestPage',
152 'changed' => '2015-12-12T01:01:01Z',
153 ],
154 ],
155 $this->getItemsFromApiResponse( $resultChanged )
156 );
157
158 $this->assertEquals(
159 [
160 [
161 'ns' => 1,
162 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage',
163 ],
164 ],
165 $this->getItemsFromApiResponse( $resultNotChanged )
166 );
167 }
168
169 public function testLimitParam() {
170 $store = $this->getWatchedItemStore();
171
172 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
173 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
174 new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
175 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
176 ] );
177
178 $resultWithoutLimit = $this->doListWatchlistRawRequest();
179 $resultWithLimit = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
180
181 $this->assertEquals(
182 [
183 [
184 'ns' => 0,
185 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
186 ],
187 [
188 'ns' => 0,
189 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
190 ],
191 [
192 'ns' => 1,
193 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
194 ],
195 ],
196 $this->getItemsFromApiResponse( $resultWithoutLimit )
197 );
198 $this->assertEquals(
199 [
200 [
201 'ns' => 0,
202 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
203 ],
204 [
205 'ns' => 0,
206 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
207 ],
208 ],
209 $this->getItemsFromApiResponse( $resultWithLimit )
210 );
211
212 $this->assertArrayNotHasKey( 'continue', $resultWithoutLimit[0] );
213 $this->assertArrayHasKey( 'continue', $resultWithLimit[0] );
214 $this->assertArrayHasKey( 'wrcontinue', $resultWithLimit[0]['continue'] );
215 }
216
217 public function testDirParams() {
218 $store = $this->getWatchedItemStore();
219
220 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
221 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
222 new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
223 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
224 ] );
225
226 $resultDirAsc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
227 $resultDirDesc = $this->doListWatchlistRawRequest( [ 'wrdir' => 'descending' ] );
228
229 $this->assertEquals(
230 [
231 [
232 'ns' => 0,
233 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
234 ],
235 [
236 'ns' => 0,
237 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
238 ],
239 [
240 'ns' => 1,
241 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
242 ],
243 ],
244 $this->getItemsFromApiResponse( $resultDirAsc )
245 );
246
247 $this->assertEquals(
248 [
249 [
250 'ns' => 1,
251 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
252 ],
253 [
254 'ns' => 0,
255 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
256 ],
257 [
258 'ns' => 0,
259 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
260 ],
261 ],
262 $this->getItemsFromApiResponse( $resultDirDesc )
263 );
264 }
265
266 public function testAscendingIsDefaultOrder() {
267 $store = $this->getWatchedItemStore();
268
269 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
270 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
271 new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
272 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
273 ] );
274
275 $resultNoDir = $this->doListWatchlistRawRequest();
276 $resultAscDir = $this->doListWatchlistRawRequest( [ 'wrdir' => 'ascending' ] );
277
278 $this->assertEquals(
279 $this->getItemsFromApiResponse( $resultNoDir ),
280 $this->getItemsFromApiResponse( $resultAscDir )
281 );
282 }
283
284 public function testFromTitleParam() {
285 $store = $this->getWatchedItemStore();
286
287 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
288 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
289 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
290 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
291 ] );
292
293 $result = $this->doListWatchlistRawRequest( [
294 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
295 ] );
296
297 $this->assertEquals(
298 [
299 [
300 'ns' => 0,
301 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
302 ],
303 [
304 'ns' => 0,
305 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
306 ],
307 ],
308 $this->getItemsFromApiResponse( $result )
309 );
310 }
311
312 public function testToTitleParam() {
313 $store = $this->getWatchedItemStore();
314
315 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
316 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
317 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
318 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
319 ] );
320
321 $result = $this->doListWatchlistRawRequest( [
322 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
323 ] );
324
325 $this->assertEquals(
326 [
327 [
328 'ns' => 0,
329 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
330 ],
331 [
332 'ns' => 0,
333 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2',
334 ],
335 ],
336 $this->getItemsFromApiResponse( $result )
337 );
338 }
339
340 public function testContinueParam() {
341 $store = $this->getWatchedItemStore();
342
343 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
344 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
345 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
346 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
347 ] );
348
349 $firstResult = $this->doListWatchlistRawRequest( [ 'wrlimit' => 2 ] );
350 $continuationParam = $firstResult[0]['continue']['wrcontinue'];
351
352 $this->assertEquals( '0|ApiQueryWatchlistRawIntegrationTestPage3', $continuationParam );
353
354 $continuedResult = $this->doListWatchlistRawRequest( [ 'wrcontinue' => $continuationParam ] );
355
356 $this->assertEquals(
357 [
358 [
359 'ns' => 0,
360 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3',
361 ]
362 ],
363 $this->getItemsFromApiResponse( $continuedResult )
364 );
365 }
366
367 public function fromTitleToTitleContinueComboProvider() {
368 return [
369 [
370 [
371 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
372 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
373 ],
374 [
375 [ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1' ],
376 [ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
377 ],
378 ],
379 [
380 [
381 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
382 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
383 ],
384 [
385 [ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
386 ],
387 ],
388 [
389 [
390 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
391 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage2',
392 ],
393 [
394 [ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage2' ],
395 [ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
396 ],
397 ],
398 [
399 [
400 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
401 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage3',
402 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage3',
403 ],
404 [
405 [ 'ns' => 0, 'title' => 'ApiQueryWatchlistRawIntegrationTestPage3' ],
406 ],
407 ],
408 ];
409 }
410
411 /**
412 * @dataProvider fromTitleToTitleContinueComboProvider
413 */
414 public function testFromTitleToTitleContinueCombo( array $params, array $expectedItems ) {
415 $store = $this->getWatchedItemStore();
416
417 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
418 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
419 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
420 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage3' ),
421 ] );
422
423 $result = $this->doListWatchlistRawRequest( $params );
424
425 $this->assertEquals( $expectedItems, $this->getItemsFromApiResponse( $result ) );
426 }
427
428 public function fromTitleToTitleContinueSelfContradictoryComboProvider() {
429 return [
430 [
431 [
432 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
433 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
434 ]
435 ],
436 [
437 [
438 'wrfromtitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
439 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage2',
440 'wrdir' => 'descending',
441 ]
442 ],
443 [
444 [
445 'wrtotitle' => 'ApiQueryWatchlistRawIntegrationTestPage1',
446 'wrcontinue' => '0|ApiQueryWatchlistRawIntegrationTestPage2',
447 ]
448 ],
449 ];
450 }
451
452 /**
453 * @dataProvider fromTitleToTitleContinueSelfContradictoryComboProvider
454 */
455 public function testFromTitleToTitleContinueSelfContradictoryCombo( array $params ) {
456 $store = $this->getWatchedItemStore();
457
458 $store->addWatchBatchForUser( $this->getLoggedInTestUser(), [
459 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
460 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage2' ),
461 ] );
462
463 $result = $this->doListWatchlistRawRequest( $params );
464
465 $this->assertEmpty( $this->getItemsFromApiResponse( $result ) );
466 $this->assertArrayNotHasKey( 'continue', $result[0] );
467 }
468
469 public function testOwnerAndTokenParams() {
470 $otherUser = $this->getNotLoggedInTestUser();
471 $otherUser->setOption( 'watchlisttoken', '1234567890' );
472 $otherUser->saveSettings();
473
474 $store = $this->getWatchedItemStore();
475 $store->addWatchBatchForUser( $otherUser, [
476 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
477 new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
478 ] );
479
480 ObjectCache::getMainWANInstance()->clearProcessCache();
481 $result = $this->doListWatchlistRawRequest( [
482 'wrowner' => $otherUser->getName(),
483 'wrtoken' => '1234567890',
484 ] );
485
486 $this->assertEquals(
487 [
488 [
489 'ns' => 0,
490 'title' => 'ApiQueryWatchlistRawIntegrationTestPage1',
491 ],
492 [
493 'ns' => 1,
494 'title' => 'Talk:ApiQueryWatchlistRawIntegrationTestPage1',
495 ],
496 ],
497 $this->getItemsFromApiResponse( $result )
498 );
499 }
500
501 public function testOwnerAndTokenParams_wrongToken() {
502 $otherUser = $this->getNotLoggedInTestUser();
503 $otherUser->setOption( 'watchlisttoken', '1234567890' );
504 $otherUser->saveSettings();
505
506 $this->setExpectedException( ApiUsageException::class, 'Incorrect watchlist token provided' );
507
508 $this->doListWatchlistRawRequest( [
509 'wrowner' => $otherUser->getName(),
510 'wrtoken' => 'wrong-token',
511 ] );
512 }
513
514 public function testOwnerAndTokenParams_userHasNoWatchlistToken() {
515 $this->setExpectedException( ApiUsageException::class, 'Incorrect watchlist token provided' );
516
517 $this->doListWatchlistRawRequest( [
518 'wrowner' => $this->getNotLoggedInTestUser()->getName(),
519 'wrtoken' => 'some-watchlist-token',
520 ] );
521 }
522
523 public function testGeneratorWatchlistRawPropInfo_returnsWatchedItems() {
524 $store = $this->getWatchedItemStore();
525 $store->addWatch(
526 $this->getLoggedInTestUser(),
527 new TitleValue( 0, 'ApiQueryWatchlistRawIntegrationTestPage' )
528 );
529
530 $result = $this->doGeneratorWatchlistRawRequest( [ 'prop' => 'info' ] );
531
532 $this->assertArrayHasKey( 'query', $result[0] );
533 $this->assertArrayHasKey( 'pages', $result[0]['query'] );
534 $this->assertCount( 1, $result[0]['query']['pages'] );
535
536 // $result[0]['query']['pages'] uses page ids as keys
537 $item = array_values( $result[0]['query']['pages'] )[0];
538
539 $this->assertEquals( 0, $item['ns'] );
540 $this->assertEquals( 'ApiQueryWatchlistRawIntegrationTestPage', $item['title'] );
541 }
542
543 }