the browser-facing portion of osu!
at master 5.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 6namespace Tests\Controllers\Solo; 7 8use App\Models\Build; 9use App\Models\ScoreToken; 10use App\Models\Solo\Score; 11use App\Models\User; 12use LaravelRedis; 13use Tests\TestCase; 14 15class ScoresControllerTest extends TestCase 16{ 17 public function testStore() 18 { 19 $build = Build::factory()->create(['allow_ranking' => true]); 20 $scoreToken = ScoreToken::factory()->create(['build_id' => $build]); 21 22 $this->expectCountChange(fn () => Score::count(), 1); 23 $this->expectCountChange(fn () => $this->processingQueueCount(), 1); 24 $this->expectCountChange( 25 fn () => \LaravelRedis::llen($GLOBALS['cfg']['osu']['client']['token_queue']), 26 1, 27 ); 28 29 $this->withHeaders(['x-token' => static::createClientToken($build)]); 30 $this->actAsScopedUser($scoreToken->user, ['*']); 31 32 $this->json( 33 'PUT', 34 route('api.beatmaps.solo.scores.store', [ 35 'beatmap' => $scoreToken->beatmap->getKey(), 36 'token' => $scoreToken->getKey(), 37 ]), 38 [ 39 'accuracy' => 1, 40 'max_combo' => 10, 41 'mods' => [ 42 ['acronym' => 'DT'], 43 ], 44 'passed' => true, 45 'rank' => 'A', 46 'statistics' => ['Good' => 1], 47 'total_score' => 10, 48 ] 49 )->assertSuccessful() 50 ->assertJsonFragment(['build_id' => $scoreToken->build_id]); 51 52 $score = $scoreToken->fresh()->score; 53 $this->assertNotNull($score); 54 $this->assertSame(1, count($score->data->mods)); 55 } 56 57 public function testStoreCompleted() 58 { 59 $scoreToken = ScoreToken::factory()->create(); 60 $score = Score::factory()->create(['beatmap_id' => $scoreToken->beatmap_id]); 61 $scoreToken->update(['score_id' => $score->getKey()]); 62 63 $this->expectCountChange(fn () => Score::count(), 0); 64 $this->expectCountChange(fn () => $this->processingQueueCount(), 0); 65 66 $this->actAsScopedUser($scoreToken->user, ['*']); 67 68 $this->json( 69 'PUT', 70 route('api.beatmaps.solo.scores.store', [ 71 'beatmap' => $scoreToken->beatmap->getKey(), 72 'token' => $scoreToken->getKey(), 73 ]), 74 [ 75 'accuracy' => 1, 76 'max_combo' => 10, 77 'passed' => true, 78 'rank' => 'A', 79 'statistics' => ['Good' => 1], 80 'total_score' => 10, 81 ] 82 )->assertStatus(200); 83 84 $this->assertSame($score->getKey(), $scoreToken->fresh()->score_id); 85 } 86 87 public function testStoreMissingData() 88 { 89 $scoreToken = ScoreToken::factory()->create(); 90 91 $this->expectCountChange(fn () => Score::count(), 0); 92 93 $this->actAsScopedUser($scoreToken->user, ['*']); 94 95 $this->json( 96 'PUT', 97 route('api.beatmaps.solo.scores.store', [ 98 'beatmap' => $scoreToken->beatmap->getKey(), 99 'token' => $scoreToken->getKey(), 100 ]), 101 [ 102 'rank' => 'A', 103 ] 104 )->assertStatus(422); 105 } 106 107 public function testStoreUpdatedBeatmap() 108 { 109 $build = Build::factory()->create(['allow_ranking' => true]); 110 $scoreToken = ScoreToken::factory()->create(['build_id' => $build]); 111 $scoreToken->beatmap->beatmapset->update(['approved_date' => $scoreToken->created_at->addMinutes(5)]); 112 113 $this->expectCountChange(fn () => Score::count(), 0); 114 $this->expectCountChange(fn () => $this->processingQueueCount(), 0); 115 $this->expectCountChange( 116 fn () => \LaravelRedis::llen($GLOBALS['cfg']['osu']['client']['token_queue']), 117 0, 118 ); 119 120 $this->withHeaders(['x-token' => static::createClientToken($build)]); 121 $this->actAsScopedUser($scoreToken->user, ['*']); 122 123 $this->json( 124 'PUT', 125 route('api.beatmaps.solo.scores.store', [ 126 'beatmap' => $scoreToken->beatmap->getKey(), 127 'token' => $scoreToken->getKey(), 128 ]), 129 [ 130 'accuracy' => 1, 131 'max_combo' => 10, 132 'mods' => [ 133 ['acronym' => 'DT'], 134 ], 135 'passed' => true, 136 'rank' => 'A', 137 'statistics' => ['Good' => 1], 138 'total_score' => 10, 139 ] 140 )->assertStatus(422); 141 142 $score = $scoreToken->fresh()->score; 143 $this->assertNull($score); 144 } 145 146 public function testStoreWrongUser() 147 { 148 $otherUser = User::factory()->create(); 149 $scoreToken = ScoreToken::factory()->create(); 150 $this->expectCountChange(fn () => Score::count(), 0); 151 152 $this->actAsScopedUser($otherUser, ['*']); 153 154 $this->json( 155 'PUT', 156 route('api.beatmaps.solo.scores.store', [ 157 'beatmap' => $scoreToken->beatmap->getKey(), 158 'token' => $scoreToken->getKey(), 159 ]), 160 [ 161 'accuracy' => 1, 162 'max_combo' => 10, 163 'passed' => true, 164 'rank' => 'A', 165 'statistics' => ['Good' => 1], 166 'total_score' => 10, 167 ] 168 )->assertStatus(404); 169 } 170 171 public function tearDown(): void 172 { 173 parent::tearDown(); 174 175 static::createApp(); 176 LaravelRedis::del($GLOBALS['cfg']['osu']['scores']['processing_queue']); 177 } 178 179 private function processingQueueCount(): int 180 { 181 return LaravelRedis::llen($GLOBALS['cfg']['osu']['scores']['processing_queue']); 182 } 183}