the browser-facing portion of osu!
at master 8.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\Models; 9 10use App\Models\BeatmapDifficulty; 11use App\Models\BeatmapDifficultyAttrib; 12use App\Models\BeatmapFailtimes; 13use App\Models\BeatmapTag; 14use App\Models\Chat; 15use App\Models\FavouriteBeatmapset; 16use App\Models\Forum; 17use App\Models\LegacyMatch; 18use App\Models\UserAchievement; 19use App\Models\UserClient; 20use App\Models\UserCountryHistory; 21use App\Models\UserDonation; 22use App\Models\UserGroup; 23use App\Models\UserRelation; 24use App\Models\UserReplaysWatchedCount; 25use Carbon\Carbon; 26use Tests\TestCase; 27 28class ModelCompositePrimaryKeysTest extends TestCase 29{ 30 /** 31 * @dataProvider dataProviderBase 32 */ 33 public function testDelete(string $class, array $baseParams, array $item2Params, array $check) 34 { 35 [$item1, $item2] = $this->createModels($class, $baseParams, $item2Params, $check); 36 37 $this->expectCountChange(fn () => $class::count(), -1); 38 $item1->delete(); 39 $this->assertNull($item1->fresh()); 40 $this->assertNotNull($item2->fresh()); 41 } 42 43 /** 44 * @dataProvider dataProviderBase 45 */ 46 public function testFresh(string $class, array $baseParams, array $item2Params, array $check) 47 { 48 [$item1, $item2] = $this->createModels($class, $baseParams, $item2Params, $check); 49 50 $this->assertSame(':composite', $item1->getKeyName()); 51 $this->assertFalse($item1->incrementing); 52 53 $key = $check[0]; 54 $cast = $this->getCast($check[2]); 55 $this->assertSame($cast($check[1][0]), $cast($item1->fresh()->$key)); 56 $this->assertSame($cast($check[2]), $cast($item2->fresh()->$key)); 57 } 58 59 /** 60 * @dataProvider dataProviderBase 61 */ 62 public function testUpdate(string $class, array $baseParams, array $item2Params, array $check) 63 { 64 [$item1, $item2] = $this->createModels($class, $baseParams, $item2Params, $check); 65 66 $key = $check[0]; 67 $newValue = $check[1][1]; 68 $item1->update([$key => $newValue]); 69 $cast = $this->getCast($check[2]); 70 $this->assertSame($cast($newValue), $cast($item1->fresh()->$key)); 71 $this->assertSame($cast($check[2]), $cast($item2->fresh()->$key)); 72 } 73 74 public static function dataProviderBase() 75 { 76 // 0: class name 77 // 1: base params 78 // 2: base params for item 2 79 // 3: 80 // 0: check column 81 // 1: item 1 value 82 // 0: initial value 83 // 1: update value 84 // 2: item 2 value 85 return [ 86 [ 87 BeatmapDifficulty::class, 88 [ 89 'beatmap_id' => 0, 90 'mode' => 0, 91 'mods' => 0, 92 ], 93 ['beatmap_id' => 1], 94 ['diff_unified', [0.0, 10.0], 11.0], 95 ], 96 [ 97 BeatmapDifficultyAttrib::class, 98 [ 99 'attrib_id' => 0, 100 'beatmap_id' => 0, 101 'mode' => 0, 102 'mods' => 0, 103 ], 104 ['beatmap_id' => 1], 105 ['value', [0.0, 10.0], 11.0], 106 ], 107 [ 108 BeatmapFailtimes::class, 109 [ 110 'beatmap_id' => 0, 111 'type' => 'fail', 112 ], 113 ['type' => 'exit'], 114 ['p1', [0, 10], 11], 115 ], 116 [ 117 BeatmapTag::class, 118 [ 119 'beatmap_id' => 0, 120 'tag_id' => 0, 121 'user_id' => 0, 122 ], 123 ['tag_id' => 1], 124 ['updated_at', [Carbon::now()->subDays(5), Carbon::now()->subDays(1)], Carbon::now()], 125 ], 126 [ 127 Chat\UserChannel::class, 128 [ 129 'channel_id' => 0, 130 'user_id' => 0, 131 ], 132 ['channel_id' => 1], 133 ['last_read_id', [1, 2], 3], 134 ], 135 [ 136 FavouriteBeatmapset::class, 137 [ 138 'beatmapset_id' => 0, 139 'user_id' => 0, 140 ], 141 ['beatmapset_id' => 2], 142 ['dateadded', [Carbon::now()->subDays(5), Carbon::now()->subDays(1)], Carbon::now()], 143 ], 144 [ 145 Forum\AuthRole::class, 146 [ 147 'auth_option_id' => 0, 148 'role_id' => 0, 149 ], 150 ['role_id' => 1], 151 ['auth_setting', [0, 1], 2], 152 ], 153 [ 154 Forum\Authorize::class, 155 [ 156 'auth_option_id' => 0, 157 'auth_role_id' => 0, 158 'forum_id' => 0, 159 'group_id' => 0, 160 ], 161 [], 162 ['auth_setting', [0, 1], 2], 163 ], 164 [ 165 Forum\ForumTrack::class, 166 [ 167 'forum_id' => 0, 168 ], 169 [], 170 ['user_id', [0, 1], 2], 171 ], 172 [ 173 Forum\TopicTrack::class, 174 [ 175 'topic_id' => 0, 176 ], 177 [], 178 ['user_id', [0, 1], 2], 179 ], 180 [ 181 Forum\TopicWatch::class, 182 [ 183 'topic_id' => 0, 184 ], 185 [], 186 ['user_id', [0, 1], 2], 187 ], 188 [ 189 LegacyMatch\Score::class, 190 [ 191 'game_id' => 0, 192 'slot' => 0, 193 'user_id' => 0, 194 ], 195 ['slot' => 1], 196 ['score', [10, 20], 30], 197 ], 198 [ 199 UserAchievement::class, 200 [ 201 'user_id' => 0, 202 'achievement_id' => 0, 203 ], 204 ['user_id' => 1], 205 ['beatmap_id', [1, 2], 3], 206 ], 207 [ 208 UserClient::class, 209 [ 210 'osu_md5' => md5('', true), 211 'unique_md5' => md5('', true), 212 'disk_md5' => md5('', true), 213 ], 214 [], 215 ['user_id', [0, 1], 2], 216 ], 217 [ 218 UserCountryHistory::class, 219 [ 220 'user_id' => 0, 221 'year_month' => '2301', 222 'country_acronym' => 'JP', 223 ], 224 ['user_id' => 1], 225 ['count', [1, 2], 3], 226 ], 227 [ 228 UserDonation::class, 229 [ 230 'user_id' => 0, 231 'transaction_id' => '', 232 'amount' => 1, 233 ], 234 ['user_id' => 1], 235 ['length', [1, 2], 3], 236 ], 237 [ 238 UserGroup::class, 239 [ 240 'user_id' => 0, 241 'group_id' => 0, 242 ], 243 ['user_id' => 1], 244 ['group_leader', [true, false], true], 245 ], 246 [ 247 UserRelation::class, 248 [ 249 'user_id' => 0, 250 ], 251 [], 252 ['zebra_id', [1, 2], 3], 253 ], 254 [ 255 UserReplaysWatchedCount::class, 256 [ 257 'user_id' => 0, 258 'year_month' => '0101', 259 ], 260 ['user_id' => 1], 261 ['count', [0, 1], 2], 262 ], 263 ]; 264 } 265 266 private function createModels(string $class, array $baseParams, array $item2Params, array $check) 267 { 268 return [ 269 $class::create(array_merge($baseParams, [$check[0] => $check[1][0]])), 270 $class::create(array_merge($baseParams, $item2Params, [$check[0] => $check[2]])), 271 ]; 272 } 273 274 private function getCast(mixed $value): callable 275 { 276 return $value instanceof Carbon 277 ? fn (Carbon $value): string => json_time($value) 278 : fn (mixed $value): mixed => $value; 279 } 280}