File: RenameUserTest.php

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (158 lines) | stat: -rw-r--r-- 7,005 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php

namespace MediaWiki\Tests\Maintenance;

use MediaWiki\MainConfigNames;
use MediaWiki\Revision\SlotRecord;
use MediaWiki\Title\Title;
use MediaWiki\User\CentralId\CentralIdLookup;
use RenameUser;

/**
 * @covers \RenameUser
 * @group Database
 * @author Dreamy Jazz
 */
class RenameUserTest extends MaintenanceBaseTestCase {
	public function getMaintenanceClass() {
		return RenameUser::class;
	}

	/** @dataProvider provideExecuteForFatalError */
	public function testExecuteForFatalError( $oldName, $newName, $options, $expectedOutputRegex ) {
		$this->maintenance->setArg( 'old-name', $oldName );
		$this->maintenance->setArg( 'new-name', $newName );
		foreach ( $options as $name => $value ) {
			$this->maintenance->setOption( $name, $value );
		}
		$this->expectCallToFatalError();
		$this->expectOutputRegex( $expectedOutputRegex );
		$this->maintenance->execute();
	}

	public static function provideExecuteForFatalError() {
		return [
			'Invalid old name' => [ 'Template:Testing#test', 'abc', [], '/The specified old username is invalid/' ],
			'Non-existing old name' => [ 'Non-existing-test-user123', 'abc', [], '/The user does not exist/' ],
		];
	}

	/** @dataProvider provideExecuteForFatalErrorWithValidOldName */
	public function testExecuteForFatalErrorWithValidOldName( $newName, $options, $expectedOutputRegex ) {
		$oldName = $this->getMutableTestUser()->getUserIdentity()->getName();
		$this->testExecuteForFatalError( $oldName, $newName, $options, $expectedOutputRegex );
		// Check that the old username has not been renamed, as the script should have failed to perform the rename.
		$this->newSelectQueryBuilder()
			->select( 'COUNT(*)' )
			->from( 'actor' )
			->where( [ 'actor_name' => $oldName ] )
			->assertFieldValue( 1 );
	}

	public static function provideExecuteForFatalErrorWithValidOldName() {
		return [
			'Invalid new name' => [ 'Template:Test#testing', [], '/The specified new username is invalid/' ],
			'Performer does not exist' => [
				'Abc', [ 'performer' => 'Non-existing-test-user' ], '/Performer does not exist/',
			],
		];
	}

	public function testExecuteWhenNewNameIsAlreadyTaken() {
		$newName = $this->getMutableTestUser()->getUserIdentity();
		$this->testExecuteForFatalErrorWithValidOldName( $newName, [], '/New username must be free/' );
	}

	public function testExecuteWhenUserIsAttachedToNonLocalProvider() {
		// Set the CentralIdLookup as a mock CentralIdLookup which always returns true from ::isAttached.
		$this->overrideConfigValue( MainConfigNames::CentralIdLookupProviders, [
			'renameUserTestProvider' => [
				'factory' => function () {
					$mockCentralIdLookup = $this->createMock( CentralIdLookup::class );
					$mockCentralIdLookup->method( 'isAttached' )
						->willReturn( true );
					return $mockCentralIdLookup;
				},
			],
		] );
		$this->overrideConfigValue( MainConfigNames::CentralIdLookupProvider, 'renameUserTestProvider' );
		// Run the maintenance script and expect an error.
		$this->testExecuteForFatalErrorWithValidOldName(
			$this->getTestUser()->getUserIdentity()->getName(), [], '/The user is globally attached/'
		);
	}

	public function testExecuteWithoutPageMoves() {
		// Get one testing user, and create a user talk and user page for that user
		$testUser = $this->getMutableTestUser( [], 'Abc' );
		$testUser->getUser()->addToDatabase();
		$userPageBeforeRename = $testUser->getUser()->getUserPage();
		$this->editPage( $userPageBeforeRename, 'user testing1234' );
		$userTalkPageBeforeRename = $userPageBeforeRename->getTalkPageIfDefined();
		$this->editPage( $userTalkPageBeforeRename, 'usertalk testing1234' );
		$testUserIdentity = $testUser->getUserIdentity();
		// Run the maintenance script
		$this->maintenance->setArg( 'old-name', $testUserIdentity->getName() );
		$this->maintenance->setArg( 'new-name', 'Abcdef-user' );
		$this->maintenance->setOption( 'skip-page-moves', true );
		$this->maintenance->execute();
		// Check that the output of the script is as expected
		$this->expectOutputRegex(
			'/' . preg_quote( $testUserIdentity->getName(), '/' ) . ' was successfully renamed to Abcdef-user/'
		);
		// Check that the rename actually occurred
		$this->newSelectQueryBuilder()
			->select( 'user_name' )
			->from( 'user' )
			->where( [ 'user_id' => $testUserIdentity->getId() ] )
			->assertFieldValue( 'Abcdef-user' );
		// Check that the user page and user talk page were not moved.
		$userPageContent = $this->getServiceContainer()->getRevisionLookup()
			->getRevisionByTitle( $userPageBeforeRename )
			->getContent( SlotRecord::MAIN )->getWikitextForTransclusion();
		$this->assertSame( 'user testing1234', $userPageContent );
		$userTalkPageContent = $this->getServiceContainer()->getRevisionLookup()
			->getRevisionByTitle( $userTalkPageBeforeRename )
			->getContent( SlotRecord::MAIN )->getWikitextForTransclusion();
		$this->assertSame( 'usertalk testing1234', $userTalkPageContent );
		$this->assertFalse( Title::newFromText( 'abcdef-user', NS_USER )->exists() );
		$this->assertFalse( Title::newFromText( 'abcdef-user', NS_USER_TALK )->exists() );
	}

	public function testExecuteWithPageMoves() {
		// Get one testing user, and create a user talk and user page for that user
		$testUser = $this->getMutableTestUser( [], 'Abc' );
		$testUser->getUser()->addToDatabase();
		$this->editPage( $testUser->getUser()->getUserPage(), 'user testing1234' );
		$userTalkPageBeforeRename = $testUser->getUser()->getUserPage()->getTalkPageIfDefined();
		$this->editPage( $userTalkPageBeforeRename, 'usertalk testing1234' );
		$this->editPage( Title::newFromText( $userTalkPageBeforeRename->getPrefixedText() . '/test' ), 'usertalk subpage' );
		$testUserIdentity = $testUser->getUserIdentity();
		// Run the maintenance script
		$this->maintenance->setArg( 'old-name', $testUserIdentity->getName() );
		$this->maintenance->setArg( 'new-name', 'Abcdef-user' );
		$this->maintenance->execute();
		// Check that the output of the script is as expected
		$this->expectOutputRegex(
			'/' . preg_quote( $testUserIdentity->getName(), '/' ) . ' was successfully renamed to Abcdef-user/'
		);
		// Check that the rename actually occurred
		$this->newSelectQueryBuilder()
			->select( 'user_name' )
			->from( 'user' )
			->where( [ 'user_id' => $testUserIdentity->getId() ] )
			->assertFieldValue( 'Abcdef-user' );
		// Check that the user page, user talk page, and user talk subpage were actually moved.
		$expectedPageContent = [
			'user testing1234' => Title::newFromText( 'abcdef-user', NS_USER ),
			'usertalk testing1234' => Title::newFromText( 'abcdef-user', NS_USER_TALK ),
			'usertalk subpage' => Title::newFromText( 'abcdef-user/test', NS_USER_TALK ),
		];
		foreach ( $expectedPageContent as $expectedContent => $title ) {
			$userPageContent = $this->getServiceContainer()->getRevisionLookup()
				->getRevisionByTitle( $title )
				->getContent( SlotRecord::MAIN )->getWikitextForTransclusion();
			$this->assertSame( $expectedContent, $userPageContent );
		}
	}
}