the browser-facing portion of osu!
at master 5.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\Models; 9 10use App\Exceptions\InvariantException; 11use App\Models\Beatmap; 12use App\Models\Beatmapset; 13use App\Models\Contest; 14use App\Models\ContestEntry; 15use App\Models\Multiplayer\PlaylistItem; 16use App\Models\Multiplayer\Room; 17use App\Models\Multiplayer\ScoreLink as MultiplayerScoreLink; 18use App\Models\Multiplayer\UserScoreAggregate; 19use App\Models\User; 20use Carbon\Carbon; 21use Tests\TestCase; 22 23class ContestTest extends TestCase 24{ 25 /** 26 * @dataProvider dataProviderForTestAssertVoteRequirementPlaylistBeatmapsets 27 */ 28 public function testAssertVoteRequirementPlaylistBeatmapsets( 29 bool $loggedIn, 30 bool $played, 31 bool $passed, 32 ?bool $mustPass, 33 bool $canVote 34 ): void { 35 $beatmapsets = Beatmapset::factory()->count(5)->create(); 36 $beatmaps = []; 37 foreach ($beatmapsets as $beatmapset) { 38 $beatmapsetId = $beatmapset->getKey(); 39 for ($i = 0; $i < 2; $i++) { 40 $beatmaps[] = Beatmap::factory()->create(['beatmapset_id' => $beatmapsetId]); 41 } 42 } 43 // extra beatmap 44 Beatmap::factory()->create(); 45 46 $rooms = Room::factory()->count(2)->create(); 47 foreach ($rooms as $i => $room) { 48 foreach ($beatmapsets as $beatmapset) { 49 $playlistItems[] = PlaylistItem::factory()->create([ 50 'room_id' => $room, 51 'beatmap_id' => $beatmapset->beatmaps[$i], 52 ]); 53 } 54 } 55 $contest = Contest::factory()->create([ 56 'extra_options' => [ 57 'requirement' => [ 58 'must_pass' => $mustPass, 59 'name' => 'playlist_beatmapsets', 60 'room_ids' => array_column($rooms->all(), 'id'), 61 ], 62 ], 63 ]); 64 $entries = ContestEntry::factory()->count(2)->create(['contest_id' => $contest->getKey()]); 65 66 $user = $loggedIn ? User::factory()->create() : null; 67 68 if ($loggedIn && $played) { 69 $userId = $user->getKey(); 70 $endedAt = json_time(Carbon::now()); 71 foreach ($beatmapsets as $beatmapset) { 72 $room = array_rand_val($rooms); 73 $playlistItem = $room 74 ->playlist() 75 ->whereIn('beatmap_id', array_column($beatmapset->beatmaps->all(), 'beatmap_id')) 76 ->first(); 77 78 MultiplayerScoreLink::factory()->state([ 79 'playlist_item_id' => $playlistItem, 80 'user_id' => $userId, 81 ])->completed([ 82 'ended_at' => $endedAt, 83 'passed' => $passed, 84 ])->create(); 85 } 86 foreach ($rooms as $room) { 87 UserScoreAggregate::lookupOrDefault($user, $room)->recalculate(); 88 } 89 } 90 91 if (!$canVote) { 92 $this->expectException(InvariantException::class); 93 } 94 95 $contest->assertVoteRequirement($user); 96 97 if ($canVote) { 98 $this->assertTrue(true, 'no exception'); 99 } 100 } 101 102 public function testAssertVoteRequirementNoRequirement(): void 103 { 104 $contest = Contest::factory()->create(); 105 $entry = ContestEntry::factory()->create(['contest_id' => $contest->getKey()]); 106 $user = User::factory()->create(); 107 108 $contest->assertVoteRequirement($user, $entry); 109 $this->assertTrue(true, 'no exception'); 110 } 111 112 /** 113 * @dataProvider dataProviderForTestShowEntryUser 114 */ 115 public function testShowEntryUser(bool $showVotes, ?bool $showEntryUserOption, bool $result): void 116 { 117 $extraOptions = $showEntryUserOption === null 118 ? null 119 : ['show_entry_user' => $showEntryUserOption]; 120 $contest = Contest::factory()->create([ 121 'show_votes' => $showVotes, 122 'extra_options' => $extraOptions, 123 ]); 124 $this->assertSame($result, $contest->showEntryUser()); 125 } 126 127 public static function dataProviderForTestAssertVoteRequirementPlaylistBeatmapsets(): array 128 { 129 return [ 130 // when passing is required 131 [true, true, true, true, true], 132 [true, true, false, true, false], 133 [true, false, false, true, false], 134 [false, false, false, true, false], 135 // when passing is not specified (default required) 136 [true, true, true, null, true], 137 [true, true, false, null, false], 138 [true, false, false, null, false], 139 [false, false, false, null, false], 140 // when passing is not required 141 [true, true, true, false, true], 142 [true, true, false, false, true], 143 [true, false, false, false, false], 144 [false, false, false, false, false], 145 ]; 146 } 147 148 public static function dataProviderForTestShowEntryUser(): array 149 { 150 return [ 151 [false, null, false], 152 [true, null, true], 153 [false, false, false], 154 [true, false, true], 155 [false, true, true], 156 [true, true, true], 157 ]; 158 } 159}