the browser-facing portion of osu!
at master 5.5 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\Models\Beatmap; 11use App\Models\Build; 12use App\Models\ScoreToken; 13use App\Models\User; 14use Tests\TestCase; 15 16class ScoreTokensControllerTest extends TestCase 17{ 18 private Build $build; 19 private User $user; 20 21 /** 22 * @dataProvider dataProviderForTestStore 23 */ 24 public function testStore(string $beatmapState, int $status): void 25 { 26 $beatmap = Beatmap::factory()->$beatmapState()->create(); 27 28 $routeParams = [ 29 'beatmap' => $beatmap->getKey(), 30 'ruleset_id' => $beatmap->playmode, 31 ]; 32 $bodyParams = ['beatmap_hash' => $beatmap->checksum]; 33 $this->withHeaders(['x-token' => static::createClientToken($this->build)]); 34 35 $this->expectCountChange(fn () => ScoreToken::count(), $status >= 200 && $status < 300 ? 1 : 0); 36 37 $this->actAsScopedUser($this->user, ['*']); 38 $this->json( 39 'POST', 40 route('api.beatmaps.solo.score-tokens.store', $routeParams), 41 $bodyParams 42 )->assertStatus($status); 43 } 44 45 /** 46 * @dataProvider dataProviderForTestStoreInvalidParameter 47 */ 48 public function testStoreInvalidParameter(string $paramKey, ?string $paramValue, int $status, string $errorMessage): void 49 { 50 $origClientCheckVersion = $GLOBALS['cfg']['osu']['client']['check_version']; 51 config_set('osu.client.check_version', true); 52 $beatmap = Beatmap::factory()->ranked()->create(); 53 54 $this->actAsScopedUser($this->user, ['*']); 55 56 $params = [ 57 'beatmap' => $beatmap->getKey(), 58 'ruleset_id' => $beatmap->playmode, 59 'beatmap_hash' => $beatmap->checksum, 60 ]; 61 $this->withHeaders([ 62 'x-token' => $paramKey === 'client_token' 63 ? $paramValue 64 : static::createClientToken($this->build), 65 ]); 66 67 if ($paramKey !== 'client_token') { 68 $params[$paramKey] = $paramValue; 69 } 70 71 $routeParams = [ 72 'beatmap' => $params['beatmap'], 73 'ruleset_id' => $params['ruleset_id'], 74 ]; 75 $bodyParams = [ 76 'beatmap_hash' => $params['beatmap_hash'], 77 ]; 78 79 $this->expectCountChange(fn () => ScoreToken::count(), 0); 80 81 $this->json( 82 'POST', 83 route('api.beatmaps.solo.score-tokens.store', $routeParams), 84 $bodyParams 85 )->assertStatus($status) 86 ->assertJson([ 87 'error' => $errorMessage, 88 ]); 89 90 config_set('osu.client.check_version', $origClientCheckVersion); 91 } 92 93 public function testStoreValidRulesetConversion(): void 94 { 95 $beatmap = Beatmap::factory()->create([ 96 'playmode' => 0, 97 ]); 98 99 $routeParams = [ 100 'beatmap' => $beatmap->getKey(), 101 'ruleset_id' => 1, 102 ]; 103 $bodyParams = ['beatmap_hash' => $beatmap->checksum]; 104 $this->withHeaders(['x-token' => static::createClientToken($this->build)]); 105 106 $this->expectCountChange(fn () => ScoreToken::count(), 1); 107 108 $this->actAsScopedUser($this->user, ['*']); 109 $this->json( 110 'POST', 111 route('api.beatmaps.solo.score-tokens.store', $routeParams), 112 $bodyParams 113 )->assertStatus(200); 114 } 115 116 public function testStoreInvalidRulesetConversion(): void 117 { 118 $beatmap = Beatmap::factory()->create([ 119 'playmode' => 2, 120 ]); 121 122 $routeParams = [ 123 'beatmap' => $beatmap->getKey(), 124 'ruleset_id' => 1, 125 ]; 126 $bodyParams = ['beatmap_hash' => $beatmap->checksum]; 127 $this->withHeaders(['x-token' => static::createClientToken($this->build)]); 128 129 $this->expectCountChange(fn () => ScoreToken::count(), 0); 130 131 $this->actAsScopedUser($this->user, ['*']); 132 $this->json( 133 'POST', 134 route('api.beatmaps.solo.score-tokens.store', $routeParams), 135 $bodyParams 136 )->assertStatus(422) 137 ->assertJson([ 138 'error' => 'invalid ruleset_id', 139 ]); 140 } 141 142 public static function dataProviderForTestStore(): array 143 { 144 return [ 145 ['deleted', 404], 146 ['deletedBeatmapset', 404], 147 ['inactive', 404], 148 ['ranked', 200], 149 ['wip', 200], 150 ]; 151 } 152 153 public static function dataProviderForTestStoreInvalidParameter(): array 154 { 155 return [ 156 'invalid client token' => ['client_token', md5('invalid_'), 422, 'invalid client hash'], 157 'missing client token' => ['client_token', null, 422, 'missing token header'], 158 159 'invalid ruleset id' => ['ruleset_id', '5', 422, 'invalid ruleset_id'], 160 'missing ruleset id' => ['ruleset_id', null, 422, 'missing ruleset_id'], 161 162 'invalid beatmap hash' => ['beatmap_hash', 'xxx', 422, 'invalid or missing beatmap_hash'], 163 'missing beatmap hash' => ['beatmap_hash', null, 422, 'invalid or missing beatmap_hash'], 164 ]; 165 } 166 167 protected function setUp(): void 168 { 169 parent::setUp(); 170 171 $this->user = User::factory()->create(); 172 $this->build = Build::factory()->create(['allow_ranking' => true]); 173 } 174}