the browser-facing portion of osu!
at master 7.9 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6declare(strict_types=1); 7 8namespace Tests\Controllers; 9 10use App\Mail\UserEmailUpdated; 11use App\Mail\UserPasswordUpdated; 12use App\Models\Country; 13use App\Models\User; 14use App\Models\UserProfileCustomization; 15use App\Models\WeakPassword; 16use Database\Factories\UserFactory; 17use Hash; 18use Mail; 19use Tests\TestCase; 20 21class AccountControllerTest extends TestCase 22{ 23 private $user; 24 25 /** 26 * Checks whether an OK status is returned when the 27 * profile order update request is valid. 28 */ 29 public function testValidProfileOrderChangeRequest() 30 { 31 $newOrder = UserProfileCustomization::SECTIONS; 32 seeded_shuffle($newOrder); 33 34 $this->actingAsVerified($this->user()) 35 ->json('PUT', route('account.options'), [ 36 'order' => $newOrder, 37 ]) 38 ->assertJsonFragment(['profile_order' => $newOrder]); 39 } 40 41 public function testDuplicatesInProfileOrder() 42 { 43 $newOrder = UserProfileCustomization::SECTIONS; 44 45 $newOrderWithDuplicate = $newOrder; 46 $newOrderWithDuplicate[] = $newOrder[0]; 47 48 $this->actingAsVerified($this->user()) 49 ->json('PUT', route('account.options'), [ 50 'order' => $newOrderWithDuplicate, 51 ]) 52 ->assertJsonFragment(['profile_order' => $newOrder]); 53 } 54 55 public function testInvalidIdsInProfileOrder() 56 { 57 $newOrder = UserProfileCustomization::SECTIONS; 58 59 $newOrderWithInvalid = $newOrder; 60 $newOrderWithInvalid[] = 'test'; 61 62 $this->actingAsVerified($this->user()) 63 ->json('PUT', route('account.options'), [ 64 'order' => $newOrderWithInvalid, 65 ]) 66 ->assertJsonFragment(['profile_order' => $newOrder]); 67 } 68 69 /** 70 * @dataProvider dataProviderForUpdateCountry 71 * @group RequiresScoreIndexer 72 * 73 * More complete tests are done through CountryChange and CountryChangeTarget. 74 */ 75 public function testUpdateCountry(?string $historyCountry, ?string $targetCountry, bool $success): void 76 { 77 $user = $this->user(); 78 foreach (array_unique([$historyCountry, $targetCountry]) as $country) { 79 if ($country !== null) { 80 Country::factory()->create(['acronym' => $country]); 81 } 82 } 83 if ($historyCountry !== null) { 84 UserFactory::createRecentCountryHistory($user, $historyCountry, null); 85 } 86 87 $resultCountry = $success ? $targetCountry : $user->country_acronym; 88 89 $this->actingAsVerified($user) 90 ->json('PUT', route('account.country', ['country_acronym' => $targetCountry])) 91 ->assertStatus($success ? 200 : 403); 92 93 $this->assertSame($user->fresh()->country_acronym, $resultCountry); 94 } 95 96 public function testUpdateEmail() 97 { 98 $newEmail = 'new-'.$this->user->user_email; 99 100 Mail::fake(); 101 102 $this->actingAsVerified($this->user()) 103 ->json('PUT', route('account.email'), [ 104 'user' => [ 105 'current_password' => 'password', 106 'user_email' => $newEmail, 107 'user_email_confirmation' => $newEmail, 108 ], 109 ]) 110 ->assertSuccessful(); 111 112 $this->assertSame($newEmail, $this->user->fresh()->user_email); 113 114 Mail::assertQueued(UserEmailUpdated::class, 2); 115 } 116 117 public function testUpdateEmailLocked() 118 { 119 $newEmail = 'new-'.$this->user->user_email; 120 $this->user->update(['lock_email_changes' => true]); 121 122 $this->actingAsVerified($this->user()) 123 ->json('PUT', route('account.email'), [ 124 'user' => [ 125 'current_password' => 'password', 126 'user_email' => $newEmail, 127 'user_email_confirmation' => $newEmail, 128 ], 129 ]) 130 ->assertStatus(403); 131 } 132 133 public function testUpdateEmailInvalidPassword() 134 { 135 $newEmail = 'new-'.$this->user->user_email; 136 137 $this->actingAsVerified($this->user()) 138 ->json('PUT', route('account.email'), [ 139 'user' => [ 140 'current_password' => 'password1', 141 'user_email' => $newEmail, 142 'user_email_confirmation' => $newEmail, 143 ], 144 ]) 145 ->assertStatus(422); 146 } 147 148 public function testUpdatePassword() 149 { 150 $newPassword = 'newpassword'; 151 152 Mail::fake(); 153 154 $this->actingAsVerified($this->user()) 155 ->json('PUT', route('account.password'), [ 156 'user' => [ 157 'current_password' => 'password', 158 'password' => $newPassword, 159 'password_confirmation' => $newPassword, 160 ], 161 ]) 162 ->assertSuccessful(); 163 164 $this->assertTrue(Hash::check($newPassword, $this->user->fresh()->user_password)); 165 166 Mail::assertQueued(UserPasswordUpdated::class); 167 } 168 169 public function testUpdatePasswordInvalidCurrentPassword() 170 { 171 $this->actingAsVerified($this->user()) 172 ->json('PUT', route('account.password'), [ 173 'user' => [ 174 'current_password' => 'notpassword', 175 'password' => 'newpassword', 176 'password_confirmation' => 'newpassword', 177 ], 178 ]) 179 ->assertStatus(422); 180 } 181 182 public function testUpdatePasswordInvalidPasswordConfirmation() 183 { 184 $this->actingAsVerified($this->user()) 185 ->json('PUT', route('account.password'), [ 186 'user' => [ 187 'current_password' => 'password', 188 'password' => 'newpassword', 189 'password_confirmation' => 'oldpassword', 190 ], 191 ]) 192 ->assertStatus(422); 193 } 194 195 public function testUpdatePasswordUsernameAsPassword() 196 { 197 $this->actingAsVerified($this->user()) 198 ->json('PUT', route('account.password'), [ 199 'user' => [ 200 'current_password' => 'password', 201 'password' => $this->user->username, 202 'password_confirmation' => $this->user->username, 203 ], 204 ]) 205 ->assertStatus(422); 206 } 207 208 public function testUpdatePasswordShortPassword() 209 { 210 $this->actingAsVerified($this->user()) 211 ->json('PUT', route('account.password'), [ 212 'user' => [ 213 'current_password' => 'password', 214 'password' => '1234567', 215 'password_confirmation' => '1234567', 216 ], 217 ]) 218 ->assertStatus(422); 219 } 220 221 public function testUpdatePasswordWeakPassword() 222 { 223 $weakPassword = 'weakpassword'; 224 225 WeakPassword::add($weakPassword); 226 227 $this->actingAsVerified($this->user()) 228 ->json('PUT', route('account.password'), [ 229 'user' => [ 230 'current_password' => 'password', 231 'password' => $weakPassword, 232 'password_confirmation' => $weakPassword, 233 ], 234 ]) 235 ->assertStatus(422); 236 } 237 238 public static function dataProviderForUpdateCountry(): array 239 { 240 return [ 241 ['_A', '_A', true], 242 ['_B', '_A', false], 243 [null, null, false], 244 ]; 245 } 246 247 protected function setUp(): void 248 { 249 parent::setUp(); 250 251 $this->user = User::factory()->create(); 252 } 253 254 private function user() 255 { 256 // To reset all the verify toggles. 257 return $this->user->fresh(); 258 } 259}