CommentStore: Hard-deprecate newKey()
[lhc/web/wiklou.git] / tests / phpunit / includes / TestUser.php
1 <?php
2
3 use MediaWiki\MediaWikiServices;
4
5 /**
6 * Wraps the user object, so we can also retain full access to properties
7 * like password if we log in via the API.
8 */
9 class TestUser {
10 /**
11 * @var string
12 */
13 private $username;
14
15 /**
16 * @var string
17 */
18 private $password;
19
20 /**
21 * @var User
22 */
23 private $user;
24
25 private function assertNotReal() {
26 global $wgDBprefix;
27 if ( $wgDBprefix !== MediaWikiTestCase::DB_PREFIX &&
28 $wgDBprefix !== MediaWikiTestCase::ORA_DB_PREFIX
29 ) {
30 throw new MWException( "Can't create user on real database" );
31 }
32 }
33
34 public function __construct( $username, $realname = 'Real Name',
35 $email = 'sample@example.com', $groups = []
36 ) {
37 $this->assertNotReal();
38
39 $this->username = $username;
40 $this->password = 'TestUser';
41
42 $this->user = User::newFromName( $this->username );
43 $this->user->load();
44
45 // In an ideal world we'd have a new wiki (or mock data store) for every single test.
46 // But for now, we just need to create or update the user with the desired properties.
47 // we particularly need the new password, since we just generated it randomly.
48 // In core MediaWiki, there is no functionality to delete users, so this is the best we can do.
49 if ( !$this->user->isLoggedIn() ) {
50 // create the user
51 $this->user = User::createNew(
52 $this->username, [
53 "email" => $email,
54 "real_name" => $realname
55 ]
56 );
57
58 if ( !$this->user ) {
59 throw new MWException( "Error creating TestUser " . $username );
60 }
61 }
62
63 // Update the user to use the password and other details
64 $this->setPassword( $this->password );
65 $change = $this->setEmail( $email ) ||
66 $this->setRealName( $realname );
67
68 // Adjust groups by adding any missing ones and removing any extras
69 $currentGroups = $this->user->getGroups();
70 foreach ( array_diff( $groups, $currentGroups ) as $group ) {
71 $this->user->addGroup( $group );
72 }
73 foreach ( array_diff( $currentGroups, $groups ) as $group ) {
74 $this->user->removeGroup( $group );
75 }
76 if ( $change ) {
77 // Disable CAS check before saving. The User object may have been initialized from cached
78 // information that may be out of whack with the database during testing. If tests were
79 // perfectly isolated, this would not happen. But if it does happen, let's just ignore the
80 // inconsistency, and just write the data we want - during testing, we are not worried
81 // about data loss.
82 $this->user->mTouched = '';
83 $this->user->saveSettings();
84 }
85 }
86
87 /**
88 * @param string $realname
89 * @return bool
90 */
91 private function setRealName( $realname ) {
92 if ( $this->user->getRealName() !== $realname ) {
93 $this->user->setRealName( $realname );
94 return true;
95 }
96
97 return false;
98 }
99
100 /**
101 * @param string $email
102 * @return bool
103 */
104 private function setEmail( $email ) {
105 if ( $this->user->getEmail() !== $email ) {
106 $this->user->setEmail( $email );
107 return true;
108 }
109
110 return false;
111 }
112
113 /**
114 * @param string $password
115 */
116 private function setPassword( $password ) {
117 self::setPasswordForUser( $this->user, $password );
118 }
119
120 /**
121 * Set the password on a testing user
122 *
123 * This assumes we're still using the generic AuthManager config from
124 * PHPUnitMaintClass::finalSetup(), and just sets the password in the
125 * database directly.
126 * @param User $user
127 * @param string $password
128 */
129 public static function setPasswordForUser( User $user, $password ) {
130 if ( !$user->getId() ) {
131 throw new MWException( "Passed User has not been added to the database yet!" );
132 }
133
134 $dbw = wfGetDB( DB_MASTER );
135 $row = $dbw->selectRow(
136 'user',
137 [ 'user_password' ],
138 [ 'user_id' => $user->getId() ],
139 __METHOD__
140 );
141 if ( !$row ) {
142 throw new MWException( "Passed User has an ID but is not in the database?" );
143 }
144
145 $passwordFactory = MediaWikiServices::getInstance()->getPasswordFactory();
146 if ( !$passwordFactory->newFromCiphertext( $row->user_password )->equals( $password ) ) {
147 $passwordHash = $passwordFactory->newFromPlaintext( $password );
148 $dbw->update(
149 'user',
150 [ 'user_password' => $passwordHash->toString() ],
151 [ 'user_id' => $user->getId() ],
152 __METHOD__
153 );
154 }
155 }
156
157 /**
158 * @since 1.25
159 * @return User
160 */
161 public function getUser() {
162 return $this->user;
163 }
164
165 /**
166 * @since 1.25
167 * @return string
168 */
169 public function getPassword() {
170 return $this->password;
171 }
172 }