3 use MediaWiki\User\UserIdentity
;
4 use MediaWiki\MediaWikiServices
;
5 use Wikimedia\TestingAccessWrapper
;
9 * @covers ActorMigration
11 class ActorMigrationTest
extends MediaWikiLangTestCase
{
13 protected $tablesUsed = [
15 'revision_actor_temp',
22 * Create an ActorMigration for a particular stage
24 * @return ActorMigration
26 protected function makeMigration( $stage ) {
27 return new ActorMigration( $stage );
31 * @dataProvider provideConstructor
33 * @param string|null $exceptionMsg
35 public function testConstructor( $stage, $exceptionMsg ) {
37 $m = new ActorMigration( $stage );
38 if ( $exceptionMsg !== null ) {
39 $this->fail( 'Expected exception not thrown' );
41 $this->assertInstanceOf( ActorMigration
::class, $m );
42 } catch ( InvalidArgumentException
$ex ) {
43 $this->assertSame( $exceptionMsg, $ex->getMessage() );
47 public static function provideConstructor() {
49 [ 0, '$stage must include a write mode' ],
50 [ SCHEMA_COMPAT_READ_OLD
, '$stage must include a write mode' ],
51 [ SCHEMA_COMPAT_READ_NEW
, '$stage must include a write mode' ],
52 [ SCHEMA_COMPAT_READ_BOTH
, '$stage must include a write mode' ],
54 [ SCHEMA_COMPAT_WRITE_OLD
, '$stage must include a read mode' ],
55 [ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_OLD
, null ],
57 SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_NEW
,
58 'Cannot read the new schema without also writing it'
60 [ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_BOTH
, 'Cannot read both schemas' ],
62 [ SCHEMA_COMPAT_WRITE_NEW
, '$stage must include a read mode' ],
64 SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_OLD
,
65 'Cannot read the old schema without also writing it'
67 [ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_NEW
, null ],
68 [ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_BOTH
, 'Cannot read both schemas' ],
70 [ SCHEMA_COMPAT_WRITE_BOTH
, '$stage must include a read mode' ],
71 [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, null ],
72 [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, null ],
73 [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_BOTH
, 'Cannot read both schemas' ],
78 * @dataProvider provideGetJoin
81 * @param array $expect
83 public function testGetJoin( $stage, $key, $expect ) {
84 $m = $this->makeMigration( $stage );
85 $result = $m->getJoin( $key );
86 $this->assertEquals( $expect, $result );
89 public static function provideGetJoin() {
91 'Simple table, old' => [
92 SCHEMA_COMPAT_OLD
, 'rc_user', [
95 'rc_user' => 'rc_user',
96 'rc_user_text' => 'rc_user_text',
102 'Simple table, read-old' => [
103 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'rc_user', [
106 'rc_user' => 'rc_user',
107 'rc_user_text' => 'rc_user_text',
108 'rc_actor' => 'NULL',
113 'Simple table, read-new' => [
114 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'rc_user', [
115 'tables' => [ 'actor_rc_user' => 'actor' ],
117 'rc_user' => 'actor_rc_user.actor_user',
118 'rc_user_text' => 'actor_rc_user.actor_name',
119 'rc_actor' => 'rc_actor',
122 'actor_rc_user' => [ 'JOIN', 'actor_rc_user.actor_id = rc_actor' ],
126 'Simple table, new' => [
127 SCHEMA_COMPAT_NEW
, 'rc_user', [
128 'tables' => [ 'actor_rc_user' => 'actor' ],
130 'rc_user' => 'actor_rc_user.actor_user',
131 'rc_user_text' => 'actor_rc_user.actor_name',
132 'rc_actor' => 'rc_actor',
135 'actor_rc_user' => [ 'JOIN', 'actor_rc_user.actor_id = rc_actor' ],
141 SCHEMA_COMPAT_OLD
, 'ipb_by', [
144 'ipb_by' => 'ipb_by',
145 'ipb_by_text' => 'ipb_by_text',
146 'ipb_by_actor' => 'NULL',
151 'ipblocks, read-old' => [
152 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'ipb_by', [
155 'ipb_by' => 'ipb_by',
156 'ipb_by_text' => 'ipb_by_text',
157 'ipb_by_actor' => 'NULL',
162 'ipblocks, read-new' => [
163 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'ipb_by', [
164 'tables' => [ 'actor_ipb_by' => 'actor' ],
166 'ipb_by' => 'actor_ipb_by.actor_user',
167 'ipb_by_text' => 'actor_ipb_by.actor_name',
168 'ipb_by_actor' => 'ipb_by_actor',
171 'actor_ipb_by' => [ 'JOIN', 'actor_ipb_by.actor_id = ipb_by_actor' ],
176 SCHEMA_COMPAT_NEW
, 'ipb_by', [
177 'tables' => [ 'actor_ipb_by' => 'actor' ],
179 'ipb_by' => 'actor_ipb_by.actor_user',
180 'ipb_by_text' => 'actor_ipb_by.actor_name',
181 'ipb_by_actor' => 'ipb_by_actor',
184 'actor_ipb_by' => [ 'JOIN', 'actor_ipb_by.actor_id = ipb_by_actor' ],
190 SCHEMA_COMPAT_OLD
, 'rev_user', [
193 'rev_user' => 'rev_user',
194 'rev_user_text' => 'rev_user_text',
195 'rev_actor' => 'NULL',
200 'Revision, read-old' => [
201 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'rev_user', [
204 'rev_user' => 'rev_user',
205 'rev_user_text' => 'rev_user_text',
206 'rev_actor' => 'NULL',
211 'Revision, read-new' => [
212 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'rev_user', [
214 'temp_rev_user' => 'revision_actor_temp',
215 'actor_rev_user' => 'actor',
218 'rev_user' => 'actor_rev_user.actor_user',
219 'rev_user_text' => 'actor_rev_user.actor_name',
220 'rev_actor' => 'temp_rev_user.revactor_actor',
223 'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
224 'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
229 SCHEMA_COMPAT_NEW
, 'rev_user', [
231 'temp_rev_user' => 'revision_actor_temp',
232 'actor_rev_user' => 'actor',
235 'rev_user' => 'actor_rev_user.actor_user',
236 'rev_user_text' => 'actor_rev_user.actor_name',
237 'rev_actor' => 'temp_rev_user.revactor_actor',
240 'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
241 'actor_rev_user' => [ 'JOIN', 'actor_rev_user.actor_id = temp_rev_user.revactor_actor' ],
249 * @dataProvider provideGetWhere
252 * @param UserIdentity[] $users
254 * @param array $expect
256 public function testGetWhere( $stage, $key, $users, $useId, $expect ) {
257 $expect['conds'] = '(' . implode( ') OR (', $expect['orconds'] ) . ')';
259 if ( count( $users ) === 1 ) {
260 $users = reset( $users );
263 $m = $this->makeMigration( $stage );
264 $result = $m->getWhere( $this->db
, $key, $users, $useId );
265 $this->assertEquals( $expect, $result );
268 public function provideGetWhere() {
269 $makeUserIdentity = function ( $id, $name, $actor ) {
270 $u = $this->getMock( UserIdentity
::class );
271 $u->method( 'getId' )->willReturn( $id );
272 $u->method( 'getName' )->willReturn( $name );
273 $u->method( 'getActorId' )->willReturn( $actor );
277 $genericUser = [ $makeUserIdentity( 1, 'User1', 11 ) ];
278 $complicatedUsers = [
279 $makeUserIdentity( 1, 'User1', 11 ),
280 $makeUserIdentity( 2, 'User2', 12 ),
281 $makeUserIdentity( 3, 'User3', 0 ),
282 $makeUserIdentity( 0, '192.168.12.34', 34 ),
283 $makeUserIdentity( 0, '192.168.12.35', 0 ),
287 'Simple table, old' => [
288 SCHEMA_COMPAT_OLD
, 'rc_user', $genericUser, true, [
290 'orconds' => [ 'userid' => "rc_user = '1'" ],
294 'Simple table, read-old' => [
295 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'rc_user', $genericUser, true, [
297 'orconds' => [ 'userid' => "rc_user = '1'" ],
301 'Simple table, read-new' => [
302 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'rc_user', $genericUser, true, [
304 'orconds' => [ 'actor' => "rc_actor = '11'" ],
308 'Simple table, new' => [
309 SCHEMA_COMPAT_NEW
, 'rc_user', $genericUser, true, [
311 'orconds' => [ 'actor' => "rc_actor = '11'" ],
317 SCHEMA_COMPAT_OLD
, 'ipb_by', $genericUser, true, [
319 'orconds' => [ 'userid' => "ipb_by = '1'" ],
323 'ipblocks, read-old' => [
324 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'ipb_by', $genericUser, true, [
326 'orconds' => [ 'userid' => "ipb_by = '1'" ],
330 'ipblocks, read-new' => [
331 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'ipb_by', $genericUser, true, [
333 'orconds' => [ 'actor' => "ipb_by_actor = '11'" ],
338 SCHEMA_COMPAT_NEW
, 'ipb_by', $genericUser, true, [
340 'orconds' => [ 'actor' => "ipb_by_actor = '11'" ],
346 SCHEMA_COMPAT_OLD
, 'rev_user', $genericUser, true, [
348 'orconds' => [ 'userid' => "rev_user = '1'" ],
352 'Revision, read-old' => [
353 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'rev_user', $genericUser, true, [
355 'orconds' => [ 'userid' => "rev_user = '1'" ],
359 'Revision, read-new' => [
360 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'rev_user', $genericUser, true, [
362 'temp_rev_user' => 'revision_actor_temp',
364 'orconds' => [ 'actor' => "temp_rev_user.revactor_actor = '11'" ],
366 'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
371 SCHEMA_COMPAT_NEW
, 'rev_user', $genericUser, true, [
373 'temp_rev_user' => 'revision_actor_temp',
375 'orconds' => [ 'actor' => "temp_rev_user.revactor_actor = '11'" ],
377 'temp_rev_user' => [ 'JOIN', 'temp_rev_user.revactor_rev = rev_id' ],
382 'Multiple users, old' => [
383 SCHEMA_COMPAT_OLD
, 'rc_user', $complicatedUsers, true, [
386 'userid' => "rc_user IN ('1','2','3') ",
387 'username' => "rc_user_text IN ('192.168.12.34','192.168.12.35') "
392 'Multiple users, read-old' => [
393 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'rc_user', $complicatedUsers, true, [
396 'userid' => "rc_user IN ('1','2','3') ",
397 'username' => "rc_user_text IN ('192.168.12.34','192.168.12.35') "
402 'Multiple users, read-new' => [
403 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'rc_user', $complicatedUsers, true, [
405 'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
409 'Multiple users, new' => [
410 SCHEMA_COMPAT_NEW
, 'rc_user', $complicatedUsers, true, [
412 'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
417 'Multiple users, no use ID, old' => [
418 SCHEMA_COMPAT_OLD
, 'rc_user', $complicatedUsers, false, [
421 'username' => "rc_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
426 'Multiple users, read-old' => [
427 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'rc_user', $complicatedUsers, false, [
430 'username' => "rc_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
435 'Multiple users, read-new' => [
436 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'rc_user', $complicatedUsers, false, [
438 'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
442 'Multiple users, new' => [
443 SCHEMA_COMPAT_NEW
, 'rc_user', $complicatedUsers, false, [
445 'orconds' => [ 'actor' => "rc_actor IN ('11','12','34') " ],
453 * @dataProvider provideInsertRoundTrip
454 * @param string $table
457 * @param array $extraFields
459 public function testInsertRoundTrip( $table, $key, $pk, $extraFields ) {
460 $u = $this->getTestUser()->getUser();
461 $user = $this->getMock( UserIdentity
::class );
462 $user->method( 'getId' )->willReturn( $u->getId() );
463 $user->method( 'getName' )->willReturn( $u->getName() );
464 if ( $u->getActorId( $this->db
) ) {
465 $user->method( 'getActorId' )->willReturn( $u->getActorId() );
469 [ 'actor_user' => $u->getId(), 'actor_name' => $u->getName() ],
472 $user->method( 'getActorId' )->willReturn( $this->db
->insertId() );
476 SCHEMA_COMPAT_OLD
=> 'old',
477 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
=> 'write-both-read-old',
478 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
=> 'write-both-read-new',
479 SCHEMA_COMPAT_NEW
=> 'new',
483 SCHEMA_COMPAT_OLD
=> [
485 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
,
487 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
=> [
489 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
,
490 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
,
493 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
=> [
495 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
,
496 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
,
499 SCHEMA_COMPAT_NEW
=> [
500 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
,
505 $nameKey = $key . '_text';
506 $actorKey = $key === 'ipb_by' ?
'ipb_by_actor' : substr( $key, 0, -5 ) . '_actor';
508 foreach ( $stages as $writeStage => $possibleReadStages ) {
509 if ( $key === 'ipb_by' ) {
510 $extraFields['ipb_address'] = __CLASS__
. "#{$stageNames[$writeStage]}";
513 $w = $this->makeMigration( $writeStage );
514 $usesTemp = $key === 'rev_user';
517 list( $fields, $callback ) = $w->getInsertValuesWithTempTable( $this->db
, $key, $user );
519 $fields = $w->getInsertValues( $this->db
, $key, $user );
522 if ( $writeStage & SCHEMA_COMPAT_WRITE_OLD
) {
523 $this->assertSame( $user->getId(), $fields[$key],
524 "old field, stage={$stageNames[$writeStage]}" );
525 $this->assertSame( $user->getName(), $fields[$nameKey],
526 "old field, stage={$stageNames[$writeStage]}" );
528 $this->assertArrayNotHasKey( $key, $fields, "old field, stage={$stageNames[$writeStage]}" );
529 $this->assertArrayNotHasKey( $nameKey, $fields, "old field, stage={$stageNames[$writeStage]}" );
531 if ( ( $writeStage & SCHEMA_COMPAT_WRITE_NEW
) && !$usesTemp ) {
532 $this->assertSame( $user->getActorId(), $fields[$actorKey],
533 "new field, stage={$stageNames[$writeStage]}" );
535 $this->assertArrayNotHasKey( $actorKey, $fields,
536 "new field, stage={$stageNames[$writeStage]}" );
539 $this->db
->insert( $table, $extraFields +
$fields, __METHOD__
);
540 $id = $this->db
->insertId();
542 $callback( $id, $extraFields );
545 foreach ( $possibleReadStages as $readStage ) {
546 $r = $this->makeMigration( $readStage );
548 $queryInfo = $r->getJoin( $key );
549 $row = $this->db
->selectRow(
550 [ $table ] +
$queryInfo['tables'],
551 $queryInfo['fields'],
558 $this->assertSame( $user->getId(), (int)$row->$key,
559 "w={$stageNames[$writeStage]}, r={$stageNames[$readStage]}, id" );
560 $this->assertSame( $user->getName(), $row->$nameKey,
561 "w={$stageNames[$writeStage]}, r={$stageNames[$readStage]}, name" );
563 ( $readStage & SCHEMA_COMPAT_READ_OLD
) ?
0 : $user->getActorId(),
564 (int)$row->$actorKey,
565 "w={$stageNames[$writeStage]}, r={$stageNames[$readStage]}, actor"
571 public static function provideInsertRoundTrip() {
572 $db = wfGetDB( DB_REPLICA
); // for timestamps
574 $comment = MediaWikiServices
::getInstance()->getCommentStore()
575 ->createComment( wfGetDB( DB_MASTER
), '' );
578 'recentchanges' => [ 'recentchanges', 'rc_user', 'rc_id', [
579 'rc_timestamp' => $db->timestamp(),
581 'rc_title' => 'Test',
582 'rc_this_oldid' => 42,
583 'rc_last_oldid' => 41,
584 'rc_source' => 'test',
585 'rc_comment_id' => $comment->id
,
587 'ipblocks' => [ 'ipblocks', 'ipb_by', 'ipb_id', [
588 'ipb_range_start' => '',
589 'ipb_range_end' => '',
590 'ipb_timestamp' => $db->timestamp(),
591 'ipb_expiry' => $db->getInfinity(),
592 'ipb_reason_id' => $comment->id
,
594 'revision' => [ 'revision', 'rev_user', 'rev_id', [
597 'rev_timestamp' => $db->timestamp(),
602 public static function provideStages() {
604 'old' => [ SCHEMA_COMPAT_OLD
],
605 'read-old' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
],
606 'read-new' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
],
607 'new' => [ SCHEMA_COMPAT_NEW
],
612 * @dataProvider provideStages
614 * @expectedException InvalidArgumentException
615 * @expectedExceptionMessage Must use getInsertValuesWithTempTable() for rev_user
617 public function testInsertWrong( $stage ) {
618 $m = $this->makeMigration( $stage );
619 $m->getInsertValues( $this->db
, 'rev_user', $this->getTestUser()->getUser() );
623 * @dataProvider provideStages
625 * @expectedException InvalidArgumentException
626 * @expectedExceptionMessage Must use getInsertValues() for rc_user
628 public function testInsertWithTempTableWrong( $stage ) {
629 $m = $this->makeMigration( $stage );
630 $m->getInsertValuesWithTempTable( $this->db
, 'rc_user', $this->getTestUser()->getUser() );
634 * @dataProvider provideStages
637 public function testInsertWithTempTableDeprecated( $stage ) {
638 $wrap = TestingAccessWrapper
::newFromClass( ActorMigration
::class );
639 $wrap->formerTempTables +
= [ 'rc_user' => '1.30' ];
641 $this->hideDeprecated( 'ActorMigration::getInsertValuesWithTempTable for rc_user' );
642 $m = $this->makeMigration( $stage );
643 list( $fields, $callback )
644 = $m->getInsertValuesWithTempTable( $this->db
, 'rc_user', $this->getTestUser()->getUser() );
645 $this->assertTrue( is_callable( $callback ) );
649 * @dataProvider provideStages
651 * @expectedException InvalidArgumentException
652 * @expectedExceptionMessage $extra[rev_timestamp] is not provided
654 public function testInsertWithTempTableCallbackMissingFields( $stage ) {
655 $m = $this->makeMigration( $stage );
656 list( $fields, $callback )
657 = $m->getInsertValuesWithTempTable( $this->db
, 'rev_user', $this->getTestUser()->getUser() );
662 * @dataProvider provideStages
665 public function testInsertUserIdentity( $stage ) {
666 $this->setMwGlobals( [
667 // for User::getActorId()
668 'wgActorTableSchemaMigrationStage' => $stage
670 $this->overrideMwServices();
672 $user = $this->getMutableTestUser()->getUser();
673 $userIdentity = $this->getMock( UserIdentity
::class );
674 $userIdentity->method( 'getId' )->willReturn( $user->getId() );
675 $userIdentity->method( 'getName' )->willReturn( $user->getName() );
676 $userIdentity->method( 'getActorId' )->willReturn( 0 );
678 list( $cFields, $cCallback ) = MediaWikiServices
::getInstance()->getCommentStore()
679 ->insertWithTempTable( $this->db
, 'rev_comment', '' );
680 $m = $this->makeMigration( $stage );
681 list( $fields, $callback ) =
682 $m->getInsertValuesWithTempTable( $this->db
, 'rev_user', $userIdentity );
686 'rev_timestamp' => $this->db
->timestamp(),
688 $this->db
->insert( 'revision', $extraFields +
$fields, __METHOD__
);
689 $id = $this->db
->insertId();
690 $callback( $id, $extraFields );
693 $qi = $m->getJoin( 'rev_user' );
694 $row = $this->db
->selectRow(
695 [ 'revision' ] +
$qi['tables'], $qi['fields'], [ 'rev_id' => $id ], __METHOD__
, [], $qi['joins']
697 $this->assertSame( $user->getId(), (int)$row->rev_user
);
698 $this->assertSame( $user->getName(), $row->rev_user_text
);
700 ( $stage & SCHEMA_COMPAT_READ_NEW
) ?
$user->getActorId() : 0,
704 $m = $this->makeMigration( $stage );
705 $fields = $m->getInsertValues( $this->db
, 'dummy_user', $userIdentity );
706 if ( $stage & SCHEMA_COMPAT_WRITE_OLD
) {
707 $this->assertSame( $user->getId(), $fields['dummy_user'] );
708 $this->assertSame( $user->getName(), $fields['dummy_user_text'] );
710 $this->assertArrayNotHasKey( 'dummy_user', $fields );
711 $this->assertArrayNotHasKey( 'dummy_user_text', $fields );
713 if ( $stage & SCHEMA_COMPAT_WRITE_NEW
) {
714 $this->assertSame( $user->getActorId(), $fields['dummy_actor'] );
716 $this->assertArrayNotHasKey( 'dummy_actor', $fields );
720 public function testNewMigration() {
721 $m = ActorMigration
::newMigration();
722 $this->assertInstanceOf( ActorMigration
::class, $m );
723 $this->assertSame( $m, ActorMigration
::newMigration() );
727 * @dataProvider provideIsAnon
729 * @param string $isAnon
730 * @param string $isNotAnon
732 public function testIsAnon( $stage, $isAnon, $isNotAnon ) {
733 $m = $this->makeMigration( $stage );
734 $this->assertSame( $isAnon, $m->isAnon( 'foo' ) );
735 $this->assertSame( $isNotAnon, $m->isNotAnon( 'foo' ) );
738 public static function provideIsAnon() {
740 'old' => [ SCHEMA_COMPAT_OLD
, 'foo = 0', 'foo != 0' ],
741 'read-old' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD
, 'foo = 0', 'foo != 0' ],
743 SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW
, 'foo IS NULL', 'foo IS NOT NULL'
745 'new' => [ SCHEMA_COMPAT_NEW
, 'foo IS NULL', 'foo IS NOT NULL' ],