the browser-facing portion of osu!
at master 9.4 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\Chat; 9 10use App\Models\Chat\Channel; 11use App\Models\OAuth\Client; 12use App\Models\User; 13use App\Models\UserRelation; 14use Faker; 15use Illuminate\Testing\Fluent\AssertableJson; 16use Tests\TestCase; 17 18class ChatControllerTest extends TestCase 19{ 20 protected static $faker; 21 22 private User $anotherUser; 23 private User $user; 24 25 public static function setUpBeforeClass(): void 26 { 27 self::$faker = Faker\Factory::create(); 28 } 29 30 //region POST /chat/new - Create New PM 31 32 /** 33 * @dataProvider createPmWithAuthorizedGrantDataProvider 34 */ 35 public function testCreatePmWithAuthorizedGrant($scopes, $expectedStatus) 36 { 37 $this->actAsScopedUser($this->user, $scopes); 38 $this->json( 39 'POST', 40 route('api.chat.new'), 41 [ 42 'target_id' => $this->anotherUser->user_id, 43 'message' => self::$faker->sentence(), 44 ] 45 )->assertStatus($expectedStatus); 46 } 47 48 /** 49 * @dataProvider createPmWithClientCredentialsDataProvider 50 */ 51 public function testCreatePmWithClientCredentials($scopes, $expectedStatus) 52 { 53 $client = Client::factory()->create(['user_id' => $this->user]); 54 $this->actAsScopedUser(null, $scopes, $client); 55 $this->json( 56 'POST', 57 route('api.chat.new'), 58 [ 59 'target_id' => $this->anotherUser->user_id, 60 'message' => self::$faker->sentence(), 61 ] 62 )->assertStatus($expectedStatus); 63 } 64 65 /** 66 * @dataProvider createPmWithClientCredentialsBotGroupDataProvider 67 */ 68 public function testCreatePmWithClientCredentialsBotGroup($scopes, $expectedStatus) 69 { 70 $client = Client::factory()->create(['user_id' => $this->user]); 71 $this->user->update(['group_id' => app('groups')->byIdentifier('bot')->getKey()]); 72 $this->actAsScopedUser(null, $scopes, $client); 73 $this->json( 74 'POST', 75 route('api.chat.new'), 76 [ 77 'target_id' => $this->anotherUser->user_id, 78 'message' => self::$faker->sentence(), 79 ] 80 )->assertStatus($expectedStatus); 81 } 82 83 public function testCreatePMWhenAlreadyExists() // success 84 { 85 $this->actAsScopedUser($this->user, ['*']); 86 $this->json( 87 'POST', 88 route('api.chat.new'), 89 [ 90 'target_id' => $this->anotherUser->user_id, 91 'message' => self::$faker->sentence(), 92 ] 93 )->assertStatus(200); 94 95 // should return existing conversation and not error 96 $this->json( 97 'POST', 98 route('api.chat.new'), 99 [ 100 'target_id' => $this->anotherUser->user_id, 101 'message' => self::$faker->sentence(), 102 ] 103 )->assertStatus(200); 104 } 105 106 public function testCreatePMWhenLeftChannel() // success 107 { 108 $this->actAsScopedUser($this->user, ['*']); 109 $request = $this->json( 110 'POST', 111 route('api.chat.new'), 112 [ 113 'target_id' => $this->anotherUser->user_id, 114 'message' => self::$faker->sentence(), 115 ] 116 ); 117 118 $channelId = $request->json('new_channel_id'); 119 $request->assertSuccessful(); 120 121 $this->json( 122 'DELETE', 123 route('api.chat.channels.part', [ 124 'channel' => $channelId, 125 'user' => $this->user->user_id, 126 ]) 127 )->assertSuccessful(); 128 129 $this->json( 130 'POST', 131 route('api.chat.new'), 132 [ 133 'target_id' => $this->anotherUser->user_id, 134 'message' => self::$faker->sentence(), 135 ] 136 )->assertSuccessful(); 137 } 138 139 public function testCreatePMWhenGuest() // fail 140 { 141 $this->json( 142 'POST', 143 route('api.chat.new'), 144 [ 145 'target_id' => $this->anotherUser->user_id, 146 'message' => self::$faker->sentence(), 147 ] 148 )->assertStatus(401); 149 } 150 151 public function testCreatePMWhenBlocked() // fail 152 { 153 UserRelation::factory()->block()->create([ 154 'user_id' => $this->anotherUser, 155 'zebra_id' => $this->user, 156 ]); 157 158 $this->actAsScopedUser($this->user, ['*']); 159 $this->json( 160 'POST', 161 route('api.chat.new'), 162 [ 163 'target_id' => $this->anotherUser->user_id, 164 'message' => self::$faker->sentence(), 165 ] 166 )->assertStatus(403); 167 } 168 169 public function testCreatePMWhenRestricted() // fail 170 { 171 $restrictedUser = User::factory()->restricted()->create(); 172 173 $this->actAsScopedUser($restrictedUser, ['*']); 174 $this->json( 175 'POST', 176 route('api.chat.new'), 177 [ 178 'target_id' => $this->anotherUser->user_id, 179 'message' => self::$faker->sentence(), 180 ] 181 )->assertStatus(403); 182 } 183 184 public function testCreatePMWhenSilenced() // fail 185 { 186 $silencedUser = User::factory()->silenced()->create(); 187 188 $this->actAsScopedUser($silencedUser, ['*']); 189 $this->json( 190 'POST', 191 route('api.chat.new'), 192 [ 193 'target_id' => $this->anotherUser->user_id, 194 'message' => self::$faker->sentence(), 195 ] 196 )->assertStatus(403); 197 } 198 199 public function testCreatePMWhenTargetRestricted() // fail 200 { 201 $restrictedUser = User::factory()->restricted()->create(); 202 203 $this->actAsScopedUser($this->user, ['*']); 204 $this->json( 205 'POST', 206 route('api.chat.new'), 207 [ 208 'target_id' => $restrictedUser->user_id, 209 'message' => self::$faker->sentence(), 210 ] 211 )->assertStatus(422); 212 } 213 214 public function testCreatePMWithSelf() // fail 215 { 216 $this->actAsScopedUser($this->user, ['*']); 217 $this->json( 218 'POST', 219 route('api.chat.new'), 220 [ 221 'target_id' => $this->user->user_id, 222 'message' => self::$faker->sentence(), 223 ] 224 )->assertStatus(422); 225 } 226 227 public function testCreatePMWhenFriendsOnlyAndNotFriended() // fail 228 { 229 $privateUser = User::factory()->create(['pm_friends_only' => true]); 230 231 $this->actAsScopedUser($this->user, ['*']); 232 $this->json( 233 'POST', 234 route('api.chat.new'), 235 [ 236 'target_id' => $privateUser->user_id, 237 'message' => self::$faker->sentence(), 238 ] 239 )->assertStatus(403); 240 } 241 242 public function testCreatePMWhenFriendsOnlyAndFriended() // success 243 { 244 $privateUser = User::factory()->create(['pm_friends_only' => true]); 245 UserRelation::factory()->friend()->create([ 246 'user_id' => $privateUser, 247 'zebra_id' => $this->user, 248 ]); 249 250 $this->actAsScopedUser($this->user, ['*']); 251 $this->json( 252 'POST', 253 route('api.chat.new'), 254 [ 255 'target_id' => $privateUser->user_id, 256 'message' => self::$faker->sentence(), 257 ] 258 )->assertStatus(200); 259 } 260 261 //endregion 262 263 //region GET /chat/updates 264 public function testChatUpdatesWhenGuest() 265 { 266 $this->json('GET', route('api.chat.updates')) 267 ->assertStatus(401); 268 } 269 270 public function testChatUpdatesJoinChannel() 271 { 272 $publicChannel = Channel::factory()->type('public')->create(); 273 274 // join channel 275 $this->actAsScopedUser($this->user, ['*']); 276 $this->json('PUT', route('api.chat.channels.join', [ 277 'channel' => $publicChannel->channel_id, 278 'user' => $this->user->user_id, 279 ])) 280 ->assertSuccessful(); 281 282 $this->json('GET', route('api.chat.updates'), ['since' => 0]) 283 ->assertStatus(200) 284 ->assertJson(fn (AssertableJson $json) => 285 $json->where('presence.0.channel_id', $publicChannel->getKey()) 286 ->etc()); 287 } 288 289 //endregion 290 291 public static function createPmWithAuthorizedGrantDataProvider() 292 { 293 return [ 294 [['*'], 200], 295 // there's no test for bot because the test setup itself is expected to fail when setting the token. 296 [['public'], 403], 297 ]; 298 } 299 300 public static function createPmWithClientCredentialsDataProvider() 301 { 302 return [ 303 // TODO: need to add test that validates auth guard calls Token::validate 304 [['public'], 403], 305 ]; 306 } 307 308 public static function createPmWithClientCredentialsBotGroupDataProvider() 309 { 310 return [ 311 [['chat.write', 'delegate'], 200], 312 [['public'], 403], 313 ]; 314 } 315 316 protected function setUp(): void 317 { 318 parent::setUp(); 319 320 $this->user = User::factory()->withPlays()->create(); 321 $this->anotherUser = User::factory()->create(); 322 } 323}