5 use Wikimedia\ScopedCallback;
6 use Wikimedia\TestingAccessWrapper;
27 $expectedConnectionType =
null
30 ->disableOriginalConstructor()
32 if ( $expectedConnectionType !==
null ) {
33 $mock->expects( $this->
any() )
34 ->method(
'getConnectionRef' )
35 ->with( $expectedConnectionType )
36 ->will( $this->returnValue( $mockDb ) );
38 $mock->expects( $this->
any() )
39 ->method(
'getConnectionRef' )
40 ->will( $this->returnValue( $mockDb ) );
50 $expectedConnectionType =
null
54 ->disableOriginalConstructor()
56 $mock->expects( $this->
any() )
57 ->method(
'getMainLB' )
58 ->will( $this->returnValue( $loadBalancer ) );
67 ->disableOriginalConstructor()
68 ->setMethods( [
'get',
'set',
'delete',
'makeKey' ] )
70 $mock->expects( $this->
any() )
72 ->will( $this->returnCallback(
function () {
73 return implode(
':', func_get_args() );
83 ->disableOriginalConstructor()
85 $mock->expects( $this->
any() )
86 ->method(
'isReadOnly' )
87 ->will( $this->returnValue( $readOnly ) );
97 $mock->expects( $this->
any() )
99 ->will( $this->returnValue(
false ) );
100 $mock->expects( $this->
any() )
102 ->will( $this->returnValue( $id ) );
114 $fakeRow =
new stdClass();
115 foreach ( $rowValues
as $valueName =>
$value ) {
116 $fakeRow->$valueName =
$value;
136 $mockDb->expects( $this->once() )
137 ->method(
'selectField' )
142 'wl_user' =>
$user->getId(),
144 $this->isType(
'string' )
146 ->
will( $this->returnValue( 12 ) );
147 $mockDb->expects( $this->once() )
152 $this->isType(
'string' )
156 $mockCache->expects( $this->never() )->method(
'get' );
157 $mockCache->expects( $this->never() )->method(
'set' );
158 $mockCache->expects( $this->once() )
167 TestingAccessWrapper::newFromObject( $store )
168 ->cacheIndex = [ 0 => [
'F' => [ 7 =>
'RM-KEY', 9 =>
'KEEP-KEY' ] ] ];
170 $this->assertTrue( $store->clearUserWatchedItems(
$user ) );
177 $mockDb->expects( $this->once() )
178 ->method(
'selectField' )
183 'wl_user' =>
$user->getId(),
185 $this->isType(
'string' )
187 ->
will( $this->returnValue( 99999 ) );
190 $mockCache->expects( $this->never() )->method(
'get' );
191 $mockCache->expects( $this->never() )->method(
'set' );
192 $mockCache->expects( $this->never() )->method(
'delete' );
200 $this->assertFalse( $store->clearUserWatchedItems(
$user ) );
207 $mockDb->expects( $this->exactly( 1 ) )
208 ->method(
'selectField' )
213 'wl_user' =>
$user->getId(),
215 $this->isType(
'string' )
217 ->
will( $this->returnValue(
'12' ) );
220 $mockCache->expects( $this->never() )->method(
'get' );
221 $mockCache->expects( $this->never() )->method(
'set' );
222 $mockCache->expects( $this->never() )->method(
'delete' );
230 $this->assertEquals( 12, $store->countWatchedItems(
$user ) );
234 $titleValue =
new TitleValue( 0,
'SomeDbKey' );
237 $mockDb->expects( $this->exactly( 1 ) )
238 ->method(
'selectField' )
243 'wl_namespace' => $titleValue->getNamespace(),
244 'wl_title' => $titleValue->getDBkey(),
246 $this->isType(
'string' )
248 ->
will( $this->returnValue(
'7' ) );
251 $mockCache->expects( $this->never() )->method(
'get' );
252 $mockCache->expects( $this->never() )->method(
'set' );
253 $mockCache->expects( $this->never() )->method(
'delete' );
261 $this->assertEquals( 7, $store->countWatchers( $titleValue ) );
274 $this->
getFakeRow( [
'wl_title' =>
'SomeDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'100' ] ),
275 $this->
getFakeRow( [
'wl_title' =>
'OtherDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'300' ] ),
276 $this->
getFakeRow( [
'wl_title' =>
'AnotherDbKey',
'wl_namespace' =>
'1',
'watchers' =>
'500' ]
279 $mockDb->expects( $this->once() )
280 ->method(
'makeWhereFrom2d' )
282 [ [
'SomeDbKey' => 1,
'OtherDbKey' => 1 ], [
'AnotherDbKey' => 1 ] ],
283 $this->isType(
'string' ),
284 $this->isType(
'string' )
286 ->will( $this->returnValue(
'makeWhereFrom2d return value' ) );
287 $mockDb->expects( $this->once() )
291 [
'wl_title',
'wl_namespace',
'watchers' =>
'COUNT(*)' ],
292 [
'makeWhereFrom2d return value' ],
293 $this->isType(
'string' ),
295 'GROUP BY' => [
'wl_namespace',
'wl_title' ],
299 $this->returnValue( $dbResult )
303 $mockCache->expects( $this->never() )->method(
'get' );
304 $mockCache->expects( $this->never() )->method(
'set' );
305 $mockCache->expects( $this->never() )->method(
'delete' );
314 0 => [
'SomeDbKey' => 100,
'OtherDbKey' => 300 ],
315 1 => [
'AnotherDbKey' => 500 ],
317 $this->assertEquals( $expected, $store->countWatchersMultiple( $titleValues ) );
323 [
"50; DROP TABLE watchlist;\n--" ],
340 $this->
getFakeRow( [
'wl_title' =>
'SomeDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'100' ] ),
341 $this->
getFakeRow( [
'wl_title' =>
'OtherDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'300' ] ),
342 $this->
getFakeRow( [
'wl_title' =>
'AnotherDbKey',
'wl_namespace' =>
'1',
'watchers' =>
'500' ]
345 $mockDb->expects( $this->once() )
346 ->method(
'makeWhereFrom2d' )
348 [ [
'SomeDbKey' => 1,
'OtherDbKey' => 1 ], [
'AnotherDbKey' => 1 ] ],
349 $this->isType(
'string' ),
350 $this->isType(
'string' )
352 ->will( $this->returnValue(
'makeWhereFrom2d return value' ) );
353 $mockDb->expects( $this->once() )
357 [
'wl_title',
'wl_namespace',
'watchers' =>
'COUNT(*)' ],
358 [
'makeWhereFrom2d return value' ],
359 $this->isType(
'string' ),
361 'GROUP BY' => [
'wl_namespace',
'wl_title' ],
362 'HAVING' =>
'COUNT(*) >= 50',
366 $this->returnValue( $dbResult )
370 $mockCache->expects( $this->never() )->method(
'get' );
371 $mockCache->expects( $this->never() )->method(
'set' );
372 $mockCache->expects( $this->never() )->method(
'delete' );
381 0 => [
'SomeDbKey' => 100,
'OtherDbKey' => 300 ],
382 1 => [
'AnotherDbKey' => 500 ],
386 $store->countWatchersMultiple( $titleValues, [
'minimumWatchers' => $minWatchers ] )
391 $titleValue =
new TitleValue( 0,
'SomeDbKey' );
394 $mockDb->expects( $this->exactly( 1 ) )
395 ->method(
'selectField' )
400 'wl_namespace' => $titleValue->getNamespace(),
401 'wl_title' => $titleValue->getDBkey(),
402 'wl_notificationtimestamp >= \'TS111TS\' OR wl_notificationtimestamp IS NULL',
404 $this->isType(
'string' )
406 ->
will( $this->returnValue(
'7' ) );
407 $mockDb->expects( $this->exactly( 1 ) )
408 ->method(
'addQuotes' )
409 ->will( $this->returnCallback(
function (
$value ) {
412 $mockDb->expects( $this->exactly( 1 ) )
413 ->method(
'timestamp' )
414 ->will( $this->returnCallback(
function (
$value ) {
415 return 'TS' .
$value .
'TS';
419 $mockCache->expects( $this->never() )->method(
'set' );
420 $mockCache->expects( $this->never() )->method(
'get' );
421 $mockCache->expects( $this->never() )->method(
'delete' );
429 $this->assertEquals( 7, $store->countVisitingWatchers( $titleValue,
'111' ) );
433 $titleValuesWithThresholds = [
436 [
new TitleValue( 1,
'AnotherDbKey' ),
'123' ],
440 $this->
getFakeRow( [
'wl_title' =>
'SomeDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'100' ] ),
441 $this->
getFakeRow( [
'wl_title' =>
'OtherDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'300' ] ),
443 [
'wl_title' =>
'AnotherDbKey',
'wl_namespace' =>
'1',
'watchers' =>
'500' ]
447 $mockDb->expects( $this->exactly( 2 * 3 ) )
448 ->method(
'addQuotes' )
449 ->will( $this->returnCallback(
function (
$value ) {
452 $mockDb->expects( $this->exactly( 3 ) )
453 ->method(
'timestamp' )
454 ->will( $this->returnCallback(
function (
$value ) {
455 return 'TS' .
$value .
'TS';
457 $mockDb->expects( $this->
any() )
458 ->method(
'makeList' )
460 $this->isType(
'array' ),
461 $this->isType(
'int' )
463 ->will( $this->returnCallback(
function ( $a, $conj ) {
464 $sqlConj = $conj ===
LIST_AND ?
' AND ' :
' OR ';
465 return implode( $sqlConj, array_map(
function (
$s ) {
466 return '(' .
$s .
')';
470 $mockDb->expects( $this->never() )
471 ->method(
'makeWhereFrom2d' );
474 '((wl_namespace = 0) AND (' .
475 "(((wl_title = 'SomeDbKey') AND (" .
476 "(wl_notificationtimestamp >= 'TS111TS') OR (wl_notificationtimestamp IS NULL)" .
478 "(wl_title = 'OtherDbKey') AND (" .
479 "(wl_notificationtimestamp >= 'TS111TS') OR (wl_notificationtimestamp IS NULL)" .
481 ') OR ((wl_namespace = 1) AND (' .
482 "(((wl_title = 'AnotherDbKey') AND (" .
483 "(wl_notificationtimestamp >= 'TS123TS') OR (wl_notificationtimestamp IS NULL)" .
485 $mockDb->expects( $this->once() )
489 [
'wl_namespace',
'wl_title',
'watchers' =>
'COUNT(*)' ],
491 $this->isType(
'string' ),
493 'GROUP BY' => [
'wl_namespace',
'wl_title' ],
497 $this->returnValue( $dbResult )
501 $mockCache->expects( $this->never() )->method(
'get' );
502 $mockCache->expects( $this->never() )->method(
'set' );
503 $mockCache->expects( $this->never() )->method(
'delete' );
512 0 => [
'SomeDbKey' => 100,
'OtherDbKey' => 300 ],
513 1 => [
'AnotherDbKey' => 500 ],
517 $store->countVisitingWatchersMultiple( $titleValuesWithThresholds )
522 $titleValuesWithThresholds = [
525 [
new TitleValue( 1,
'AnotherDbKey' ),
'123' ],
526 [
new TitleValue( 0,
'SomeNotExisitingDbKey' ), null ],
527 [
new TitleValue( 0,
'OtherNotExisitingDbKey' ), null ],
531 $this->
getFakeRow( [
'wl_title' =>
'SomeDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'100' ] ),
532 $this->
getFakeRow( [
'wl_title' =>
'OtherDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'300' ] ),
534 [
'wl_title' =>
'AnotherDbKey',
'wl_namespace' =>
'1',
'watchers' =>
'500' ]
537 [
'wl_title' =>
'SomeNotExisitingDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'100' ]
540 [
'wl_title' =>
'OtherNotExisitingDbKey',
'wl_namespace' =>
'0',
'watchers' =>
'200' ]
544 $mockDb->expects( $this->exactly( 2 * 3 ) )
545 ->method(
'addQuotes' )
546 ->will( $this->returnCallback(
function (
$value ) {
549 $mockDb->expects( $this->exactly( 3 ) )
550 ->method(
'timestamp' )
551 ->will( $this->returnCallback(
function (
$value ) {
552 return 'TS' .
$value .
'TS';
554 $mockDb->expects( $this->
any() )
555 ->method(
'makeList' )
557 $this->isType(
'array' ),
558 $this->isType(
'int' )
560 ->will( $this->returnCallback(
function ( $a, $conj ) {
561 $sqlConj = $conj ===
LIST_AND ?
' AND ' :
' OR ';
562 return implode( $sqlConj, array_map(
function (
$s ) {
563 return '(' .
$s .
')';
567 $mockDb->expects( $this->once() )
568 ->method(
'makeWhereFrom2d' )
570 [ [
'SomeNotExisitingDbKey' => 1,
'OtherNotExisitingDbKey' => 1 ] ],
571 $this->isType(
'string' ),
572 $this->isType(
'string' )
574 ->will( $this->returnValue(
'makeWhereFrom2d return value' ) );
577 '((wl_namespace = 0) AND (' .
578 "(((wl_title = 'SomeDbKey') AND (" .
579 "(wl_notificationtimestamp >= 'TS111TS') OR (wl_notificationtimestamp IS NULL)" .
581 "(wl_title = 'OtherDbKey') AND (" .
582 "(wl_notificationtimestamp >= 'TS111TS') OR (wl_notificationtimestamp IS NULL)" .
584 ') OR ((wl_namespace = 1) AND (' .
585 "(((wl_title = 'AnotherDbKey') AND (" .
586 "(wl_notificationtimestamp >= 'TS123TS') OR (wl_notificationtimestamp IS NULL)" .
589 '(makeWhereFrom2d return value)';
590 $mockDb->expects( $this->once() )
594 [
'wl_namespace',
'wl_title',
'watchers' =>
'COUNT(*)' ],
596 $this->isType(
'string' ),
598 'GROUP BY' => [
'wl_namespace',
'wl_title' ],
602 $this->returnValue( $dbResult )
606 $mockCache->expects( $this->never() )->method(
'get' );
607 $mockCache->expects( $this->never() )->method(
'set' );
608 $mockCache->expects( $this->never() )->method(
'delete' );
618 'SomeDbKey' => 100,
'OtherDbKey' => 300,
619 'SomeNotExisitingDbKey' => 100,
'OtherNotExisitingDbKey' => 200
621 1 => [
'AnotherDbKey' => 500 ],
625 $store->countVisitingWatchersMultiple( $titleValuesWithThresholds )
633 $titleValuesWithThresholds = [
636 [
new TitleValue( 1,
'AnotherDbKey' ),
'123' ],
640 $mockDb->expects( $this->
any() )
641 ->method(
'makeList' )
642 ->will( $this->returnValue(
'makeList return value' ) );
643 $mockDb->expects( $this->once() )
647 [
'wl_namespace',
'wl_title',
'watchers' =>
'COUNT(*)' ],
648 'makeList return value',
649 $this->isType(
'string' ),
651 'GROUP BY' => [
'wl_namespace',
'wl_title' ],
652 'HAVING' =>
'COUNT(*) >= 50',
656 $this->returnValue( [] )
660 $mockCache->expects( $this->never() )->method(
'get' );
661 $mockCache->expects( $this->never() )->method(
'set' );
662 $mockCache->expects( $this->never() )->method(
'delete' );
671 0 => [
'SomeDbKey' => 0,
'OtherDbKey' => 0 ],
672 1 => [
'AnotherDbKey' => 0 ],
676 $store->countVisitingWatchersMultiple( $titleValuesWithThresholds, $minWatchers )
684 $mockDb->expects( $this->exactly( 1 ) )
685 ->method(
'selectRowCount' )
690 "wl_notificationtimestamp IS NOT NULL",
693 $this->isType(
'string' )
695 ->will( $this->returnValue(
'9' ) );
698 $mockCache->expects( $this->never() )->method(
'set' );
699 $mockCache->expects( $this->never() )->method(
'get' );
700 $mockCache->expects( $this->never() )->method(
'delete' );
708 $this->assertEquals( 9, $store->countUnreadNotifications(
$user ) );
718 $mockDb->expects( $this->exactly( 1 ) )
719 ->method(
'selectRowCount' )
724 "wl_notificationtimestamp IS NOT NULL",
727 $this->isType(
'string' ),
730 ->will( $this->returnValue(
'50' ) );
733 $mockCache->expects( $this->never() )->method(
'set' );
734 $mockCache->expects( $this->never() )->method(
'get' );
735 $mockCache->expects( $this->never() )->method(
'delete' );
745 $store->countUnreadNotifications(
$user, $limit )
756 $mockDb->expects( $this->exactly( 1 ) )
757 ->method(
'selectRowCount' )
762 "wl_notificationtimestamp IS NOT NULL",
765 $this->isType(
'string' ),
768 ->will( $this->returnValue(
'9' ) );
771 $mockCache->expects( $this->never() )->method(
'set' );
772 $mockCache->expects( $this->never() )->method(
'get' );
773 $mockCache->expects( $this->never() )->method(
'delete' );
783 $store->countUnreadNotifications(
$user, $limit )
789 $mockDb->expects( $this->once() )
795 'wl_notificationtimestamp',
799 'wl_title' =>
'Old_Title',
801 'WatchedItemStore::duplicateEntry',
804 ->will( $this->returnValue(
new FakeResultWrapper( [] ) ) );
812 $store->duplicateEntry(
820 $this->
getFakeRow( [
'wl_user' =>
'1',
'wl_notificationtimestamp' =>
'20151212010101' ] ),
821 $this->
getFakeRow( [
'wl_user' =>
'2',
'wl_notificationtimestamp' =>
null ] ),
825 $mockDb->expects( $this->at( 0 ) )
831 'wl_notificationtimestamp',
835 'wl_title' =>
'Old_Title',
838 ->will( $this->returnValue(
new FakeResultWrapper( $fakeRows ) ) );
839 $mockDb->expects( $this->at( 1 ) )
840 ->method(
'replace' )
843 [ [
'wl_user',
'wl_namespace',
'wl_title' ] ],
848 'wl_title' =>
'New_Title',
849 'wl_notificationtimestamp' =>
'20151212010101',
854 'wl_title' =>
'New_Title',
855 'wl_notificationtimestamp' =>
null,
858 $this->isType(
'string' )
862 $mockCache->expects( $this->never() )->method(
'get' );
863 $mockCache->expects( $this->never() )->method(
'delete' );
871 $store->duplicateEntry(
879 $mockDb->expects( $this->at( 0 ) )
885 'wl_notificationtimestamp',
889 'wl_title' =>
'Old_Title',
892 ->will( $this->returnValue(
new FakeResultWrapper( [] ) ) );
893 $mockDb->expects( $this->at( 1 ) )
899 'wl_notificationtimestamp',
903 'wl_title' =>
'Old_Title',
906 ->will( $this->returnValue(
new FakeResultWrapper( [] ) ) );
909 $mockCache->expects( $this->never() )->method(
'get' );
910 $mockCache->expects( $this->never() )->method(
'delete' );
918 $store->duplicateAllAssociatedEntries(
939 $this->
getFakeRow( [
'wl_user' =>
'1',
'wl_notificationtimestamp' =>
'20151212010101' ] ),
943 $mockDb->expects( $this->at( 0 ) )
949 'wl_notificationtimestamp',
953 'wl_title' => $oldTarget->
getDBkey(),
956 ->
will( $this->returnValue(
new FakeResultWrapper( $fakeRows ) ) );
957 $mockDb->expects( $this->at( 1 ) )
958 ->method(
'replace' )
961 [ [
'wl_user',
'wl_namespace',
'wl_title' ] ],
966 'wl_title' => $newTarget->
getDBkey(),
967 'wl_notificationtimestamp' =>
'20151212010101',
970 $this->isType(
'string' )
972 $mockDb->expects( $this->at( 2 ) )
978 'wl_notificationtimestamp',
982 'wl_title' => $oldTarget->
getDBkey(),
985 ->
will( $this->returnValue(
new FakeResultWrapper( $fakeRows ) ) );
986 $mockDb->expects( $this->at( 3 ) )
987 ->method(
'replace' )
990 [ [
'wl_user',
'wl_namespace',
'wl_title' ] ],
995 'wl_title' => $newTarget->
getDBkey(),
996 'wl_notificationtimestamp' =>
'20151212010101',
999 $this->isType(
'string' )
1003 $mockCache->expects( $this->never() )->method(
'get' );
1004 $mockCache->expects( $this->never() )->method(
'delete' );
1012 $store->duplicateAllAssociatedEntries(
1020 $mockDb->expects( $this->once() )
1021 ->method(
'insert' )
1027 'wl_namespace' => 0,
1028 'wl_title' =>
'Some_Page',
1029 'wl_notificationtimestamp' =>
null,
1035 $mockCache->expects( $this->once() )
1036 ->method(
'delete' )
1037 ->with(
'0:Some_Page:1' );
1053 $mockDb->expects( $this->never() )
1054 ->method(
'insert' );
1057 $mockCache->expects( $this->never() )
1058 ->method(
'delete' );
1080 $store->addWatchBatchForUser(
1081 $this->getMockNonAnonUserWithId( 1 ),
1089 $mockDb->expects( $this->once() )
1090 ->method(
'insert' )
1096 'wl_namespace' => 0,
1097 'wl_title' =>
'Some_Page',
1098 'wl_notificationtimestamp' =>
null,
1102 'wl_namespace' => 1,
1103 'wl_title' =>
'Some_Page',
1104 'wl_notificationtimestamp' =>
null,
1110 $mockCache->expects( $this->exactly( 2 ) )
1111 ->method(
'delete' );
1112 $mockCache->expects( $this->at( 1 ) )
1113 ->method(
'delete' )
1114 ->with(
'0:Some_Page:1' );
1115 $mockCache->expects( $this->at( 3 ) )
1116 ->method(
'delete' )
1117 ->with(
'1:Some_Page:1' );
1128 $store->addWatchBatchForUser(
1137 $mockDb->expects( $this->never() )
1138 ->method(
'insert' );
1141 $mockCache->expects( $this->never() )
1142 ->method(
'delete' );
1151 $store->addWatchBatchForUser(
1152 $this->getAnonUser(),
1161 $mockDb->expects( $this->never() )
1162 ->method(
'insert' );
1165 $mockCache->expects( $this->never() )
1166 ->method(
'delete' );
1175 $store->addWatchBatchForUser(
$user, [] )
1181 $mockDb->expects( $this->once() )
1182 ->method(
'selectRow' )
1185 'wl_notificationtimestamp',
1188 'wl_namespace' => 0,
1189 'wl_title' =>
'SomeDbKey',
1192 ->will( $this->returnValue(
1193 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'20151212010101' ] )
1197 $mockCache->expects( $this->once() )
1209 $watchedItem = $store->loadWatchedItem(
1214 $this->assertEquals( 1, $watchedItem->getUser()->getId() );
1215 $this->assertEquals(
'SomeDbKey', $watchedItem->getLinkTarget()->getDBkey() );
1216 $this->assertEquals( 0, $watchedItem->getLinkTarget()->getNamespace() );
1221 $mockDb->expects( $this->once() )
1222 ->method(
'selectRow' )
1225 'wl_notificationtimestamp',
1228 'wl_namespace' => 0,
1229 'wl_title' =>
'SomeDbKey',
1232 ->will( $this->returnValue( [] ) );
1235 $mockCache->expects( $this->never() )->method(
'get' );
1236 $mockCache->expects( $this->never() )->method(
'delete' );
1245 $store->loadWatchedItem(
1246 $this->getMockNonAnonUserWithId( 1 ),
1254 $mockDb->expects( $this->never() )
1255 ->method(
'selectRow' );
1258 $mockCache->expects( $this->never() )->method(
'get' );
1259 $mockCache->expects( $this->never() )->method(
'delete' );
1268 $store->loadWatchedItem(
1269 $this->getAnonUser(),
1277 $mockDb->expects( $this->once() )
1278 ->method(
'delete' )
1283 'wl_namespace' => 0,
1284 'wl_title' =>
'SomeDbKey',
1287 $mockDb->expects( $this->once() )
1288 ->method(
'affectedRows' )
1289 ->will( $this->returnValue( 1 ) );
1292 $mockCache->expects( $this->never() )->method(
'get' );
1293 $mockCache->expects( $this->once() )
1294 ->method(
'delete' )
1295 ->with(
'0:SomeDbKey:1' );
1304 $store->removeWatch(
1305 $this->getMockNonAnonUserWithId( 1 ),
1313 $mockDb->expects( $this->once() )
1314 ->method(
'delete' )
1319 'wl_namespace' => 0,
1320 'wl_title' =>
'SomeDbKey',
1323 $mockDb->expects( $this->once() )
1324 ->method(
'affectedRows' )
1325 ->will( $this->returnValue( 0 ) );
1328 $mockCache->expects( $this->never() )->method(
'get' );
1329 $mockCache->expects( $this->once() )
1330 ->method(
'delete' )
1331 ->with(
'0:SomeDbKey:1' );
1340 $store->removeWatch(
1341 $this->getMockNonAnonUserWithId( 1 ),
1349 $mockDb->expects( $this->never() )
1350 ->method(
'delete' );
1353 $mockCache->expects( $this->never() )->method(
'get' );
1354 $mockCache->expects( $this->never() )
1355 ->method(
'delete' );
1364 $store->removeWatch(
1365 $this->getAnonUser(),
1373 $mockDb->expects( $this->once() )
1374 ->method(
'selectRow' )
1377 'wl_notificationtimestamp',
1380 'wl_namespace' => 0,
1381 'wl_title' =>
'SomeDbKey',
1384 ->will( $this->returnValue(
1385 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'20151212010101' ] )
1389 $mockCache->expects( $this->never() )->method(
'delete' );
1390 $mockCache->expects( $this->once() )
1395 ->will( $this->returnValue(
null ) );
1396 $mockCache->expects( $this->once() )
1408 $watchedItem = $store->getWatchedItem(
1413 $this->assertEquals( 1, $watchedItem->getUser()->getId() );
1414 $this->assertEquals(
'SomeDbKey', $watchedItem->getLinkTarget()->getDBkey() );
1415 $this->assertEquals( 0, $watchedItem->getLinkTarget()->getNamespace() );
1420 $mockDb->expects( $this->never() )
1421 ->method(
'selectRow' );
1424 $linkTarget =
new TitleValue( 0,
'SomeDbKey' );
1425 $cachedItem =
new WatchedItem( $mockUser, $linkTarget,
'20151212010101' );
1428 $mockCache->expects( $this->never() )->method(
'delete' );
1429 $mockCache->expects( $this->never() )->method(
'set' );
1430 $mockCache->expects( $this->once() )
1435 ->will( $this->returnValue( $cachedItem ) );
1443 $this->assertEquals(
1445 $store->getWatchedItem(
1454 $mockDb->expects( $this->once() )
1455 ->method(
'selectRow' )
1458 'wl_notificationtimestamp',
1461 'wl_namespace' => 0,
1462 'wl_title' =>
'SomeDbKey',
1465 ->will( $this->returnValue( [] ) );
1468 $mockCache->expects( $this->never() )->method(
'set' );
1469 $mockCache->expects( $this->never() )->method(
'delete' );
1470 $mockCache->expects( $this->once() )
1472 ->with(
'0:SomeDbKey:1' )
1473 ->will( $this->returnValue(
false ) );
1482 $store->getWatchedItem(
1483 $this->getMockNonAnonUserWithId( 1 ),
1491 $mockDb->expects( $this->never() )
1492 ->method(
'selectRow' );
1495 $mockCache->expects( $this->never() )->method(
'set' );
1496 $mockCache->expects( $this->never() )->method(
'get' );
1497 $mockCache->expects( $this->never() )->method(
'delete' );
1506 $store->getWatchedItem(
1507 $this->getAnonUser(),
1515 $mockDb->expects( $this->once() )
1516 ->method(
'select' )
1519 [
'wl_namespace',
'wl_title',
'wl_notificationtimestamp' ],
1522 ->will( $this->returnValue( [
1524 'wl_namespace' => 0,
1525 'wl_title' =>
'Foo1',
1526 'wl_notificationtimestamp' =>
'20151212010101',
1529 'wl_namespace' => 1,
1530 'wl_title' =>
'Foo2',
1531 'wl_notificationtimestamp' =>
null,
1536 $mockCache->expects( $this->never() )->method(
'delete' );
1537 $mockCache->expects( $this->never() )->method(
'get' );
1538 $mockCache->expects( $this->never() )->method(
'set' );
1547 $watchedItems = $store->getWatchedItemsForUser(
$user );
1549 $this->assertInternalType(
'array', $watchedItems );
1550 $this->assertCount( 2, $watchedItems );
1551 foreach ( $watchedItems
as $watchedItem ) {
1554 $this->assertEquals(
1558 $this->assertEquals(
1580 $mockDb->expects( $this->once() )
1581 ->method(
'select' )
1584 [
'wl_namespace',
'wl_title',
'wl_notificationtimestamp' ],
1586 $this->isType(
'string' ),
1587 [
'ORDER BY' => [
'wl_namespace ASC',
'wl_title ASC' ] ]
1589 ->will( $this->returnValue( [] ) );
1597 $watchedItems = $store->getWatchedItemsForUser(
1601 $this->assertEquals( [], $watchedItems );
1612 $store->getWatchedItemsForUser(
1620 $mockDb->expects( $this->once() )
1621 ->method(
'selectRow' )
1624 'wl_notificationtimestamp',
1627 'wl_namespace' => 0,
1628 'wl_title' =>
'SomeDbKey',
1631 ->will( $this->returnValue(
1632 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'20151212010101' ] )
1636 $mockCache->expects( $this->never() )->method(
'delete' );
1637 $mockCache->expects( $this->once() )
1639 ->with(
'0:SomeDbKey:1' )
1640 ->will( $this->returnValue(
false ) );
1641 $mockCache->expects( $this->once() )
1655 $this->getMockNonAnonUserWithId( 1 ),
1663 $mockDb->expects( $this->once() )
1664 ->method(
'selectRow' )
1667 'wl_notificationtimestamp',
1670 'wl_namespace' => 0,
1671 'wl_title' =>
'SomeDbKey',
1674 ->will( $this->returnValue( [] ) );
1677 $mockCache->expects( $this->never() )->method(
'set' );
1678 $mockCache->expects( $this->never() )->method(
'delete' );
1679 $mockCache->expects( $this->once() )
1681 ->with(
'0:SomeDbKey:1' )
1682 ->will( $this->returnValue(
false ) );
1692 $this->getMockNonAnonUserWithId( 1 ),
1700 $mockDb->expects( $this->never() )
1701 ->method(
'selectRow' );
1704 $mockCache->expects( $this->never() )->method(
'set' );
1705 $mockCache->expects( $this->never() )->method(
'get' );
1706 $mockCache->expects( $this->never() )->method(
'delete' );
1716 $this->getAnonUser(),
1731 'wl_namespace' =>
'0',
1732 'wl_title' =>
'SomeDbKey',
1733 'wl_notificationtimestamp' =>
'20151212010101',
1737 'wl_namespace' =>
'1',
1738 'wl_title' =>
'AnotherDbKey',
1739 'wl_notificationtimestamp' =>
null,
1744 $mockDb->expects( $this->once() )
1745 ->method(
'makeWhereFrom2d' )
1747 [ [
'SomeDbKey' => 1 ], [
'AnotherDbKey' => 1 ] ],
1748 $this->isType(
'string' ),
1749 $this->isType(
'string' )
1751 ->will( $this->returnValue(
'makeWhereFrom2d return value' ) );
1752 $mockDb->expects( $this->once() )
1753 ->method(
'select' )
1756 [
'wl_namespace',
'wl_title',
'wl_notificationtimestamp' ],
1758 'makeWhereFrom2d return value',
1761 $this->isType(
'string' )
1763 ->will( $this->returnValue( $dbResult ) );
1766 $mockCache->expects( $this->exactly( 2 ) )
1769 [
'0:SomeDbKey:1' ],
1770 [
'1:AnotherDbKey:1' ]
1772 ->will( $this->returnValue(
null ) );
1773 $mockCache->expects( $this->never() )->method(
'set' );
1774 $mockCache->expects( $this->never() )->method(
'delete' );
1782 $this->assertEquals(
1784 0 => [
'SomeDbKey' =>
'20151212010101', ],
1785 1 => [
'AnotherDbKey' =>
null, ],
1787 $store->getNotificationTimestampsBatch( $this->getMockNonAnonUserWithId( 1 ), $targets )
1798 $mockDb->expects( $this->once() )
1799 ->method(
'makeWhereFrom2d' )
1801 [ [
'OtherDbKey' => 1 ] ],
1802 $this->isType(
'string' ),
1803 $this->isType(
'string' )
1805 ->will( $this->returnValue(
'makeWhereFrom2d return value' ) );
1806 $mockDb->expects( $this->once() )
1807 ->method(
'select' )
1810 [
'wl_namespace',
'wl_title',
'wl_notificationtimestamp' ],
1812 'makeWhereFrom2d return value',
1815 $this->isType(
'string' )
1817 ->will( $this->returnValue( $this->
getFakeRow( [] ) ) );
1820 $mockCache->expects( $this->once() )
1822 ->with(
'0:OtherDbKey:1' )
1823 ->will( $this->returnValue(
null ) );
1824 $mockCache->expects( $this->never() )->method(
'set' );
1825 $mockCache->expects( $this->never() )->method(
'delete' );
1833 $this->assertEquals(
1835 0 => [
'OtherDbKey' =>
false, ],
1837 $store->getNotificationTimestampsBatch( $this->getMockNonAnonUserWithId( 1 ), $targets )
1852 $mockDb->expects( $this->once() )
1853 ->method(
'makeWhereFrom2d' )
1855 [ 1 => [
'AnotherDbKey' => 1 ] ],
1856 $this->isType(
'string' ),
1857 $this->isType(
'string' )
1859 ->will( $this->returnValue(
'makeWhereFrom2d return value' ) );
1860 $mockDb->expects( $this->once() )
1861 ->method(
'select' )
1864 [
'wl_namespace',
'wl_title',
'wl_notificationtimestamp' ],
1866 'makeWhereFrom2d return value',
1869 $this->isType(
'string' )
1871 ->will( $this->returnValue( [
1873 [
'wl_namespace' =>
'1',
'wl_title' =>
'AnotherDbKey',
'wl_notificationtimestamp' =>
null, ]
1878 $mockCache->expects( $this->at( 1 ) )
1880 ->with(
'0:SomeDbKey:1' )
1881 ->will( $this->returnValue( $cachedItem ) );
1882 $mockCache->expects( $this->at( 3 ) )
1884 ->with(
'1:AnotherDbKey:1' )
1885 ->will( $this->returnValue(
null ) );
1886 $mockCache->expects( $this->never() )->method(
'set' );
1887 $mockCache->expects( $this->never() )->method(
'delete' );
1895 $this->assertEquals(
1897 0 => [
'SomeDbKey' =>
'20151212010101', ],
1898 1 => [
'AnotherDbKey' =>
null, ],
1900 $store->getNotificationTimestampsBatch(
$user, $targets )
1916 $mockDb->expects( $this->never() )->method( $this->
anything() );
1919 $mockCache->expects( $this->at( 1 ) )
1921 ->with(
'0:SomeDbKey:1' )
1922 ->will( $this->returnValue( $cachedItems[0] ) );
1923 $mockCache->expects( $this->at( 3 ) )
1925 ->with(
'1:AnotherDbKey:1' )
1926 ->will( $this->returnValue( $cachedItems[1] ) );
1927 $mockCache->expects( $this->never() )->method(
'set' );
1928 $mockCache->expects( $this->never() )->method(
'delete' );
1936 $this->assertEquals(
1938 0 => [
'SomeDbKey' =>
'20151212010101', ],
1939 1 => [
'AnotherDbKey' =>
null, ],
1941 $store->getNotificationTimestampsBatch(
$user, $targets )
1952 $mockDb->expects( $this->never() )->method( $this->
anything() );
1955 $mockCache->expects( $this->never() )->method( $this->
anything() );
1963 $this->assertEquals(
1965 0 => [
'SomeDbKey' =>
false, ],
1966 1 => [
'AnotherDbKey' =>
false, ],
1968 $store->getNotificationTimestampsBatch( $this->getAnonUser(), $targets )
1974 $mockDb->expects( $this->never() )
1975 ->method(
'selectRow' );
1978 $mockCache->expects( $this->never() )->method(
'get' );
1979 $mockCache->expects( $this->never() )->method(
'set' );
1980 $mockCache->expects( $this->never() )->method(
'delete' );
1989 $store->resetNotificationTimestamp(
1990 $this->getAnonUser(),
1998 $mockDb->expects( $this->once() )
1999 ->method(
'selectRow' )
2002 'wl_notificationtimestamp',
2005 'wl_namespace' => 0,
2006 'wl_title' =>
'SomeDbKey',
2009 ->will( $this->returnValue( [] ) );
2012 $mockCache->expects( $this->never() )->method(
'get' );
2013 $mockCache->expects( $this->never() )->method(
'set' );
2014 $mockCache->expects( $this->never() )->method(
'delete' );
2023 $store->resetNotificationTimestamp(
2024 $this->getMockNonAnonUserWithId( 1 ),
2035 $mockDb->expects( $this->once() )
2036 ->method(
'selectRow' )
2039 'wl_notificationtimestamp',
2042 'wl_namespace' => 0,
2043 'wl_title' =>
'SomeDbKey',
2046 ->will( $this->returnValue(
2047 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'20151212010101' ] )
2051 $mockCache->expects( $this->never() )->method(
'get' );
2052 $mockCache->expects( $this->once() )
2058 $mockCache->expects( $this->once() )
2059 ->method(
'delete' )
2060 ->with(
'0:SomeDbKey:1' );
2069 $callableCallCounter = 0;
2070 $mockCallback =
function ( $callable )
use ( &$callableCallCounter ) {
2071 $callableCallCounter++;
2072 $this->assertInternalType(
'callable', $callable );
2074 $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
2077 $store->resetNotificationTimestamp(
2082 $this->assertEquals( 1, $callableCallCounter );
2084 ScopedCallback::consume( $scopedOverride );
2092 $mockDb->expects( $this->never() )
2093 ->method(
'selectRow' );
2096 $mockCache->expects( $this->never() )->method(
'get' );
2097 $mockCache->expects( $this->never() )->method(
'set' );
2098 $mockCache->expects( $this->once() )
2099 ->method(
'delete' )
2100 ->with(
'0:SomeDbKey:1' );
2109 $callableCallCounter = 0;
2110 $mockCallback =
function ( $callable )
use ( &$callableCallCounter ) {
2111 $callableCallCounter++;
2112 $this->assertInternalType(
'callable', $callable );
2114 $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback( $mockCallback );
2117 $store->resetNotificationTimestamp(
2123 $this->assertEquals( 1, $callableCallCounter );
2125 ScopedCallback::consume( $scopedOverride );
2137 ->method(
'getText' )
2138 ->will( $this->returnValue( str_replace(
'_',
' ', $text ) ) );
2140 ->method(
'getDbKey' )
2141 ->will( $this->returnValue( str_replace(
'_',
' ', $text ) ) );
2143 ->method(
'getNamespace' )
2144 ->will( $this->returnValue( $ns ) );
2152 callable $notificationTimestampCondition
2154 $this->assertInternalType(
'callable', $callback );
2156 $callbackReflector =
new ReflectionFunction( $callback );
2157 $vars = $callbackReflector->getStaticVariables();
2158 $this->assertArrayHasKey(
'job',
$vars );
2163 $this->assertEquals( $expectedTitle->
getDBkey(),
$job->getTitle()->getDBkey() );
2164 $this->assertEquals( $expectedTitle->
getNamespace(),
$job->getTitle()->getNamespace() );
2166 $jobParams =
$job->getParams();
2167 $this->assertArrayHasKey(
'type', $jobParams );
2168 $this->assertEquals(
'updateWatchlistNotification', $jobParams[
'type'] );
2169 $this->assertArrayHasKey(
'userid', $jobParams );
2170 $this->assertEquals( $expectedUserId, $jobParams[
'userid'] );
2171 $this->assertArrayHasKey(
'notifTime', $jobParams );
2172 $this->assertTrue( $notificationTimestampCondition( $jobParams[
'notifTime'] ) );
2179 $title->expects( $this->once() )
2180 ->method(
'getNextRevisionID' )
2182 ->will( $this->returnValue(
false ) );
2185 $mockDb->expects( $this->never() )
2186 ->method(
'selectRow' );
2189 $mockCache->expects( $this->never() )->method(
'get' );
2190 $mockCache->expects( $this->never() )->method(
'set' );
2191 $mockCache->expects( $this->once() )
2192 ->method(
'delete' )
2193 ->with(
'0:SomeTitle:1' );
2201 $callableCallCounter = 0;
2202 $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
2203 function ( $callable )
use ( &$callableCallCounter,
$title,
$user ) {
2204 $callableCallCounter++;
2209 function (
$time ) {
2210 return $time ===
null;
2217 $store->resetNotificationTimestamp(
2224 $this->assertEquals( 1, $callableCallCounter );
2226 ScopedCallback::consume( $scopedOverride );
2233 $title->expects( $this->once() )
2234 ->method(
'getNextRevisionID' )
2236 ->will( $this->returnValue( 33 ) );
2239 $mockDb->expects( $this->once() )
2240 ->method(
'selectRow' )
2243 'wl_notificationtimestamp',
2246 'wl_namespace' => 0,
2247 'wl_title' =>
'SomeDbKey',
2250 ->will( $this->returnValue(
2251 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'20151212010101' ] )
2255 $mockCache->expects( $this->never() )->method(
'get' );
2256 $mockCache->expects( $this->once() )
2258 ->with(
'0:SomeDbKey:1', $this->isType(
'object' ) );
2259 $mockCache->expects( $this->once() )
2260 ->method(
'delete' )
2261 ->with(
'0:SomeDbKey:1' );
2269 $addUpdateCallCounter = 0;
2270 $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
2271 function ( $callable )
use ( &$addUpdateCallCounter,
$title,
$user ) {
2272 $addUpdateCallCounter++;
2277 function (
$time ) {
2278 return $time !==
null &&
$time >
'20151212010101';
2284 $getTimestampCallCounter = 0;
2285 $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
2286 function ( $titleParam, $oldidParam )
use ( &$getTimestampCallCounter,
$title, $oldid ) {
2287 $getTimestampCallCounter++;
2288 $this->assertEquals(
$title, $titleParam );
2289 $this->assertEquals( $oldid, $oldidParam );
2294 $store->resetNotificationTimestamp(
2301 $this->assertEquals( 1, $addUpdateCallCounter );
2302 $this->assertEquals( 1, $getTimestampCallCounter );
2304 ScopedCallback::consume( $scopedOverrideDeferred );
2305 ScopedCallback::consume( $scopedOverrideRevision );
2312 $title->expects( $this->once() )
2313 ->method(
'getNextRevisionID' )
2315 ->will( $this->returnValue( 33 ) );
2318 $mockDb->expects( $this->once() )
2319 ->method(
'selectRow' )
2322 'wl_notificationtimestamp',
2325 'wl_namespace' => 0,
2326 'wl_title' =>
'SomeDbKey',
2329 ->will( $this->returnValue(
false ) );
2332 $mockCache->expects( $this->never() )->method(
'get' );
2333 $mockCache->expects( $this->never() )->method(
'set' );
2334 $mockCache->expects( $this->once() )
2335 ->method(
'delete' )
2336 ->with(
'0:SomeDbKey:1' );
2344 $callableCallCounter = 0;
2345 $scopedOverride = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
2346 function ( $callable )
use ( &$callableCallCounter,
$title,
$user ) {
2347 $callableCallCounter++;
2352 function (
$time ) {
2353 return $time ===
null;
2360 $store->resetNotificationTimestamp(
2367 $this->assertEquals( 1, $callableCallCounter );
2369 ScopedCallback::consume( $scopedOverride );
2376 $title->expects( $this->once() )
2377 ->method(
'getNextRevisionID' )
2379 ->will( $this->returnValue( 33 ) );
2382 $mockDb->expects( $this->once() )
2383 ->method(
'selectRow' )
2386 'wl_notificationtimestamp',
2389 'wl_namespace' => 0,
2390 'wl_title' =>
'SomeDbKey',
2393 ->will( $this->returnValue(
2394 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'30151212010101' ] )
2398 $mockCache->expects( $this->never() )->method(
'get' );
2399 $mockCache->expects( $this->once() )
2401 ->with(
'0:SomeDbKey:1', $this->isType(
'object' ) );
2402 $mockCache->expects( $this->once() )
2403 ->method(
'delete' )
2404 ->with(
'0:SomeDbKey:1' );
2412 $addUpdateCallCounter = 0;
2413 $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
2414 function ( $callable )
use ( &$addUpdateCallCounter,
$title,
$user ) {
2415 $addUpdateCallCounter++;
2420 function (
$time ) {
2421 return $time ===
'30151212010101';
2427 $getTimestampCallCounter = 0;
2428 $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
2429 function ( $titleParam, $oldidParam )
use ( &$getTimestampCallCounter,
$title, $oldid ) {
2430 $getTimestampCallCounter++;
2431 $this->assertEquals(
$title, $titleParam );
2432 $this->assertEquals( $oldid, $oldidParam );
2437 $store->resetNotificationTimestamp(
2444 $this->assertEquals( 1, $addUpdateCallCounter );
2445 $this->assertEquals( 1, $getTimestampCallCounter );
2447 ScopedCallback::consume( $scopedOverrideDeferred );
2448 ScopedCallback::consume( $scopedOverrideRevision );
2455 $title->expects( $this->once() )
2456 ->method(
'getNextRevisionID' )
2458 ->will( $this->returnValue( 33 ) );
2461 $mockDb->expects( $this->once() )
2462 ->method(
'selectRow' )
2465 'wl_notificationtimestamp',
2468 'wl_namespace' => 0,
2469 'wl_title' =>
'SomeDbKey',
2472 ->will( $this->returnValue(
2473 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'30151212010101' ] )
2477 $mockCache->expects( $this->never() )->method(
'get' );
2478 $mockCache->expects( $this->once() )
2480 ->with(
'0:SomeDbKey:1', $this->isType(
'object' ) );
2481 $mockCache->expects( $this->once() )
2482 ->method(
'delete' )
2483 ->with(
'0:SomeDbKey:1' );
2491 $addUpdateCallCounter = 0;
2492 $scopedOverrideDeferred = $store->overrideDeferredUpdatesAddCallableUpdateCallback(
2493 function ( $callable )
use ( &$addUpdateCallCounter,
$title,
$user ) {
2494 $addUpdateCallCounter++;
2499 function (
$time ) {
2500 return $time ===
false;
2506 $getTimestampCallCounter = 0;
2507 $scopedOverrideRevision = $store->overrideRevisionGetTimestampFromIdCallback(
2508 function ( $titleParam, $oldidParam )
use ( &$getTimestampCallCounter,
$title, $oldid ) {
2509 $getTimestampCallCounter++;
2510 $this->assertEquals(
$title, $titleParam );
2511 $this->assertEquals( $oldid, $oldidParam );
2516 $store->resetNotificationTimestamp(
2523 $this->assertEquals( 1, $addUpdateCallCounter );
2524 $this->assertEquals( 1, $getTimestampCallCounter );
2526 ScopedCallback::consume( $scopedOverrideDeferred );
2527 ScopedCallback::consume( $scopedOverrideRevision );
2536 $this->assertFalse( $store->setNotificationTimestampsForUser( $this->getAnonUser(),
'' ) );
2541 $timestamp =
'20100101010101';
2544 $mockDb->expects( $this->once() )
2545 ->method(
'update' )
2548 [
'wl_notificationtimestamp' =>
'TS' . $timestamp .
'TS' ],
2551 ->will( $this->returnValue(
true ) );
2552 $mockDb->expects( $this->exactly( 1 ) )
2553 ->method(
'timestamp' )
2554 ->will( $this->returnCallback(
function (
$value ) {
2555 return 'TS' .
$value .
'TS';
2565 $store->setNotificationTimestampsForUser(
$user, $timestamp )
2574 $mockDb->expects( $this->once() )
2575 ->method(
'update' )
2578 [
'wl_notificationtimestamp' =>
null ],
2581 ->will( $this->returnValue(
true ) );
2582 $mockDb->expects( $this->exactly( 0 ) )
2583 ->method(
'timestamp' )
2584 ->will( $this->returnCallback(
function (
$value ) {
2585 return 'TS' .
$value .
'TS';
2595 $store->setNotificationTimestampsForUser(
$user, $timestamp )
2601 $timestamp =
'20100101010101';
2605 $mockDb->expects( $this->once() )
2606 ->method(
'update' )
2609 [
'wl_notificationtimestamp' =>
'TS' . $timestamp .
'TS' ],
2610 [
'wl_user' => 1, 0 =>
'makeWhereFrom2d return value' ]
2612 ->will( $this->returnValue(
true ) );
2613 $mockDb->expects( $this->exactly( 1 ) )
2614 ->method(
'timestamp' )
2615 ->will( $this->returnCallback(
function (
$value ) {
2616 return 'TS' .
$value .
'TS';
2618 $mockDb->expects( $this->once() )
2619 ->method(
'makeWhereFrom2d' )
2621 [ [
'Foo' => 1,
'Bar' => 1 ] ],
2622 $this->isType(
'string' ),
2623 $this->isType(
'string' )
2625 ->will( $this->returnValue(
'makeWhereFrom2d return value' ) );
2634 $store->setNotificationTimestampsForUser(
$user, $timestamp, $targets )
2640 $mockDb->expects( $this->once() )
2641 ->method(
'selectFieldValues' )
2647 'wl_namespace' => 0,
2648 'wl_title' =>
'SomeDbKey',
2649 'wl_notificationtimestamp IS NULL'
2652 ->will( $this->returnValue( [
'2',
'3' ] ) );
2653 $mockDb->expects( $this->once() )
2654 ->method(
'update' )
2657 [
'wl_notificationtimestamp' =>
null ],
2659 'wl_user' => [ 2, 3 ],
2660 'wl_namespace' => 0,
2661 'wl_title' =>
'SomeDbKey',
2666 $mockCache->expects( $this->never() )->method(
'set' );
2667 $mockCache->expects( $this->never() )->method(
'get' );
2668 $mockCache->expects( $this->never() )->method(
'delete' );
2676 $this->assertEquals(
2678 $store->updateNotificationTimestamp(
2679 $this->getMockNonAnonUserWithId( 1 ),
2688 $mockDb->expects( $this->once() )
2689 ->method(
'selectFieldValues' )
2695 'wl_namespace' => 0,
2696 'wl_title' =>
'SomeDbKey',
2697 'wl_notificationtimestamp IS NULL'
2701 $this->returnValue( [] )
2703 $mockDb->expects( $this->never() )
2704 ->method(
'update' );
2707 $mockCache->expects( $this->never() )->method(
'set' );
2708 $mockCache->expects( $this->never() )->method(
'get' );
2709 $mockCache->expects( $this->never() )->method(
'delete' );
2717 $watchers = $store->updateNotificationTimestamp(
2722 $this->assertInternalType(
'array', $watchers );
2723 $this->assertEmpty( $watchers );
2728 $titleValue =
new TitleValue( 0,
'SomeDbKey' );
2731 $mockDb->expects( $this->once() )
2732 ->method(
'selectRow' )
2733 ->will( $this->returnValue(
2734 $this->
getFakeRow( [
'wl_notificationtimestamp' =>
'20151212010101' ] )
2736 $mockDb->expects( $this->once() )
2737 ->method(
'selectFieldValues' )
2739 $this->returnValue( [
'2',
'3' ] )
2741 $mockDb->expects( $this->once() )
2742 ->method(
'update' );
2745 $mockCache->expects( $this->once() )
2747 ->with(
'0:SomeDbKey:1', $this->isType(
'object' ) );
2748 $mockCache->expects( $this->once() )
2750 ->with(
'0:SomeDbKey:1' );
2751 $mockCache->expects( $this->once() )
2752 ->method(
'delete' )
2753 ->with(
'0:SomeDbKey:1' );
2762 $store->getWatchedItem(
$user, $titleValue );
2764 $store->updateNotificationTimestamp(