2017-09-12 17:12:29 +00:00
|
|
|
<?php
|
|
|
|
|
|
2020-10-11 21:55:12 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2017-09-12 17:12:29 +00:00
|
|
|
use MediaWiki\User\UserIdentity;
|
2019-07-23 17:40:52 +00:00
|
|
|
use Wikimedia\ScopedCallback;
|
2017-09-12 17:12:29 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @group Database
|
|
|
|
|
* @covers ActorMigration
|
|
|
|
|
*/
|
|
|
|
|
class ActorMigrationTest extends MediaWikiLangTestCase {
|
|
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
protected $resetActorMigration = null;
|
|
|
|
|
protected static $amId = 0;
|
|
|
|
|
|
2017-09-12 17:12:29 +00:00
|
|
|
protected $tablesUsed = [
|
|
|
|
|
'actor',
|
|
|
|
|
];
|
|
|
|
|
|
2019-10-20 18:11:08 +00:00
|
|
|
protected function setUp() : void {
|
2019-07-23 17:40:52 +00:00
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
|
|
$w = TestingAccessWrapper::newFromClass( ActorMigration::class );
|
|
|
|
|
$data = [
|
|
|
|
|
'tempTables' => $w->tempTables,
|
|
|
|
|
'formerTempTables' => $w->formerTempTables,
|
|
|
|
|
'deprecated' => $w->deprecated,
|
|
|
|
|
'removed' => $w->removed,
|
|
|
|
|
'specialFields' => $w->specialFields,
|
|
|
|
|
];
|
|
|
|
|
$this->resetActorMigration = new ScopedCallback( function ( $w, $data ) {
|
|
|
|
|
foreach ( $data as $k => $v ) {
|
|
|
|
|
$w->$k = $v;
|
|
|
|
|
}
|
|
|
|
|
}, [ $w, $data ] );
|
|
|
|
|
|
|
|
|
|
$w->tempTables = [
|
|
|
|
|
'am2_user' => [
|
|
|
|
|
'table' => 'actormigration2_temp',
|
|
|
|
|
'pk' => 'am2t_id',
|
|
|
|
|
'field' => 'am2t_actor',
|
|
|
|
|
'joinPK' => 'am2_id',
|
|
|
|
|
'extra' => [],
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
$w->specialFields = [
|
|
|
|
|
'am3_xxx' => [ 'am3_xxx_text', 'am3_xxx_actor' ],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-20 18:11:08 +00:00
|
|
|
protected function tearDown() : void {
|
2019-07-23 17:40:52 +00:00
|
|
|
parent::tearDown();
|
|
|
|
|
ScopedCallback::consume( $this->resetActorMigration );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected function getSchemaOverrides( IMaintainableDatabase $db ) {
|
|
|
|
|
return [
|
|
|
|
|
'scripts' => [
|
|
|
|
|
__DIR__ . '/ActorMigrationTest.sql',
|
|
|
|
|
],
|
|
|
|
|
'drop' => [],
|
|
|
|
|
'create' => [ 'actormigration1', 'actormigration2', 'actormigration2_temp', 'actormigration3' ],
|
|
|
|
|
'alter' => [],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-11 21:55:12 +00:00
|
|
|
private function getMigration( $stage ) {
|
|
|
|
|
return new ActorMigration( $stage, MediaWikiServices::getInstance()->getUserNameUtils() );
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-18 18:21:20 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideConstructor
|
|
|
|
|
* @param int $stage
|
|
|
|
|
* @param string|null $exceptionMsg
|
|
|
|
|
*/
|
|
|
|
|
public function testConstructor( $stage, $exceptionMsg ) {
|
|
|
|
|
try {
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2018-09-18 18:21:20 +00:00
|
|
|
if ( $exceptionMsg !== null ) {
|
|
|
|
|
$this->fail( 'Expected exception not thrown' );
|
|
|
|
|
}
|
|
|
|
|
$this->assertInstanceOf( ActorMigration::class, $m );
|
|
|
|
|
} catch ( InvalidArgumentException $ex ) {
|
|
|
|
|
$this->assertSame( $exceptionMsg, $ex->getMessage() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideConstructor() {
|
|
|
|
|
return [
|
|
|
|
|
[ 0, '$stage must include a write mode' ],
|
|
|
|
|
[ SCHEMA_COMPAT_READ_OLD, '$stage must include a write mode' ],
|
|
|
|
|
[ SCHEMA_COMPAT_READ_NEW, '$stage must include a write mode' ],
|
|
|
|
|
[ SCHEMA_COMPAT_READ_BOTH, '$stage must include a write mode' ],
|
|
|
|
|
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_OLD, '$stage must include a read mode' ],
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_OLD, null ],
|
|
|
|
|
[
|
|
|
|
|
SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_NEW,
|
|
|
|
|
'Cannot read the new schema without also writing it'
|
|
|
|
|
],
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_OLD | SCHEMA_COMPAT_READ_BOTH, 'Cannot read both schemas' ],
|
|
|
|
|
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_NEW, '$stage must include a read mode' ],
|
|
|
|
|
[
|
|
|
|
|
SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_OLD,
|
|
|
|
|
'Cannot read the old schema without also writing it'
|
|
|
|
|
],
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_NEW, null ],
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_NEW | SCHEMA_COMPAT_READ_BOTH, 'Cannot read both schemas' ],
|
|
|
|
|
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_BOTH, '$stage must include a read mode' ],
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, null ],
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, null ],
|
|
|
|
|
[ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_BOTH, 'Cannot read both schemas' ],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 17:12:29 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideGetJoin
|
|
|
|
|
* @param int $stage
|
|
|
|
|
* @param string $key
|
|
|
|
|
* @param array $expect
|
|
|
|
|
*/
|
|
|
|
|
public function testGetJoin( $stage, $key, $expect ) {
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2017-09-12 17:12:29 +00:00
|
|
|
$result = $m->getJoin( $key );
|
|
|
|
|
$this->assertEquals( $expect, $result );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideGetJoin() {
|
|
|
|
|
return [
|
|
|
|
|
'Simple table, old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_OLD, 'am1_user', [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
|
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am1_user' => 'am1_user',
|
|
|
|
|
'am1_user_text' => 'am1_user_text',
|
|
|
|
|
'am1_actor' => 'NULL',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Simple table, read-old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', [
|
2018-09-18 18:21:20 +00:00
|
|
|
'tables' => [],
|
2017-09-12 17:12:29 +00:00
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am1_user' => 'am1_user',
|
|
|
|
|
'am1_user_text' => 'am1_user_text',
|
|
|
|
|
'am1_actor' => 'NULL',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'joins' => [],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Simple table, read-new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', [
|
|
|
|
|
'tables' => [ 'actor_am1_user' => 'actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am1_user' => 'actor_am1_user.actor_user',
|
|
|
|
|
'am1_user_text' => 'actor_am1_user.actor_name',
|
|
|
|
|
'am1_actor' => 'am1_actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'actor_am1_user' => [ 'JOIN', 'actor_am1_user.actor_id = am1_actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'Simple table, new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_NEW, 'am1_user', [
|
|
|
|
|
'tables' => [ 'actor_am1_user' => 'actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am1_user' => 'actor_am1_user.actor_user',
|
|
|
|
|
'am1_user_text' => 'actor_am1_user.actor_name',
|
|
|
|
|
'am1_actor' => 'am1_actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'actor_am1_user' => [ 'JOIN', 'actor_am1_user.actor_id = am1_actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, old' => [
|
|
|
|
|
SCHEMA_COMPAT_OLD, 'am3_xxx', [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
|
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am3_xxx' => 'am3_xxx',
|
|
|
|
|
'am3_xxx_text' => 'am3_xxx_text',
|
|
|
|
|
'am3_xxx_actor' => 'NULL',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, read-old' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am3_xxx', [
|
2018-09-18 18:21:20 +00:00
|
|
|
'tables' => [],
|
2017-09-12 17:12:29 +00:00
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am3_xxx' => 'am3_xxx',
|
|
|
|
|
'am3_xxx_text' => 'am3_xxx_text',
|
|
|
|
|
'am3_xxx_actor' => 'NULL',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'joins' => [],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, read-new' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am3_xxx', [
|
|
|
|
|
'tables' => [ 'actor_am3_xxx' => 'actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am3_xxx' => 'actor_am3_xxx.actor_user',
|
|
|
|
|
'am3_xxx_text' => 'actor_am3_xxx.actor_name',
|
|
|
|
|
'am3_xxx_actor' => 'am3_xxx_actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'actor_am3_xxx' => [ 'JOIN', 'actor_am3_xxx.actor_id = am3_xxx_actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, new' => [
|
|
|
|
|
SCHEMA_COMPAT_NEW, 'am3_xxx', [
|
|
|
|
|
'tables' => [ 'actor_am3_xxx' => 'actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am3_xxx' => 'actor_am3_xxx.actor_user',
|
|
|
|
|
'am3_xxx_text' => 'actor_am3_xxx.actor_name',
|
|
|
|
|
'am3_xxx_actor' => 'am3_xxx_actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'actor_am3_xxx' => [ 'JOIN', 'actor_am3_xxx.actor_id = am3_xxx_actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, old' => [
|
|
|
|
|
SCHEMA_COMPAT_OLD, 'am2_user', [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
|
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am2_user' => 'am2_user',
|
|
|
|
|
'am2_user_text' => 'am2_user_text',
|
|
|
|
|
'am2_actor' => 'NULL',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, read-old' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am2_user', [
|
2018-09-18 18:21:20 +00:00
|
|
|
'tables' => [],
|
2017-09-12 17:12:29 +00:00
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am2_user' => 'am2_user',
|
|
|
|
|
'am2_user_text' => 'am2_user_text',
|
|
|
|
|
'am2_actor' => 'NULL',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'joins' => [],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, read-new' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am2_user', [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => 'actormigration2_temp',
|
|
|
|
|
'actor_am2_user' => 'actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am2_user' => 'actor_am2_user.actor_user',
|
|
|
|
|
'am2_user_text' => 'actor_am2_user.actor_name',
|
|
|
|
|
'am2_actor' => 'temp_am2_user.am2t_actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
|
|
|
|
|
'actor_am2_user' => [ 'JOIN', 'actor_am2_user.actor_id = temp_am2_user.am2t_actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, new' => [
|
|
|
|
|
SCHEMA_COMPAT_NEW, 'am2_user', [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => 'actormigration2_temp',
|
|
|
|
|
'actor_am2_user' => 'actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'fields' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'am2_user' => 'actor_am2_user.actor_user',
|
|
|
|
|
'am2_user_text' => 'actor_am2_user.actor_name',
|
|
|
|
|
'am2_actor' => 'temp_am2_user.am2t_actor',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
|
|
|
|
|
'actor_am2_user' => [ 'JOIN', 'actor_am2_user.actor_id = temp_am2_user.am2t_actor' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideGetWhere
|
|
|
|
|
* @param int $stage
|
|
|
|
|
* @param string $key
|
2019-12-04 14:33:08 +00:00
|
|
|
* @param UserIdentity|UserIdentity[]|null|false $users
|
2017-09-12 17:12:29 +00:00
|
|
|
* @param bool $useId
|
|
|
|
|
* @param array $expect
|
|
|
|
|
*/
|
|
|
|
|
public function testGetWhere( $stage, $key, $users, $useId, $expect ) {
|
2019-12-04 14:33:08 +00:00
|
|
|
if ( !isset( $expect['conds'] ) ) {
|
|
|
|
|
$expect['conds'] = '(' . implode( ') OR (', $expect['orconds'] ) . ')';
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2017-09-12 17:12:29 +00:00
|
|
|
$result = $m->getWhere( $this->db, $key, $users, $useId );
|
|
|
|
|
$this->assertEquals( $expect, $result );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function provideGetWhere() {
|
|
|
|
|
$makeUserIdentity = function ( $id, $name, $actor ) {
|
2019-10-05 22:14:35 +00:00
|
|
|
$u = $this->createMock( UserIdentity::class );
|
2017-09-12 17:12:29 +00:00
|
|
|
$u->method( 'getId' )->willReturn( $id );
|
|
|
|
|
$u->method( 'getName' )->willReturn( $name );
|
|
|
|
|
$u->method( 'getActorId' )->willReturn( $actor );
|
|
|
|
|
return $u;
|
|
|
|
|
};
|
|
|
|
|
|
2019-12-04 14:33:08 +00:00
|
|
|
$genericUser = $makeUserIdentity( 1, 'User1', 11 );
|
2017-09-12 17:12:29 +00:00
|
|
|
$complicatedUsers = [
|
|
|
|
|
$makeUserIdentity( 1, 'User1', 11 ),
|
|
|
|
|
$makeUserIdentity( 2, 'User2', 12 ),
|
|
|
|
|
$makeUserIdentity( 3, 'User3', 0 ),
|
|
|
|
|
$makeUserIdentity( 0, '192.168.12.34', 34 ),
|
|
|
|
|
$makeUserIdentity( 0, '192.168.12.35', 0 ),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'Simple table, old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_OLD, 'am1_user', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'userid' => "am1_user = 1" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Simple table, read-old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'userid' => "am1_user = 1" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Simple table, read-new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am1_actor = 11" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'Simple table, new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_NEW, 'am1_user', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am1_actor = 11" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, old' => [
|
|
|
|
|
SCHEMA_COMPAT_OLD, 'am3_xxx', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'userid' => "am3_xxx = 1" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, read-old' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am3_xxx', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'userid' => "am3_xxx = 1" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, read-new' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am3_xxx', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am3_xxx_actor = 11" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Special name, new' => [
|
|
|
|
|
SCHEMA_COMPAT_NEW, 'am3_xxx', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am3_xxx_actor = 11" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, old' => [
|
|
|
|
|
SCHEMA_COMPAT_OLD, 'am2_user', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'userid' => "am2_user = 1" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, read-old' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am2_user', $genericUser, true, [
|
2018-09-18 18:21:20 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'userid' => "am2_user = 1" ],
|
2018-09-18 18:21:20 +00:00
|
|
|
'joins' => [],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, read-new' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am2_user', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => 'actormigration2_temp',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "temp_am2_user.am2t_actor = 11" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-07-23 17:40:52 +00:00
|
|
|
'Temp table, new' => [
|
|
|
|
|
SCHEMA_COMPAT_NEW, 'am2_user', $genericUser, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => 'actormigration2_temp',
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "temp_am2_user.am2t_actor = 11" ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'temp_am2_user' => [ 'JOIN', 'temp_am2_user.am2t_id = am2_id' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
'Multiple users, old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_OLD, 'am1_user', $complicatedUsers, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
|
|
|
|
'orconds' => [
|
2019-11-15 05:35:33 +00:00
|
|
|
'userid' => "am1_user IN (1,2,3) ",
|
2019-07-23 17:40:52 +00:00
|
|
|
'username' => "am1_user_text IN ('192.168.12.34','192.168.12.35') "
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Multiple users, read-old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', $complicatedUsers, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
|
|
|
|
'orconds' => [
|
2019-11-15 05:35:33 +00:00
|
|
|
'userid' => "am1_user IN (1,2,3) ",
|
2019-07-23 17:40:52 +00:00
|
|
|
'username' => "am1_user_text IN ('192.168.12.34','192.168.12.35') "
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Multiple users, read-new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', $complicatedUsers, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am1_actor IN (11,12,34) " ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'Multiple users, new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_NEW, 'am1_user', $complicatedUsers, true, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am1_actor IN (11,12,34) " ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
'Multiple users, no use ID, old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_OLD, 'am1_user', $complicatedUsers, false, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
|
|
|
|
'orconds' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'username' => "am1_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Multiple users, read-old' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'am1_user', $complicatedUsers, false, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
|
|
|
|
'orconds' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
'username' => "am1_user_text IN ('User1','User2','User3','192.168.12.34','192.168.12.35') "
|
2017-09-12 17:12:29 +00:00
|
|
|
],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2018-09-18 18:21:20 +00:00
|
|
|
'Multiple users, read-new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'am1_user', $complicatedUsers, false, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am1_actor IN (11,12,34) " ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'Multiple users, new' => [
|
2019-07-23 17:40:52 +00:00
|
|
|
SCHEMA_COMPAT_NEW, 'am1_user', $complicatedUsers, false, [
|
2017-09-12 17:12:29 +00:00
|
|
|
'tables' => [],
|
2019-11-15 05:35:33 +00:00
|
|
|
'orconds' => [ 'actor' => "am1_actor IN (11,12,34) " ],
|
2017-09-12 17:12:29 +00:00
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2019-12-04 14:33:08 +00:00
|
|
|
|
|
|
|
|
'Empty $users' => [
|
|
|
|
|
SCHEMA_COMPAT_NEW, 'am1_user', [], true, [
|
|
|
|
|
'tables' => [],
|
|
|
|
|
'conds' => '1=0',
|
|
|
|
|
'orconds' => [],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'Null $users' => [
|
|
|
|
|
SCHEMA_COMPAT_NEW, 'am1_user', null, true, [
|
|
|
|
|
'tables' => [],
|
|
|
|
|
'conds' => '1=0',
|
|
|
|
|
'orconds' => [],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
'False $users' => [
|
|
|
|
|
SCHEMA_COMPAT_NEW, 'am1_user', false, true, [
|
|
|
|
|
'tables' => [],
|
|
|
|
|
'conds' => '1=0',
|
|
|
|
|
'orconds' => [],
|
|
|
|
|
'joins' => [],
|
|
|
|
|
],
|
|
|
|
|
],
|
2017-09-12 17:12:29 +00:00
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-04 14:33:08 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideStages
|
|
|
|
|
*/
|
|
|
|
|
public function testGetWhere_exception( $stage ) {
|
|
|
|
|
$this->expectException( InvalidArgumentException::class );
|
|
|
|
|
$this->expectExceptionMessage(
|
|
|
|
|
'ActorMigration::getWhere: Value for $users must be a UserIdentity or array, got string'
|
|
|
|
|
);
|
|
|
|
|
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2019-12-04 14:33:08 +00:00
|
|
|
$result = $m->getWhere( $this->db, 'am1_user', 'Foo' );
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 17:12:29 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideInsertRoundTrip
|
|
|
|
|
* @param string $table
|
|
|
|
|
* @param string $key
|
|
|
|
|
* @param string $pk
|
2019-07-23 17:40:52 +00:00
|
|
|
* @param bool $usesTemp
|
2017-09-12 17:12:29 +00:00
|
|
|
*/
|
2019-07-23 17:40:52 +00:00
|
|
|
public function testInsertRoundTrip( $table, $key, $pk, $usesTemp ) {
|
2017-09-12 17:12:29 +00:00
|
|
|
$u = $this->getTestUser()->getUser();
|
2019-10-05 22:14:35 +00:00
|
|
|
$user = $this->createMock( UserIdentity::class );
|
2017-09-12 17:12:29 +00:00
|
|
|
$user->method( 'getId' )->willReturn( $u->getId() );
|
|
|
|
|
$user->method( 'getName' )->willReturn( $u->getName() );
|
2019-07-23 17:40:52 +00:00
|
|
|
$user->method( 'getActorId' )->willReturn( $u->getActorId( $this->db ) );
|
2017-09-12 17:12:29 +00:00
|
|
|
|
2018-09-18 18:21:20 +00:00
|
|
|
$stageNames = [
|
|
|
|
|
SCHEMA_COMPAT_OLD => 'old',
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD => 'write-both-read-old',
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW => 'write-both-read-new',
|
|
|
|
|
SCHEMA_COMPAT_NEW => 'new',
|
|
|
|
|
];
|
|
|
|
|
|
2017-09-12 17:12:29 +00:00
|
|
|
$stages = [
|
2018-09-18 18:21:20 +00:00
|
|
|
SCHEMA_COMPAT_OLD => [
|
|
|
|
|
SCHEMA_COMPAT_OLD,
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
|
|
|
|
|
],
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD => [
|
|
|
|
|
SCHEMA_COMPAT_OLD,
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
|
|
|
|
|
SCHEMA_COMPAT_NEW
|
|
|
|
|
],
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW => [
|
|
|
|
|
SCHEMA_COMPAT_OLD,
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD,
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
|
|
|
|
|
SCHEMA_COMPAT_NEW
|
|
|
|
|
],
|
|
|
|
|
SCHEMA_COMPAT_NEW => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW,
|
|
|
|
|
SCHEMA_COMPAT_NEW
|
|
|
|
|
],
|
2017-09-12 17:12:29 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$nameKey = $key . '_text';
|
2019-07-23 17:40:52 +00:00
|
|
|
$actorKey = ( $key === 'am3_xxx' ? $key : substr( $key, 0, -5 ) ) . '_actor';
|
2017-09-12 17:12:29 +00:00
|
|
|
|
2018-06-26 17:26:33 +00:00
|
|
|
foreach ( $stages as $writeStage => $possibleReadStages ) {
|
2020-10-11 21:55:12 +00:00
|
|
|
$w = $this->getMigration( $writeStage );
|
2017-09-12 17:12:29 +00:00
|
|
|
|
|
|
|
|
if ( $usesTemp ) {
|
|
|
|
|
list( $fields, $callback ) = $w->getInsertValuesWithTempTable( $this->db, $key, $user );
|
|
|
|
|
} else {
|
|
|
|
|
$fields = $w->getInsertValues( $this->db, $key, $user );
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-18 18:21:20 +00:00
|
|
|
if ( $writeStage & SCHEMA_COMPAT_WRITE_OLD ) {
|
|
|
|
|
$this->assertSame( $user->getId(), $fields[$key],
|
|
|
|
|
"old field, stage={$stageNames[$writeStage]}" );
|
|
|
|
|
$this->assertSame( $user->getName(), $fields[$nameKey],
|
|
|
|
|
"old field, stage={$stageNames[$writeStage]}" );
|
2017-09-12 17:12:29 +00:00
|
|
|
} else {
|
2018-09-18 18:21:20 +00:00
|
|
|
$this->assertArrayNotHasKey( $key, $fields, "old field, stage={$stageNames[$writeStage]}" );
|
|
|
|
|
$this->assertArrayNotHasKey( $nameKey, $fields, "old field, stage={$stageNames[$writeStage]}" );
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
2018-09-18 18:21:20 +00:00
|
|
|
if ( ( $writeStage & SCHEMA_COMPAT_WRITE_NEW ) && !$usesTemp ) {
|
|
|
|
|
$this->assertSame( $user->getActorId(), $fields[$actorKey],
|
|
|
|
|
"new field, stage={$stageNames[$writeStage]}" );
|
2017-09-12 17:12:29 +00:00
|
|
|
} else {
|
2018-09-18 18:21:20 +00:00
|
|
|
$this->assertArrayNotHasKey( $actorKey, $fields,
|
|
|
|
|
"new field, stage={$stageNames[$writeStage]}" );
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
$id = ++self::$amId;
|
|
|
|
|
$this->db->insert( $table, [ $pk => $id ] + $fields, __METHOD__ );
|
2017-09-12 17:12:29 +00:00
|
|
|
if ( $usesTemp ) {
|
2019-07-23 17:40:52 +00:00
|
|
|
$callback( $id, [] );
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-26 17:26:33 +00:00
|
|
|
foreach ( $possibleReadStages as $readStage ) {
|
2020-10-11 21:55:12 +00:00
|
|
|
$r = $this->getMigration( $readStage );
|
2017-09-12 17:12:29 +00:00
|
|
|
|
|
|
|
|
$queryInfo = $r->getJoin( $key );
|
|
|
|
|
$row = $this->db->selectRow(
|
|
|
|
|
[ $table ] + $queryInfo['tables'],
|
|
|
|
|
$queryInfo['fields'],
|
|
|
|
|
[ $pk => $id ],
|
|
|
|
|
__METHOD__,
|
|
|
|
|
[],
|
|
|
|
|
$queryInfo['joins']
|
|
|
|
|
);
|
|
|
|
|
|
2018-09-18 18:21:20 +00:00
|
|
|
$this->assertSame( $user->getId(), (int)$row->$key,
|
|
|
|
|
"w={$stageNames[$writeStage]}, r={$stageNames[$readStage]}, id" );
|
|
|
|
|
$this->assertSame( $user->getName(), $row->$nameKey,
|
|
|
|
|
"w={$stageNames[$writeStage]}, r={$stageNames[$readStage]}, name" );
|
2017-09-12 17:12:29 +00:00
|
|
|
$this->assertSame(
|
2018-09-18 18:21:20 +00:00
|
|
|
( $readStage & SCHEMA_COMPAT_READ_OLD ) ? 0 : $user->getActorId(),
|
2017-09-12 17:12:29 +00:00
|
|
|
(int)$row->$actorKey,
|
2018-09-18 18:21:20 +00:00
|
|
|
"w={$stageNames[$writeStage]}, r={$stageNames[$readStage]}, actor"
|
2017-09-12 17:12:29 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideInsertRoundTrip() {
|
|
|
|
|
return [
|
2019-07-23 17:40:52 +00:00
|
|
|
'normal' => [ 'actormigration1', 'am1_user', 'am1_id', false ],
|
|
|
|
|
'temp table' => [ 'actormigration2', 'am2_user', 'am2_id', true ],
|
|
|
|
|
'special name' => [ 'actormigration3', 'am3_xxx', 'am3_id', false ],
|
2017-09-12 17:12:29 +00:00
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideStages() {
|
|
|
|
|
return [
|
2018-09-18 18:21:20 +00:00
|
|
|
'old' => [ SCHEMA_COMPAT_OLD ],
|
|
|
|
|
'read-old' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD ],
|
|
|
|
|
'read-new' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW ],
|
|
|
|
|
'new' => [ SCHEMA_COMPAT_NEW ],
|
2017-09-12 17:12:29 +00:00
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideStages
|
|
|
|
|
* @param int $stage
|
|
|
|
|
*/
|
|
|
|
|
public function testInsertWrong( $stage ) {
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2019-10-11 22:22:26 +00:00
|
|
|
$this->expectException( InvalidArgumentException::class );
|
|
|
|
|
$this->expectExceptionMessage( "Must use getInsertValuesWithTempTable() for am2_user" );
|
2019-07-23 17:40:52 +00:00
|
|
|
$m->getInsertValues( $this->db, 'am2_user', $this->getTestUser()->getUser() );
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideStages
|
|
|
|
|
* @param int $stage
|
|
|
|
|
*/
|
|
|
|
|
public function testInsertWithTempTableWrong( $stage ) {
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2019-10-11 22:22:26 +00:00
|
|
|
$this->expectException( InvalidArgumentException::class );
|
|
|
|
|
$this->expectExceptionMessage( "Must use getInsertValues() for am1_user" );
|
2019-07-23 17:40:52 +00:00
|
|
|
$m->getInsertValuesWithTempTable( $this->db, 'am1_user', $this->getTestUser()->getUser() );
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideStages
|
|
|
|
|
* @param int $stage
|
|
|
|
|
*/
|
|
|
|
|
public function testInsertWithTempTableDeprecated( $stage ) {
|
|
|
|
|
$wrap = TestingAccessWrapper::newFromClass( ActorMigration::class );
|
2019-07-23 17:40:52 +00:00
|
|
|
$wrap->formerTempTables += [ 'am1_user' => '1.30' ];
|
2017-09-12 17:12:29 +00:00
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
$this->hideDeprecated( 'ActorMigration::getInsertValuesWithTempTable for am1_user' );
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2017-09-12 17:12:29 +00:00
|
|
|
list( $fields, $callback )
|
2019-07-23 17:40:52 +00:00
|
|
|
= $m->getInsertValuesWithTempTable( $this->db, 'am1_user', $this->getTestUser()->getUser() );
|
2019-12-29 10:50:03 +00:00
|
|
|
$this->assertIsCallable( $callback );
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideStages
|
|
|
|
|
* @param int $stage
|
|
|
|
|
*/
|
|
|
|
|
public function testInsertWithTempTableCallbackMissingFields( $stage ) {
|
2019-07-23 17:40:52 +00:00
|
|
|
$w = TestingAccessWrapper::newFromClass( ActorMigration::class );
|
|
|
|
|
$w->tempTables = [
|
|
|
|
|
'foo_user' => [
|
|
|
|
|
'table' => 'foo_temp',
|
|
|
|
|
'pk' => 'footmp_id',
|
|
|
|
|
'field' => 'footmp_actor',
|
|
|
|
|
'joinPK' => 'foo_id',
|
|
|
|
|
'extra' => [ 'footmp_timestamp' => 'foo_timestamp' ],
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2017-09-12 17:12:29 +00:00
|
|
|
list( $fields, $callback )
|
2019-07-23 17:40:52 +00:00
|
|
|
= $m->getInsertValuesWithTempTable( $this->db, 'foo_user', $this->getTestUser()->getUser() );
|
2019-10-11 22:22:26 +00:00
|
|
|
$this->expectException( InvalidArgumentException::class );
|
|
|
|
|
$this->expectExceptionMessage( '$extra[foo_timestamp] is not provided' );
|
2017-09-12 17:12:29 +00:00
|
|
|
$callback( 1, [] );
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-04 19:23:41 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideStages
|
|
|
|
|
* @param int $stage
|
|
|
|
|
*/
|
|
|
|
|
public function testInsertUserIdentity( $stage ) {
|
|
|
|
|
$user = $this->getMutableTestUser()->getUser();
|
2019-10-05 22:14:35 +00:00
|
|
|
$userIdentity = $this->createMock( UserIdentity::class );
|
2017-09-12 17:12:29 +00:00
|
|
|
$userIdentity->method( 'getId' )->willReturn( $user->getId() );
|
|
|
|
|
$userIdentity->method( 'getName' )->willReturn( $user->getName() );
|
|
|
|
|
$userIdentity->method( 'getActorId' )->willReturn( 0 );
|
|
|
|
|
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2017-09-12 17:12:29 +00:00
|
|
|
list( $fields, $callback ) =
|
2019-07-23 17:40:52 +00:00
|
|
|
$m->getInsertValuesWithTempTable( $this->db, 'am2_user', $userIdentity );
|
|
|
|
|
$id = ++self::$amId;
|
|
|
|
|
$this->db->insert( 'actormigration2', [ 'am2_id' => $id ] + $fields, __METHOD__ );
|
|
|
|
|
$callback( $id, [] );
|
|
|
|
|
|
|
|
|
|
$qi = $m->getJoin( 'am2_user' );
|
2017-09-12 17:12:29 +00:00
|
|
|
$row = $this->db->selectRow(
|
2019-07-23 17:40:52 +00:00
|
|
|
[ 'actormigration2' ] + $qi['tables'],
|
|
|
|
|
$qi['fields'],
|
|
|
|
|
[ 'am2_id' => $id ],
|
|
|
|
|
__METHOD__,
|
|
|
|
|
[],
|
|
|
|
|
$qi['joins']
|
2017-09-12 17:12:29 +00:00
|
|
|
);
|
2019-07-23 17:40:52 +00:00
|
|
|
$this->assertSame( $user->getId(), (int)$row->am2_user );
|
|
|
|
|
$this->assertSame( $user->getName(), $row->am2_user_text );
|
2019-04-04 19:23:41 +00:00
|
|
|
$this->assertSame(
|
|
|
|
|
( $stage & SCHEMA_COMPAT_READ_NEW ) ? $user->getActorId() : 0,
|
2019-07-23 17:40:52 +00:00
|
|
|
(int)$row->am2_actor
|
2019-04-04 19:23:41 +00:00
|
|
|
);
|
2017-09-12 17:12:29 +00:00
|
|
|
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2017-09-12 17:12:29 +00:00
|
|
|
$fields = $m->getInsertValues( $this->db, 'dummy_user', $userIdentity );
|
2019-04-04 19:23:41 +00:00
|
|
|
if ( $stage & SCHEMA_COMPAT_WRITE_OLD ) {
|
|
|
|
|
$this->assertSame( $user->getId(), $fields['dummy_user'] );
|
|
|
|
|
$this->assertSame( $user->getName(), $fields['dummy_user_text'] );
|
|
|
|
|
} else {
|
|
|
|
|
$this->assertArrayNotHasKey( 'dummy_user', $fields );
|
|
|
|
|
$this->assertArrayNotHasKey( 'dummy_user_text', $fields );
|
|
|
|
|
}
|
|
|
|
|
if ( $stage & SCHEMA_COMPAT_WRITE_NEW ) {
|
|
|
|
|
$this->assertSame( $user->getActorId(), $fields['dummy_actor'] );
|
|
|
|
|
} else {
|
|
|
|
|
$this->assertArrayNotHasKey( 'dummy_actor', $fields );
|
|
|
|
|
}
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|
|
|
|
|
|
2018-09-18 18:21:20 +00:00
|
|
|
public function testNewMigration() {
|
2017-09-12 17:12:29 +00:00
|
|
|
$m = ActorMigration::newMigration();
|
|
|
|
|
$this->assertInstanceOf( ActorMigration::class, $m );
|
|
|
|
|
$this->assertSame( $m, ActorMigration::newMigration() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider provideIsAnon
|
|
|
|
|
* @param int $stage
|
|
|
|
|
* @param string $isAnon
|
|
|
|
|
* @param string $isNotAnon
|
|
|
|
|
*/
|
|
|
|
|
public function testIsAnon( $stage, $isAnon, $isNotAnon ) {
|
2020-10-11 21:55:12 +00:00
|
|
|
$m = $this->getMigration( $stage );
|
2017-09-12 17:12:29 +00:00
|
|
|
$this->assertSame( $isAnon, $m->isAnon( 'foo' ) );
|
|
|
|
|
$this->assertSame( $isNotAnon, $m->isNotAnon( 'foo' ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static function provideIsAnon() {
|
|
|
|
|
return [
|
2018-09-18 18:21:20 +00:00
|
|
|
'old' => [ SCHEMA_COMPAT_OLD, 'foo = 0', 'foo != 0' ],
|
|
|
|
|
'read-old' => [ SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_OLD, 'foo = 0', 'foo != 0' ],
|
|
|
|
|
'read-new' => [
|
|
|
|
|
SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_COMPAT_READ_NEW, 'foo IS NULL', 'foo IS NOT NULL'
|
|
|
|
|
],
|
|
|
|
|
'new' => [ SCHEMA_COMPAT_NEW, 'foo IS NULL', 'foo IS NOT NULL' ],
|
2017-09-12 17:12:29 +00:00
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-23 17:40:52 +00:00
|
|
|
public function testCheckDeprecation() {
|
|
|
|
|
$wrap = TestingAccessWrapper::newFromClass( ActorMigration::class );
|
|
|
|
|
$wrap->deprecated += [ 'soft' => null, 'hard' => '1.34' ];
|
|
|
|
|
$wrap->removed += [ 'gone' => '1.34' ];
|
|
|
|
|
|
|
|
|
|
$this->hideDeprecated( 'ActorMigration for \'hard\'' );
|
|
|
|
|
|
|
|
|
|
$wrap->checkDeprecation( 'valid' );
|
|
|
|
|
$wrap->checkDeprecation( 'soft' );
|
|
|
|
|
$wrap->checkDeprecation( 'hard' );
|
|
|
|
|
try {
|
|
|
|
|
$wrap->checkDeprecation( 'gone' );
|
|
|
|
|
} catch ( InvalidArgumentException $ex ) {
|
|
|
|
|
$this->assertSame(
|
|
|
|
|
'Use of ActorMigration for \'gone\' was removed in MediaWiki 1.34',
|
|
|
|
|
$ex->getMessage()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-12 17:12:29 +00:00
|
|
|
}
|