the browser-facing portion of osu!
at master 13 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\Channels; 9 10use App\Models\Chat\Channel; 11use App\Models\Chat\UserChannel; 12use App\Models\ChatFilter; 13use App\Models\User; 14use App\Models\UserRelation; 15use Faker; 16use Tests\TestCase; 17 18class MessagesControllerTest extends TestCase 19{ 20 protected static $faker; 21 22 private User $anotherUser; 23 private Channel $privateChannel; 24 private Channel $publicChannel; 25 private User $restrictedUser; 26 private User $silencedUser; 27 private Channel $tourneyChannel; 28 private User $user; 29 30 public static function setUpBeforeClass(): void 31 { 32 self::$faker = Faker\Factory::create(); 33 } 34 35 //region GET /chat/channels/[channel_id]/messages - Get Channel Messages (public) 36 public function testChannelShowPublicWhenGuest() // fail 37 { 38 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->publicChannel->channel_id])) 39 ->assertStatus(401); 40 } 41 42 public function testChannelShowPublicWhenUnjoined() // fail 43 { 44 $this->actAsScopedUser($this->user, ['*']); 45 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->publicChannel->channel_id])) 46 ->assertStatus(404); 47 } 48 49 public function testChannelShowPublicWhenJoined() // success 50 { 51 $this->actAsScopedUser($this->user, ['*']); 52 $this->json('PUT', route('api.chat.channels.join', [ 53 'channel' => $this->publicChannel->channel_id, 54 'user' => $this->user->user_id, 55 ])); 56 57 $this->actAsScopedUser($this->user, ['*']); 58 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->publicChannel->channel_id])) 59 ->assertStatus(200); 60 // TODO: Add check for messages being present? 61 } 62 63 //endregion 64 65 //region GET /chat/channels/[channel_id]/messages - Get Channel Messages (tourney) 66 public function testChannelShowTourneyWhenGuest() // fail 67 { 68 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->tourneyChannel->channel_id])) 69 ->assertStatus(401); 70 } 71 72 public function testChannelShowTourneyWhenUnjoined() // fail 73 { 74 $this->actAsScopedUser($this->user, ['*']); 75 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->tourneyChannel->channel_id])) 76 ->assertStatus(404); 77 } 78 79 public function testChannelShowTourneyWhenJoined() // success 80 { 81 $this->actAsScopedUser($this->user, ['*']); 82 $this->json('PUT', route('api.chat.channels.join', [ 83 'channel' => $this->tourneyChannel->channel_id, 84 'user' => $this->user->user_id, 85 ]))->assertSuccessful(); 86 87 $this->actAsScopedUser($this->user, ['*']); 88 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->tourneyChannel->channel_id])) 89 ->assertStatus(200); 90 // TODO: Add check for messages being present? 91 } 92 93 //endregion 94 95 //region GET /chat/channels/[channel_id]/messages - Get Channel Messages (private) 96 public function testChannelShowPrivateWhenGuest() // fail 97 { 98 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->privateChannel->channel_id])) 99 ->assertStatus(401); 100 } 101 102 public function testChannelShowPrivateWhenNotJoined() // fail 103 { 104 $this->actAsScopedUser($this->user, ['*']); 105 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->privateChannel->channel_id])) 106 ->assertStatus(404); 107 } 108 109 public function testChannelShowPrivateWhenJoined() // success 110 { 111 $this->userChannel = UserChannel::factory()->create([ 112 'user_id' => $this->user->user_id, 113 'channel_id' => $this->privateChannel->channel_id, 114 ]); 115 116 $this->actAsScopedUser($this->user, ['*']); 117 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $this->privateChannel->channel_id])) 118 ->assertStatus(200); 119 } 120 121 //endregion 122 123 //region GET /chat/channels/[channel_id]/messages - Get Channel Messages (pm) 124 public function testChannelShowPMWhenGuest() // fail 125 { 126 $pmChannel = Channel::factory()->type('pm')->create(); 127 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $pmChannel->channel_id])) 128 ->assertStatus(401); 129 } 130 131 public function testChannelShowPMWhenNotJoined() // fail 132 { 133 $pmChannel = Channel::factory()->type('pm')->create(); 134 $this->actAsScopedUser($this->user, ['*']); 135 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $pmChannel->channel_id])) 136 ->assertStatus(404); 137 } 138 139 public function testChannelShowPMWhenTargetRestricted() // fail 140 { 141 $pmChannel = Channel::factory()->type('pm', [$this->user, $this->restrictedUser])->create(); 142 143 $this->actAsScopedUser($this->user, ['*']); 144 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $pmChannel->channel_id])) 145 ->assertStatus(404); 146 } 147 148 public function testChannelShowPM() // success 149 { 150 $pmChannel = Channel::factory()->type('pm', [$this->user, $this->anotherUser])->create(); 151 152 $this->actAsScopedUser($this->user, ['*']); 153 $this->json('GET', route('api.chat.channels.messages.index', ['channel' => $pmChannel->channel_id])) 154 ->assertStatus(200); 155 // TODO: Add check for messages being present? 156 } 157 158 //endregion 159 160 //region POST /chat/channels/[channel_id]/messages - Send Message to Channel 161 public function testChannelSendFiltered() 162 { 163 $this->actAsScopedUser($this->user, ['*']); 164 $this->json('PUT', route('api.chat.channels.join', [ 165 'channel' => $this->publicChannel->getKey(), 166 'user' => $this->user->getKey(), 167 ])); 168 169 $filter = ChatFilter::factory()->create(); 170 171 $this->json( 172 'POST', 173 route('api.chat.channels.messages.store', ['channel' => $this->publicChannel->getKey()]), 174 ['message' => $filter->match], 175 ) 176 ->assertJsonFragment(['content' => $filter->replacement]); 177 } 178 179 public function testChannelSendWhenGuest() // fail 180 { 181 $this->json( 182 'POST', 183 route('api.chat.channels.messages.store', ['channel' => $this->publicChannel->channel_id]), 184 ['message' => self::$faker->sentence()] 185 )->assertStatus(401); 186 } 187 188 public function testChannelSendWhenUnjoined() // fail 189 { 190 $this->actAsScopedUser($this->user, ['*']); 191 $this->json( 192 'POST', 193 route('api.chat.channels.messages.store', ['channel' => $this->publicChannel->channel_id]), 194 ['message' => self::$faker->sentence()] 195 ) 196 ->assertStatus(403); 197 } 198 199 public function testChannelSendWhenJoined() // success 200 { 201 $message = self::$faker->sentence(); 202 203 $this->actAsScopedUser($this->user, ['*']); 204 $this->json('PUT', route('api.chat.channels.join', [ 205 'channel' => $this->publicChannel->channel_id, 206 'user' => $this->user->user_id, 207 ])); 208 209 $this->actAsScopedUser($this->user, ['*']); 210 211 $this->json( 212 'POST', 213 route('api.chat.channels.messages.store', ['channel' => $this->publicChannel->channel_id]), 214 ['message' => $message] 215 ) 216 ->assertStatus(200) 217 ->assertJsonFragment(['content' => $message]); 218 } 219 220 public function testChannelSendWhenModerated() // fail 221 { 222 $moderatedChannel = Channel::factory()->type('public')->create(['moderated' => true]); 223 224 $this->actAsScopedUser($this->user, ['*']); 225 $this->json( 226 'POST', 227 route('api.chat.channels.messages.store', ['channel' => $moderatedChannel->channel_id]), 228 ['message' => self::$faker->sentence()] 229 ) 230 ->assertStatus(403); 231 } 232 233 public function testChannelSendWhenBlocking() // fail 234 { 235 $pmChannel = Channel::factory()->type('pm', [$this->user, $this->anotherUser])->create(); 236 UserRelation::factory()->block()->create([ 237 'user_id' => $this->user, 238 'zebra_id' => $this->anotherUser, 239 ]); 240 241 $this->actAsScopedUser($this->user, ['*']); 242 $this->json( 243 'POST', 244 route('api.chat.channels.messages.store', ['channel' => $pmChannel->channel_id]), 245 ['message' => self::$faker->sentence()] 246 ) 247 ->assertStatus(403); 248 } 249 250 public function testChannelSendWhenBlocked() // fail 251 { 252 $pmChannel = Channel::factory()->type('pm', [$this->user, $this->anotherUser])->create(); 253 UserRelation::factory()->block()->create([ 254 'user_id' => $this->anotherUser, 255 'zebra_id' => $this->user, 256 ]); 257 258 $this->actAsScopedUser($this->user, ['*']); 259 $this->json( 260 'POST', 261 route('api.chat.channels.messages.store', ['channel' => $pmChannel->channel_id]), 262 ['message' => self::$faker->sentence()] 263 ) 264 ->assertStatus(403); 265 } 266 267 public function testChannelSendWhenRestrictedToPM() // fail 268 { 269 $pmChannel = Channel::factory()->type('pm', [$this->restrictedUser, $this->anotherUser])->create(); 270 271 $this->actAsScopedUser($this->restrictedUser, ['*']); 272 $this->json( 273 'POST', 274 route('api.chat.channels.messages.store', ['channel' => $pmChannel->channel_id]), 275 ['message' => self::$faker->sentence()] 276 ) 277 ->assertStatus(403); 278 } 279 280 public function testChannelSendWhenRestrictedToPublic() // fail 281 { 282 $this->actAsScopedUser($this->restrictedUser, ['*']); 283 $this->json('PUT', route('api.chat.channels.join', [ 284 'channel' => $this->publicChannel->channel_id, 285 'user' => $this->restrictedUser->user_id, 286 ])); 287 288 $this->actAsScopedUser($this->restrictedUser, ['*']); 289 $this->json( 290 'POST', 291 route('api.chat.channels.messages.store', ['channel' => $this->publicChannel->channel_id]), 292 ['message' => self::$faker->sentence()] 293 ) 294 ->assertStatus(403); 295 } 296 297 public function testChannelSendWhenTargetRestricted() // fail 298 { 299 $pmChannel = Channel::factory()->type('pm', [$this->user, $this->restrictedUser])->create(); 300 301 $this->actAsScopedUser($this->user, ['*']); 302 $this->json( 303 'POST', 304 route('api.chat.channels.messages.store', ['channel' => $pmChannel->channel_id]), 305 ['message' => self::$faker->sentence()] 306 ) 307 ->assertStatus(404); 308 } 309 310 public function testChannelSendWhenTourney() // fail 311 { 312 $message = self::$faker->sentence(); 313 314 $this->actAsScopedUser($this->user, ['*']); 315 $this->json('PUT', route('api.chat.channels.join', [ 316 'channel' => $this->tourneyChannel->channel_id, 317 'user' => $this->user->user_id, 318 ])); 319 320 $this->actAsScopedUser($this->user, ['*']); 321 322 $this->json( 323 'POST', 324 route('api.chat.channels.messages.store', ['channel' => $this->tourneyChannel->channel_id]), 325 ['message' => $message] 326 ) 327 ->assertStatus(403); 328 } 329 330 public function testChannelSendWhenSilencedToPM() // fail 331 { 332 $pmChannel = Channel::factory()->type('pm', [$this->silencedUser, $this->anotherUser])->create(); 333 334 $this->actAsScopedUser($this->silencedUser, ['*']); 335 $this->json( 336 'POST', 337 route('api.chat.channels.messages.store', ['channel' => $pmChannel->channel_id]), 338 ['message' => self::$faker->sentence()] 339 ) 340 ->assertStatus(403); 341 } 342 343 public function testChannelSendWhenSilencedToPublic() // fail 344 { 345 $this->actAsScopedUser($this->silencedUser, ['*']); 346 $this->json('PUT', route('api.chat.channels.join', [ 347 'channel' => $this->publicChannel->channel_id, 348 'user' => $this->silencedUser->user_id, 349 ])); 350 351 $this->actAsScopedUser($this->silencedUser, ['*']); 352 $this->json( 353 'POST', 354 route('api.chat.channels.messages.store', ['channel' => $this->publicChannel->channel_id]), 355 ['message' => self::$faker->sentence()] 356 ) 357 ->assertStatus(403); 358 } 359 360 //endregion 361 362 protected function setUp(): void 363 { 364 parent::setUp(); 365 366 $this->user = User::factory()->withPlays()->create(); 367 $this->anotherUser = User::factory()->create(); 368 $this->restrictedUser = User::factory()->restricted()->create(); 369 $this->silencedUser = User::factory()->silenced()->create(); 370 $this->publicChannel = Channel::factory()->type('public')->create(); 371 $this->privateChannel = Channel::factory()->type('private')->create(); 372 $this->tourneyChannel = Channel::factory()->tourney()->create(); 373 } 374}