From cb5c3caad8adb098190a42ef2bc4f52fb3ba7826 Mon Sep 17 00:00:00 2001 From: Refringe Date: Thu, 30 Jan 2025 00:23:55 -0500 Subject: [PATCH] Rector Changes --- app/Actions/Fortify/CreateNewUser.php | 2 + .../Fortify/PasswordValidationRules.php | 2 + app/Actions/Fortify/ResetUserPassword.php | 2 + app/Actions/Fortify/UpdateUserPassword.php | 2 + .../Fortify/UpdateUserProfileInformation.php | 2 + app/Actions/Jetstream/DeleteUser.php | 2 + app/Console/Commands/ImportHubCommand.php | 2 + .../Commands/ResolveVersionsCommand.php | 2 + app/Console/Commands/SearchSyncCommand.php | 8 +- .../Commands/SptVersionModCountsCommand.php | 2 + .../Commands/UpdateModDownloadsCommand.php | 2 + app/Console/Commands/UploadAssetsCommand.php | 2 + .../CircularDependencyException.php | 2 + .../InvalidVersionNumberException.php | 2 + app/Filament/Resources/UserResource.php | 57 ++++---- .../UserResource/Pages/CreateUser.php | 2 + .../Resources/UserResource/Pages/EditUser.php | 6 +- .../UserResource/Pages/ListUsers.php | 6 +- app/Http/Controllers/Api/AuthController.php | 12 +- app/Http/Controllers/Api/V0/ApiController.php | 4 +- app/Http/Controllers/Api/V0/ModController.php | 6 +- .../Controllers/Api/V0/UsersController.php | 6 +- app/Http/Controllers/Controller.php | 2 + app/Http/Controllers/ModController.php | 12 +- app/Http/Controllers/ModVersionController.php | 2 + app/Http/Controllers/SocialiteController.php | 6 +- app/Http/Controllers/UserController.php | 4 +- app/Http/Filters/ModFilter.php | 19 ++- app/Http/Filters/V1/ModFilter.php | 2 + app/Http/Filters/V1/QueryFilter.php | 17 ++- app/Http/Filters/V1/UserFilter.php | 2 + app/Http/Requests/Api/LoginUserRequest.php | 2 + app/Http/Requests/Api/V0/StoreModRequest.php | 2 + app/Http/Requests/Api/V0/StoreUserRequest.php | 2 + app/Http/Requests/Api/V0/UpdateModRequest.php | 2 + .../Requests/Api/V0/UpdateUserRequest.php | 2 + app/Http/Requests/ModRequest.php | 2 + app/Http/Resources/Api/V0/LicenseResource.php | 4 + app/Http/Resources/Api/V0/ModResource.php | 14 +- .../Resources/Api/V0/ModVersionResource.php | 8 +- app/Http/Resources/Api/V0/UserResource.php | 4 + .../Resources/Api/V0/UserRoleResource.php | 4 + app/Http/Resources/LicenseResource.php | 4 + app/Http/Resources/ModResource.php | 4 + app/Http/Resources/ModVersionResource.php | 4 + app/Http/Resources/SptVersionResource.php | 4 + .../Import/DataTransferObjects/HubUser.php | 2 + app/Jobs/Import/ImportHubDataJob.php | 122 +++++++++--------- app/Jobs/ResolveDependenciesJob.php | 7 +- app/Jobs/ResolveSptVersionsJob.php | 7 +- app/Jobs/SptVersionModCountsJob.php | 9 +- app/Jobs/UpdateModDownloadsJob.php | 9 +- app/Livewire/GlobalSearch.php | 6 +- app/Livewire/Mod/Listing.php | 36 +++--- .../Profile/ManageOAuthConnections.php | 2 + app/Livewire/Profile/UpdatePasswordForm.php | 6 +- app/Livewire/Profile/UpdateProfileForm.php | 10 +- app/Livewire/User/FollowButtons.php | 2 + app/Livewire/User/FollowCard.php | 2 + app/Livewire/User/FollowCards.php | 2 + app/Models/License.php | 2 + app/Models/Mod.php | 26 ++-- app/Models/ModDependency.php | 2 + app/Models/ModResolvedDependency.php | 2 + app/Models/ModVersion.php | 30 +++-- app/Models/ModVersionSptVersion.php | 2 + app/Models/OAuthConnection.php | 2 + app/Models/Scopes/DisabledScope.php | 2 + app/Models/Scopes/PublishedScope.php | 2 + app/Models/SptVersion.php | 52 ++++---- app/Models/User.php | 13 +- app/Models/UserRole.php | 2 + app/Notifications/ResetPassword.php | 2 + app/Notifications/VerifyEmail.php | 2 + app/Observers/ModDependencyObserver.php | 9 +- app/Observers/ModObserver.php | 10 +- app/Observers/ModVersionObserver.php | 14 +- app/Observers/SptVersionObserver.php | 9 +- app/Policies/ModPolicy.php | 2 + app/Policies/ModVersionPolicy.php | 2 + app/Policies/OAuthConnectionPolicy.php | 2 + app/Policies/UserPolicy.php | 2 + app/Providers/AppServiceProvider.php | 29 +++-- app/Providers/Filament/AdminPanelProvider.php | 13 +- app/Providers/FortifyServiceProvider.php | 8 +- app/Providers/HorizonServiceProvider.php | 9 +- app/Providers/JetstreamServiceProvider.php | 4 + app/Services/DependencyVersionService.php | 6 +- app/Services/SptVersionService.php | 2 + app/Support/Version.php | 10 +- app/Traits/ApiResponses.php | 3 + app/Traits/HasCoverPhoto.php | 8 +- app/Traits/V1/FilterMethods.php | 2 + app/View/Components/AppLayout.php | 2 + app/View/Components/GuestLayout.php | 2 + app/View/Components/HomepageMods.php | 64 +++++---- bootstrap/app.php | 8 +- bootstrap/providers.php | 21 ++- composer.json | 2 +- composer.lock | 122 +++++++++--------- config/app.php | 7 +- config/auth.php | 6 +- config/ban.php | 6 +- config/cache.php | 2 + config/database.php | 2 + config/filament.php | 2 + config/filesystems.php | 2 + config/fortify.php | 2 + config/horizon.php | 2 + config/jetstream.php | 2 + config/livewire.php | 2 + config/logging.php | 4 +- config/mail.php | 2 + config/octane.php | 5 +- config/pulse.php | 35 +++-- config/purify.php | 5 +- config/queue.php | 2 + config/sanctum.php | 13 +- config/scout.php | 2 + config/scribe.php | 68 ++++++---- config/services.php | 2 + config/session.php | 2 + lang/vendor/nova/en/validation.php | 2 + public/index.php | 2 + rector.php | 6 +- routes/api.php | 4 +- routes/api_v0.php | 4 +- routes/console.php | 2 + routes/web.php | 22 ++-- tests/Feature/Api/V1/ModFilterTest.php | 34 ++--- tests/Feature/Mod/ModDependencyTest.php | 44 ++++--- tests/Feature/Mod/ModFilterTest.php | 16 ++- tests/Feature/Mod/ModTest.php | 10 +- tests/Feature/Mod/ModVersionTest.php | 33 ++--- tests/Feature/Mod/SptVersionTest.php | 8 +- .../Feature/User/ApiTokenPermissionsTest.php | 8 +- tests/Feature/User/AuthenticationTest.php | 12 +- tests/Feature/User/BrowserSessionsTest.php | 4 +- tests/Feature/User/CreateApiTokenTest.php | 8 +- tests/Feature/User/DeleteAccountTest.php | 14 +- tests/Feature/User/DeleteApiTokenTest.php | 8 +- tests/Feature/User/EmailVerificationTest.php | 22 ++-- tests/Feature/User/FollowTest.php | 20 +-- tests/Feature/User/OAuthAccountTest.php | 50 +++---- .../Feature/User/PasswordConfirmationTest.php | 8 +- tests/Feature/User/PasswordResetTest.php | 30 ++--- tests/Feature/User/ProfileInformationTest.php | 12 +- tests/Feature/User/RegistrationTest.php | 20 ++- .../TwoFactorAuthenticationSettingsTest.php | 20 ++- tests/Feature/User/UpdatePasswordTest.php | 8 +- tests/Pest.php | 8 +- tests/TestCase.php | 2 + tests/Unit/ExampleTest.php | 4 +- 153 files changed, 961 insertions(+), 648 deletions(-) diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php index 057f25c..18248f6 100644 --- a/app/Actions/Fortify/CreateNewUser.php +++ b/app/Actions/Fortify/CreateNewUser.php @@ -1,5 +1,7 @@ '\App\Models\Mod']); - Artisan::call('scout:import', ['model' => '\App\Models\User']); + Artisan::call('scout:import', ['model' => Mod::class]); + Artisan::call('scout:import', ['model' => User::class]); $this->info('The search synchronisation jobs have been added to the queue'); } diff --git a/app/Console/Commands/SptVersionModCountsCommand.php b/app/Console/Commands/SptVersionModCountsCommand.php index d339a54..4a0204c 100644 --- a/app/Console/Commands/SptVersionModCountsCommand.php +++ b/app/Console/Commands/SptVersionModCountsCommand.php @@ -1,5 +1,7 @@ schema([ - Forms\Components\TextInput::make('name') + TextInput::make('name') ->required() ->maxLength(255), - Forms\Components\TextInput::make('email') + TextInput::make('email') ->email() ->required() ->maxLength(255), - Forms\Components\DateTimePicker::make('email_verified_at'), - Forms\Components\TextInput::make('password') + DateTimePicker::make('email_verified_at'), + TextInput::make('password') ->password() ->required() ->maxLength(255), - Forms\Components\TextInput::make('user_role_id') + TextInput::make('user_role_id') ->numeric(), - Forms\Components\TextInput::make('profile_photo_path') + TextInput::make('profile_photo_path') ->maxLength(2048), - Forms\Components\DateTimePicker::make('created_at'), - Forms\Components\DateTimePicker::make('updated_at'), + DateTimePicker::make('created_at'), + DateTimePicker::make('updated_at'), ]); } + #[Override] public static function table(Table $table): Table { return $table ->columns([ - Tables\Columns\TextColumn::make('name') + TextColumn::make('name') ->searchable(), - Tables\Columns\TextColumn::make('email') + TextColumn::make('email') ->searchable(), - Tables\Columns\TextColumn::make('role.name') + TextColumn::make('role.name') ->sortable(), - Tables\Columns\TextColumn::make('email_verified_at') + TextColumn::make('email_verified_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), - Tables\Columns\TextColumn::make('created_at') + TextColumn::make('created_at') ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), @@ -64,15 +75,16 @@ class UserResource extends Resource // ]) ->actions([ - Tables\Actions\EditAction::make(), + EditAction::make(), ]) ->bulkActions([ - Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), + BulkActionGroup::make([ + DeleteBulkAction::make(), ]), ]); } + #[Override] public static function getRelations(): array { return [ @@ -80,12 +92,13 @@ class UserResource extends Resource ]; } + #[Override] public static function getPages(): array { return [ - 'index' => Pages\ListUsers::route('/'), - 'create' => Pages\CreateUser::route('/create'), - 'edit' => Pages\EditUser::route('/{record}/edit'), + 'index' => ListUsers::route('/'), + 'create' => CreateUser::route('/create'), + 'edit' => EditUser::route('/{record}/edit'), ]; } } diff --git a/app/Filament/Resources/UserResource/Pages/CreateUser.php b/app/Filament/Resources/UserResource/Pages/CreateUser.php index 78a3894..72b81bb 100644 --- a/app/Filament/Resources/UserResource/Pages/CreateUser.php +++ b/app/Filament/Resources/UserResource/Pages/CreateUser.php @@ -1,5 +1,7 @@ 'authenticated', 'data' => ['token' => 'YOUR_API_KEY'], 'status' => 200], status: 200, description: 'Authenticated successfully')] #[Response(['message' => 'invalid credentials', 'status' => 401], status: 401, description: 'Invalid credentials')] #[ResponseField('token', description: 'The newly created read-only API token to use for future authenticated requests.')] - public function login(LoginUserRequest $request): JsonResponse + public function login(LoginUserRequest $loginUserRequest): JsonResponse { - $request->validated($request->all()); + $loginUserRequest->validated($loginUserRequest->all()); - if (! Auth::attempt($request->only('email', 'password'))) { + if (! Auth::attempt($loginUserRequest->only('email', 'password'))) { return $this->error(__('invalid credentials'), 401); } - $user = User::firstWhere('email', $request->email); - $tokenName = $request->token_name ?? __('Dynamic API Token'); + $user = User::firstWhere('email', $loginUserRequest->email); + $tokenName = $loginUserRequest->token_name ?? __('Dynamic API Token'); return $this->success(__('authenticated'), [ // Only allowing the 'read' scope to be dynamically created. Can revisit later when writes are possible. diff --git a/app/Http/Controllers/Api/V0/ApiController.php b/app/Http/Controllers/Api/V0/ApiController.php index f8b8860..760b876 100644 --- a/app/Http/Controllers/Api/V0/ApiController.php +++ b/app/Http/Controllers/Api/V0/ApiController.php @@ -1,5 +1,7 @@ get('include'); - } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) { + } catch (NotFoundExceptionInterface|ContainerExceptionInterface) { return false; } diff --git a/app/Http/Controllers/Api/V0/ModController.php b/app/Http/Controllers/Api/V0/ModController.php index b0f738a..6fd497a 100644 --- a/app/Http/Controllers/Api/V0/ModController.php +++ b/app/Http/Controllers/Api/V0/ModController.php @@ -1,5 +1,7 @@ paginate()); + return ModResource::collection(Mod::filter($modFilter)->paginate()); } /** diff --git a/app/Http/Controllers/Api/V0/UsersController.php b/app/Http/Controllers/Api/V0/UsersController.php index 69a4b56..877b19a 100644 --- a/app/Http/Controllers/Api/V0/UsersController.php +++ b/app/Http/Controllers/Api/V0/UsersController.php @@ -1,5 +1,7 @@ paginate()); + return UserResource::collection(User::filter($userFilter)->paginate()); } /** diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 8677cd5..e2af3d2 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -1,5 +1,7 @@ authorize('create', Mod::class); - return new ModResource(Mod::create($request->validated())); + return new ModResource(Mod::create($modRequest->validated())); } public function show(int $modId, string $slug): View @@ -43,14 +45,14 @@ class ModController extends Controller $this->authorize('view', $mod); - return view('mod.show', compact(['mod'])); + return view('mod.show', ['mod' => $mod]); } - public function update(ModRequest $request, Mod $mod): ModResource + public function update(ModRequest $modRequest, Mod $mod): ModResource { $this->authorize('update', $mod); - $mod->update($request->validated()); + $mod->update($modRequest->validated()); return new ModResource($mod); } diff --git a/app/Http/Controllers/ModVersionController.php b/app/Http/Controllers/ModVersionController.php index 090c0d7..b75b4de 100644 --- a/app/Http/Controllers/ModVersionController.php +++ b/app/Http/Controllers/ModVersionController.php @@ -1,5 +1,7 @@ user(); - } catch (\Exception $e) { + } catch (Exception) { return redirect()->route('login')->withErrors('Unable to login using '.$provider.'. Please try again.'); } @@ -86,6 +89,7 @@ class SocialiteController extends Controller while (User::whereName($username.$random)->exists()) { $random = '-'.Str::random(5); } + $username .= $random; // The user has not connected their account with this OAuth provider before, so a new connection needs to be diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 97eed7c..bbb4cc3 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -1,5 +1,7 @@ $user, 'mods' => $mods]); } } diff --git a/app/Http/Filters/ModFilter.php b/app/Http/Filters/ModFilter.php index ec3f493..48c626c 100644 --- a/app/Http/Filters/ModFilter.php +++ b/app/Http/Filters/ModFilter.php @@ -1,5 +1,7 @@ filters = $filters; $this->builder = $this->baseQuery(); } @@ -34,7 +33,7 @@ class ModFilter { return Mod::query() ->select('mods.*') - ->whereExists(function ($query) { + ->whereExists(function ($query): void { $query->select(DB::raw(1)) ->from('mod_versions') ->join('mod_version_spt_version', 'mod_versions.id', '=', 'mod_version_spt_version.mod_version_id') @@ -54,7 +53,7 @@ class ModFilter */ private function query(string $term): Builder { - return $this->builder->whereLike('mods.name', "%{$term}%"); + return $this->builder->whereLike('mods.name', sprintf('%%%s%%', $term)); } /** @@ -100,7 +99,7 @@ class ModFilter */ private function sptVersions(array $versions): Builder { - return $this->builder->whereExists(function ($query) use ($versions) { + return $this->builder->whereExists(function ($query) use ($versions): void { $query->select(DB::raw(1)) ->from('mod_versions') ->join('mod_version_spt_version', 'mod_versions.id', '=', 'mod_version_spt_version.mod_version_id') diff --git a/app/Http/Filters/V1/ModFilter.php b/app/Http/Filters/V1/ModFilter.php index 8c5ffff..062065b 100644 --- a/app/Http/Filters/V1/ModFilter.php +++ b/app/Http/Filters/V1/ModFilter.php @@ -1,5 +1,7 @@ request = $request; - } + public function __construct( + /** + * The request instance. + */ + protected Request $request + ) {} /** * Iterate over each of the filter options and call the appropriate method if it exists. diff --git a/app/Http/Filters/V1/UserFilter.php b/app/Http/Filters/V1/UserFilter.php index 18b5ecb..e4a9322 100644 --- a/app/Http/Filters/V1/UserFilter.php +++ b/app/Http/Filters/V1/UserFilter.php @@ -1,5 +1,7 @@ load(['users', 'versions', 'license']); @@ -39,7 +43,7 @@ class ModResource extends JsonResource 'published_at' => $this->published_at, ], 'relationships' => [ - 'users' => $this->users->map(fn ($user) => [ + 'users' => $this->users->map(fn ($user): array => [ 'data' => [ 'type' => 'user', 'id' => $user->id, @@ -48,7 +52,7 @@ class ModResource extends JsonResource 'self' => $user->profileUrl(), ], ])->toArray(), - 'versions' => $this->versions->map(fn ($version) => [ + 'versions' => $this->versions->map(fn ($version): array => [ 'data' => [ 'type' => 'version', 'id' => $version->id, @@ -70,11 +74,11 @@ class ModResource extends JsonResource 'includes' => $this->when( ApiController::shouldInclude(['users', 'license', 'versions']), fn () => collect([ - 'users' => $this->users->map(fn ($user) => new UserResource($user)), + 'users' => $this->users->map(fn ($user): UserResource => new UserResource($user)), 'license' => new LicenseResource($this->license), - 'versions' => $this->versions->map(fn ($version) => new ModVersionResource($version)), + 'versions' => $this->versions->map(fn ($version): ModVersionResource => new ModVersionResource($version)), ]) - ->filter(fn ($value, $key) => ApiController::shouldInclude($key)) + ->filter(fn ($value, $key): bool => ApiController::shouldInclude($key)) ->flatten(1) ->values() ), diff --git a/app/Http/Resources/Api/V0/ModVersionResource.php b/app/Http/Resources/Api/V0/ModVersionResource.php index 3a5037f..58aec9c 100644 --- a/app/Http/Resources/Api/V0/ModVersionResource.php +++ b/app/Http/Resources/Api/V0/ModVersionResource.php @@ -1,10 +1,13 @@ $this->version, // TODO: This should only be visible on the mod version show route(?) which doesn't exist. - //'description' => $this->when( + // 'description' => $this->when( // $request->routeIs('api.v0.modversion.show'), // $this->description - //), + // ), 'link' => $this->downloadUrl(absolute: true), 'virus_total_link' => $this->virus_total_link, diff --git a/app/Http/Resources/Api/V0/UserResource.php b/app/Http/Resources/Api/V0/UserResource.php index 1b26c64..d2ac02b 100644 --- a/app/Http/Resources/Api/V0/UserResource.php +++ b/app/Http/Resources/Api/V0/UserResource.php @@ -1,11 +1,14 @@ load('role'); diff --git a/app/Http/Resources/Api/V0/UserRoleResource.php b/app/Http/Resources/Api/V0/UserRoleResource.php index 0932611..ae8bab8 100644 --- a/app/Http/Resources/Api/V0/UserRoleResource.php +++ b/app/Http/Resources/Api/V0/UserRoleResource.php @@ -1,10 +1,13 @@ table('wcf1_user_avatar') ->orderBy('avatarID') - ->chunk(200, function ($avatars) { + ->chunk(200, function ($avatars): void { $insertData = []; foreach ($avatars as $avatar) { $insertData[] = [ @@ -97,7 +102,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_user_avatar')->insert($insertData); } }); @@ -117,7 +122,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue DB::connection('mysql_hub') ->table('wcf1_user_option_value') ->orderBy('userID') - ->chunk(200, function ($options) { + ->chunk(200, function ($options): void { $insertData = []; foreach ($options as $option) { $insertData[] = [ @@ -126,7 +131,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_user_options_values')->insert($insertData); } }); @@ -146,7 +151,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue DB::connection('mysql_hub') ->table('filebase1_file_author') ->orderBy('fileID') - ->chunk(200, function ($relationships) { + ->chunk(200, function ($relationships): void { $insertData = []; foreach ($relationships as $relationship) { $insertData[] = [ @@ -155,7 +160,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_file_author')->insert($insertData); } }); @@ -176,7 +181,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue DB::connection('mysql_hub') ->table('filebase1_file_option_value') ->orderBy('fileID') - ->chunk(200, function ($options) { + ->chunk(200, function ($options): void { $insertData = []; foreach ($options as $option) { $insertData[] = [ @@ -186,7 +191,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_file_option_values')->insert($insertData); } }); @@ -208,7 +213,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue DB::connection('mysql_hub') ->table('filebase1_file_content') ->orderBy('fileID') - ->chunk(200, function ($contents) { + ->chunk(200, function ($contents): void { $insertData = []; foreach ($contents as $content) { $insertData[] = [ @@ -219,7 +224,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_file_content')->insert($insertData); } }); @@ -240,7 +245,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ->table('wcf1_label_object') ->where('objectTypeID', 387) ->orderBy('labelID') - ->chunk(200, function ($options) { + ->chunk(200, function ($options): void { $insertData = []; foreach ($options as $option) { $insertData[] = [ @@ -249,7 +254,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_file_version_labels')->insert($insertData); } }); @@ -269,7 +274,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue DB::connection('mysql_hub') ->table('filebase1_file_version_content') ->orderBy('versionID') - ->chunk(200, function ($options) { + ->chunk(200, function ($options): void { $insertData = []; foreach ($options as $option) { $insertData[] = [ @@ -278,7 +283,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_file_version_content')->insert($insertData); } }); @@ -297,7 +302,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ->table('wcf1_label') ->where('groupID', 1) ->orderBy('labelID') - ->chunk(100, function (Collection $versions) { + ->chunk(100, function (Collection $versions): void { $insertData = []; foreach ($versions as $version) { $insertData[] = [ @@ -307,7 +312,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if ($insertData) { + if ($insertData !== []) { DB::table('temp_spt_version_tags')->insert($insertData); } }); @@ -340,9 +345,10 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue 'r.rankTitle', ) ->leftJoin('wcf1_user_rank as r', 'u.rankID', '=', 'r.rankID') - ->chunkById(250, function (Collection $users) use ($curl) { - $userData = $bannedUsers = $userRanks = []; - + ->chunkById(250, function (Collection $users) use ($curl): void { + $userData = []; + $bannedUsers = []; + $userRanks = []; foreach ($users as $user) { $hubUser = new HubUser( $user->userID, @@ -384,16 +390,16 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue /** * Build an array of user data ready to be inserted into the local database. */ - protected function collectUserData(CurlHandle $curl, HubUser $hubUser): array + protected function collectUserData(CurlHandle $curlHandle, HubUser $hubUser): array { return [ - 'hub_id' => (int) $hubUser->userID, + 'hub_id' => $hubUser->userID, 'name' => $hubUser->username, 'email' => Str::lower($hubUser->email), 'password' => $this->cleanPasswordHash($hubUser->password), 'about' => $this->fetchUserAbout($hubUser->userID), - 'profile_photo_path' => $this->fetchUserAvatar($curl, $hubUser), - 'cover_photo_path' => $this->fetchUserCoverPhoto($curl, $hubUser), + 'profile_photo_path' => $this->fetchUserAvatar($curlHandle, $hubUser), + 'cover_photo_path' => $this->fetchUserCoverPhoto($curlHandle, $hubUser), 'created_at' => $this->cleanRegistrationDate($hubUser->registrationDate), 'updated_at' => now('UTC')->toDateTimeString(), ]; @@ -432,16 +438,16 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue { // Alright, hear me out... Shut up. - $converter = new HtmlConverter; + $htmlConverter = new HtmlConverter; $clean = Purify::clean($dirty); - return $converter->convert($clean); + return $htmlConverter->convert($clean); } /** * Fetch the user avatar from the Hub and store it anew. */ - protected function fetchUserAvatar(CurlHandle $curl, HubUser $hubUser): string + protected function fetchUserAvatar(CurlHandle $curlHandle, HubUser $hubUser): string { // Fetch the user's avatar data from the temporary table. $avatar = DB::table('temp_user_avatar')->where('userID', $hubUser->userID)->first(); @@ -450,18 +456,18 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue return ''; } - $hashShort = substr($avatar->fileHash, 0, 2); + $hashShort = substr((string) $avatar->fileHash, 0, 2); $fileName = $avatar->fileHash.'.'.$avatar->avatarExtension; $hubUrl = 'https://hub.sp-tarkov.com/images/avatars/'.$hashShort.'/'.$avatar->avatarID.'-'.$fileName; $relativePath = User::profilePhotoStoragePath().'/'.$fileName; - return $this->fetchAndStoreImage($curl, $hubUrl, $relativePath); + return $this->fetchAndStoreImage($curlHandle, $hubUrl, $relativePath); } /** * Fetch and store an image from the Hub. */ - protected function fetchAndStoreImage(CurlHandle $curl, string $hubUrl, string $relativePath): string + protected function fetchAndStoreImage(CurlHandle $curlHandle, string $hubUrl, string $relativePath): string { // Determine the disk to use based on the environment. $disk = match (config('app.env')) { @@ -475,11 +481,11 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue } // Download the image using the cURL handler. - curl_setopt($curl, CURLOPT_URL, $hubUrl); - $image = curl_exec($curl); + curl_setopt($curlHandle, CURLOPT_URL, $hubUrl); + $image = curl_exec($curlHandle); if ($image === false) { - Log::error('There was an error attempting to download the image. cURL error: '.curl_error($curl)); + Log::error('There was an error attempting to download the image. cURL error: '.curl_error($curlHandle)); return ''; } @@ -493,9 +499,9 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue /** * Fetch the user avatar from the Hub and store it anew. */ - protected function fetchUserCoverPhoto(CurlHandle $curl, HubUser $hubUser): string + protected function fetchUserCoverPhoto(CurlHandle $curlHandle, HubUser $hubUser): string { - if (empty($hubUser->coverPhotoHash) || empty($hubUser->coverPhotoExtension)) { + if ($hubUser->coverPhotoHash === null || $hubUser->coverPhotoHash === '' || $hubUser->coverPhotoExtension === null || $hubUser->coverPhotoExtension === '') { return ''; } @@ -504,7 +510,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue $hubUrl = 'https://hub.sp-tarkov.com/images/coverPhotos/'.$hashShort.'/'.$hubUser->userID.'-'.$fileName; $relativePath = 'user-covers/'.$fileName; - return $this->fetchAndStoreImage($curl, $hubUrl, $relativePath); + return $this->fetchAndStoreImage($curlHandle, $hubUrl, $relativePath); } /** @@ -529,7 +535,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue { if ($hubUser->banned) { return [ - 'hub_id' => (int) $hubUser->userID, + 'hub_id' => $hubUser->userID, 'comment' => $hubUser->banReason ?? '', 'expired_at' => $this->cleanUnbannedAtDate($hubUser->banExpires), ]; @@ -572,7 +578,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue } return $date->toDateTimeString(); - } catch (\Exception $e) { + } catch (Exception) { // If the date is not valid, return null return null; } @@ -585,7 +591,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue { if ($hubUser->rankID && $hubUser->rankTitle) { return [ - 'hub_id' => (int) $hubUser->userID, + 'hub_id' => $hubUser->userID, 'title' => $hubUser->rankTitle, ]; } @@ -598,7 +604,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue */ protected function upsertUsers(array $usersData): void { - if (! empty($usersData)) { + if ($usersData !== []) { DB::table('users')->upsert($usersData, ['hub_id'], [ 'name', 'email', @@ -677,7 +683,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue DB::connection('mysql_hub') ->table('wcf1_user_follow') ->select(['followID', 'userID', 'followUserID', 'time']) - ->chunkById(100, function (Collection $follows) use (&$followsGroupedByFollower) { + ->chunkById(100, function (Collection $follows) use (&$followsGroupedByFollower): void { foreach ($follows as $follow) { $followerId = User::whereHubId($follow->userID)->value('id'); $followingId = User::whereHubId($follow->followUserID)->value('id'); @@ -708,7 +714,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue { DB::connection('mysql_hub') ->table('filebase1_license') - ->chunkById(100, function (Collection $licenses) { + ->chunkById(100, function (Collection $licenses): void { $insertData = []; foreach ($licenses as $license) { @@ -719,7 +725,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue ]; } - if (! empty($insertData)) { + if ($insertData !== []) { DB::table('licenses')->upsert($insertData, ['hub_id'], ['name', 'link']); } }, 'licenseID'); @@ -745,7 +751,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue $response = curl_exec($ch); - if (curl_errno($ch)) { + if (curl_errno($ch) !== 0) { throw new Exception('cURL Error: '.curl_error($ch)); } @@ -757,21 +763,19 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue throw new Exception('JSON Decode Error: '.json_last_error_msg()); } - if (empty($response)) { + if ($response === []) { throw new Exception('No version data found in the GitHub API response.'); } // Filter out drafts and pre-releases. - $response = array_filter($response, function ($release) { - return ! $release['draft'] && ! $release['prerelease']; - }); + $response = array_filter($response, fn (array $release): bool => ! $release['draft'] && ! $release['prerelease']); - if (empty($response)) { + if ($response === []) { throw new Exception('No finalized versions found after filtering drafts and pre-releases.'); } // Ensure that each of the tag_name values has any 'v' prefix trimmed. - $response = array_map(function ($release) { + $response = array_map(function (array $release) { $release['tag_name'] = Str::of($release['tag_name'])->ltrim('v')->toString(); return $release; @@ -821,7 +825,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue protected function getLatestVersion(array $versions): string { $semanticVersions = array_map( - fn ($version) => $this->extractSemanticVersion($version['tag_name']), + fn ($version): ?string => $this->extractSemanticVersion($version['tag_name']), $versions ); @@ -876,7 +880,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue $major = (int) $major; $minor = (int) $minor; - if ($major == $currentMajor) { + if ($major === $currentMajor) { $difference = $currentMinor - $minor; return match ($difference) { @@ -903,7 +907,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue DB::connection('mysql_hub') ->table('filebase1_file') - ->chunkById(100, function (Collection $mods) use ($curl) { + ->chunkById(100, function (Collection $mods) use ($curl): void { foreach ($mods as $mod) { // Fetch any additional authors for the mod. @@ -1006,10 +1010,10 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue /** * Fetch the mod thumbnail from the Hub and store it anew. */ - protected function fetchModThumbnail(CurlHandle $curl, string $fileID, string $thumbnailHash, string $thumbnailExtension): string + protected function fetchModThumbnail(CurlHandle $curlHandle, string $fileID, string $thumbnailHash, string $thumbnailExtension): string { // If any of the required fields are empty, return an empty string. - if (empty($fileID) || empty($thumbnailHash) || empty($thumbnailExtension)) { + if ($fileID === '' || $fileID === '0' || ($thumbnailHash === '' || $thumbnailHash === '0') || ($thumbnailExtension === '' || $thumbnailExtension === '0')) { return ''; } @@ -1019,7 +1023,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue $hubUrl = 'https://hub.sp-tarkov.com/files/images/file/'.$hashShort.'/'.$fileName; $relativePath = 'mods/'.$fileName; - return $this->fetchAndStoreImage($curl, $hubUrl, $relativePath); + return $this->fetchAndStoreImage($curlHandle, $hubUrl, $relativePath); } /** @@ -1029,7 +1033,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue { DB::connection('mysql_hub') ->table('filebase1_file_version') - ->chunkById(500, function (Collection $versions) { + ->chunkById(500, function (Collection $versions): void { foreach ($versions as $version) { $versionContent = DB::table('temp_file_version_content') @@ -1065,7 +1069,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue try { $modVersion = new Version($version->versionNumber); - } catch (InvalidVersionNumberException $e) { + } catch (InvalidVersionNumberException) { $modVersion = new Version('0.0.0'); } @@ -1123,7 +1127,7 @@ class ImportHubDataJob implements ShouldBeUnique, ShouldQueue /** * The job failed to process. */ - public function failed(Throwable $exception): void + public function failed(Throwable $throwable): void { // Explicitly drop the temporary tables. DB::unprepared('DROP TEMPORARY TABLE IF EXISTS temp_user_avatar'); diff --git a/app/Jobs/ResolveDependenciesJob.php b/app/Jobs/ResolveDependenciesJob.php index 8f5024b..234ec3f 100644 --- a/app/Jobs/ResolveDependenciesJob.php +++ b/app/Jobs/ResolveDependenciesJob.php @@ -1,5 +1,7 @@ each(function (SptVersion $sptVersion) { + SptVersion::all()->each(function (SptVersion $sptVersion): void { $sptVersion->updateModCount(); }); } diff --git a/app/Jobs/UpdateModDownloadsJob.php b/app/Jobs/UpdateModDownloadsJob.php index 57f4781..a5907c2 100644 --- a/app/Jobs/UpdateModDownloadsJob.php +++ b/app/Jobs/UpdateModDownloadsJob.php @@ -1,5 +1,7 @@ chunk(100, function ($mods) { + Mod::with('versions')->chunk(100, function ($mods): void { foreach ($mods as $mod) { $mod->calculateDownloads(); } diff --git a/app/Livewire/GlobalSearch.php b/app/Livewire/GlobalSearch.php index 9e0ea0c..a5ef949 100644 --- a/app/Livewire/GlobalSearch.php +++ b/app/Livewire/GlobalSearch.php @@ -1,5 +1,7 @@ reduce(function (int $carry, Collection $result) { - return $carry + $result->count(); - }, 0); + return collect($results)->reduce(fn (int $carry, Collection $result): int => $carry + $result->count(), 0); } } diff --git a/app/Livewire/Mod/Listing.php b/app/Livewire/Mod/Listing.php index 7b3e25a..5e95d73 100644 --- a/app/Livewire/Mod/Listing.php +++ b/app/Livewire/Mod/Listing.php @@ -1,5 +1,7 @@ activeSptVersions = $this->activeSptVersions ?? Cache::remember('active-spt-versions', 60 * 60, function () { - return SptVersion::getVersionsForLastThreeMinors(); - }); + $this->activeSptVersions ??= Cache::remember('active-spt-versions', 60 * 60, fn (): Collection => SptVersion::getVersionsForLastThreeMinors()); - $this->sptVersions = $this->sptVersions ?? $this->getDefaultSptVersions(); + $this->sptVersions ??= $this->getDefaultSptVersions(); } /** @@ -92,9 +92,7 @@ class Listing extends Component */ public function getLatestMinorVersions(): Collection { - return $this->activeSptVersions->filter(function (SptVersion $sptVersion) { - return $sptVersion->isLatestMinor(); - }); + return $this->activeSptVersions->filter(fn (SptVersion $sptVersion): bool => $sptVersion->isLatestMinor()); } /** @@ -112,11 +110,11 @@ class Listing extends Component 'sptVersions' => $this->sptVersions, ]; - $mods = (new ModFilter($filters))->apply()->paginate($this->perPage); + $lengthAwarePaginator = (new ModFilter($filters))->apply()->paginate($this->perPage); - $this->redirectOutOfBoundsPage($mods); + $this->redirectOutOfBoundsPage($lengthAwarePaginator); - return view('livewire.mod.listing', compact('mods')); + return view('livewire.mod.listing', ['mods' => $mods]); } /** @@ -140,10 +138,10 @@ class Listing extends Component /** * Check if the current page is greater than the last page. Redirect if it is. */ - private function redirectOutOfBoundsPage(LengthAwarePaginator $mods): void + private function redirectOutOfBoundsPage(LengthAwarePaginator $lengthAwarePaginator): void { - if ($mods->currentPage() > $mods->lastPage()) { - $this->redirectRoute('mods', ['page' => $mods->lastPage()]); + if ($lengthAwarePaginator->currentPage() > $lengthAwarePaginator->lastPage()) { + $this->redirectRoute('mods', ['page' => $lengthAwarePaginator->lastPage()]); } } @@ -165,13 +163,13 @@ class Listing extends Component { $count = 0; if ($this->query !== '') { - $count++; + ++$count; } - if ($this->featured !== 'include') { - $count++; - } - $count += count($this->sptVersions); - return $count; + if ($this->featured !== 'include') { + ++$count; + } + + return $count + count($this->sptVersions); } } diff --git a/app/Livewire/Profile/ManageOAuthConnections.php b/app/Livewire/Profile/ManageOAuthConnections.php index cb297fd..f14b103 100644 --- a/app/Livewire/Profile/ManageOAuthConnections.php +++ b/app/Livewire/Profile/ManageOAuthConnections.php @@ -1,5 +1,7 @@ resetErrorBag(); $user = Auth::user(); if ($user->password !== null) { - parent::updatePassword($updater); + parent::updatePassword($updatesUserPasswords); } else { // User has a null password. Allow them to set a new password without their current password. diff --git a/app/Livewire/Profile/UpdateProfileForm.php b/app/Livewire/Profile/UpdateProfileForm.php index 2408030..dd6b95f 100644 --- a/app/Livewire/Profile/UpdateProfileForm.php +++ b/app/Livewire/Profile/UpdateProfileForm.php @@ -1,5 +1,7 @@ resetErrorBag(); - $updater->update( + $updatesUserProfileInformation->update( Auth::user(), $this->photo || $this->cover ? array_merge($this->state, array_filter([ @@ -51,7 +55,7 @@ class UpdateProfileForm extends UpdateProfileInformationForm ])) : $this->state ); - if (isset($this->photo) || isset($this->cover)) { + if ($this->photo !== null || $this->cover !== null) { return redirect()->route('profile.show'); } diff --git a/app/Livewire/User/FollowButtons.php b/app/Livewire/User/FollowButtons.php index 6b591d2..48399bf 100644 --- a/app/Livewire/User/FollowButtons.php +++ b/app/Livewire/User/FollowButtons.php @@ -1,5 +1,7 @@ latestVersion->latestSptVersion->version, $activeSptVersions->pluck('version')->toArray())) { - return false; - } + $activeSptVersions = Cache::remember('active-spt-versions', 60 * 60, fn (): Collection => SptVersion::getVersionsForLastThreeMinors()); // All conditions are met; the mod should be searchable. - return true; + return in_array($this->latestVersion->latestSptVersion->version, $activeSptVersions->pluck('version')->toArray()); } /** @@ -196,11 +196,9 @@ class Mod extends Model */ public function thumbnailUrl(): Attribute { - return Attribute::get(function (): string { - return $this->thumbnail - ? Storage::disk($this->thumbnailDisk())->url($this->thumbnail) - : ''; - }); + return Attribute::get(fn (): string => $this->thumbnail + ? Storage::disk($this->thumbnailDisk())->url($this->thumbnail) + : ''); } /** @@ -217,9 +215,9 @@ class Mod extends Model /** * Scope a query by applying QueryFilter filters. */ - public function scopeFilter(Builder $builder, QueryFilter $filters): Builder + public function scopeFilter(Builder $builder, QueryFilter $queryFilter): Builder { - return $filters->apply($builder); + return $queryFilter->apply($builder); } /** diff --git a/app/Models/ModDependency.php b/app/Models/ModDependency.php index 8ab885c..4041829 100644 --- a/app/Models/ModDependency.php +++ b/app/Models/ModDependency.php @@ -1,5 +1,7 @@ version); + $version = new Version($modVersion->version); - $model->version_major = $version->getMajor(); - $model->version_minor = $version->getMinor(); - $model->version_patch = $version->getPatch(); - $model->version_pre_release = $version->getPreRelease(); - } catch (InvalidVersionNumberException $e) { - $model->version_major = 0; - $model->version_minor = 0; - $model->version_patch = 0; - $model->version_pre_release = ''; + $modVersion->version_major = $version->getMajor(); + $modVersion->version_minor = $version->getMinor(); + $modVersion->version_patch = $version->getPatch(); + $modVersion->version_pre_release = $version->getPreRelease(); + } catch (InvalidVersionNumberException) { + $modVersion->version_major = 0; + $modVersion->version_minor = 0; + $modVersion->version_patch = 0; + $modVersion->version_pre_release = ''; } }); } @@ -93,7 +97,7 @@ class ModVersion extends Model { return $this->belongsToMany(ModVersion::class, 'mod_resolved_dependencies', 'mod_version_id', 'resolved_mod_version_id') ->withPivot('dependency_id') - ->join('mod_versions as latest_versions', function ($join) { + ->join('mod_versions as latest_versions', function ($join): void { $join->on('latest_versions.id', '=', 'mod_versions.id') ->whereRaw('latest_versions.version = (SELECT MAX(mv.version) FROM mod_versions mv WHERE mv.mod_id = mod_versions.mod_id)'); }) @@ -144,7 +148,7 @@ class ModVersion extends Model */ public function incrementDownloads(): int { - $this->downloads++; + ++$this->downloads; $this->save(); // Recalculate the total download count for this mod. diff --git a/app/Models/ModVersionSptVersion.php b/app/Models/ModVersionSptVersion.php index 355dce7..5054cfa 100644 --- a/app/Models/ModVersionSptVersion.php +++ b/app/Models/ModVersionSptVersion.php @@ -1,5 +1,7 @@ orderByDesc('version_minor') ->limit(3) ->get() - ->map(function (SptVersion $version) { - return [ - 'major' => (int) $version->version_major, - 'minor' => (int) $version->version_minor, - ]; - }) + ->map(fn (SptVersion $sptVersion): array => [ + 'major' => (int) $sptVersion->version_major, + 'minor' => (int) $sptVersion->version_minor, + ]) ->toArray(); } @@ -77,7 +78,7 @@ class SptVersion extends Model // Perform the regex match to capture the version sections, including the possible preRelease section. preg_match('/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([a-zA-Z0-9]+))?$/', $version, $matches); - if (! $matches) { + if ($matches === []) { throw new InvalidVersionNumberException('Invalid SPT version number: '.$version); } @@ -92,22 +93,23 @@ class SptVersion extends Model /** * Called when the model is booted. */ + #[Override] protected static function booted(): void { - static::saving(function (SptVersion $model) { + static::saving(function (SptVersion $sptVersion): void { // Extract the version sections from the version string. try { - $version = new Version($model->version); + $version = new Version($sptVersion->version); - $model->version_major = $version->getMajor(); - $model->version_minor = $version->getMinor(); - $model->version_patch = $version->getPatch(); - $model->version_pre_release = $version->getPreRelease(); - } catch (InvalidVersionNumberException $e) { - $model->version_major = 0; - $model->version_minor = 0; - $model->version_patch = 0; - $model->version_pre_release = ''; + $sptVersion->version_major = $version->getMajor(); + $sptVersion->version_minor = $version->getMinor(); + $sptVersion->version_patch = $version->getPatch(); + $sptVersion->version_pre_release = $version->getPreRelease(); + } catch (InvalidVersionNumberException) { + $sptVersion->version_major = 0; + $sptVersion->version_minor = 0; + $sptVersion->version_patch = 0; + $sptVersion->version_pre_release = ''; } }); } @@ -152,7 +154,7 @@ class SptVersion extends Model { $latestVersion = self::getLatest(); - if (! $latestVersion) { + if (! $latestVersion instanceof \App\Models\SptVersion) { return false; } @@ -166,13 +168,11 @@ class SptVersion extends Model */ public static function getLatest(): ?SptVersion { - return Cache::remember('latest_spt_version', 300, function () { - return SptVersion::select(['version', 'version_major', 'version_minor', 'version_patch', 'version_pre_release']) - ->orderByDesc('version_major') - ->orderByDesc('version_minor') - ->orderByDesc('version_patch') - ->first(); - }); + return Cache::remember('latest_spt_version', 300, fn () => SptVersion::select(['version', 'version_major', 'version_minor', 'version_patch', 'version_pre_release']) + ->orderByDesc('version_major') + ->orderByDesc('version_minor') + ->orderByDesc('version_patch') + ->first()); } /** diff --git a/app/Models/User.php b/app/Models/User.php index 123b5e7..f0a092d 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -1,5 +1,7 @@ notify(new ResetPassword($token)); } @@ -196,9 +199,9 @@ class User extends Authenticatable implements MustVerifyEmail /** * Assign a role to the user. */ - public function assignRole(UserRole $role): bool + public function assignRole(UserRole $userRole): bool { - $this->role()->associate($role); + $this->role()->associate($userRole); return $this->save(); } @@ -216,9 +219,9 @@ class User extends Authenticatable implements MustVerifyEmail /** * Scope a query by applying QueryFilter filters. */ - public function scopeFilter(Builder $builder, QueryFilter $filters): Builder + public function scopeFilter(Builder $builder, QueryFilter $queryFilter): Builder { - return $filters->apply($builder); + return $queryFilter->apply($builder); } /** diff --git a/app/Models/UserRole.php b/app/Models/UserRole.php index 09f1906..0431df0 100644 --- a/app/Models/UserRole.php +++ b/app/Models/UserRole.php @@ -1,5 +1,7 @@ dependencyVersionService = $dependencyVersionService; - } + public function __construct(protected DependencyVersionService $dependencyVersionService) {} /** * Handle the ModDependency "saved" event. diff --git a/app/Observers/ModObserver.php b/app/Observers/ModObserver.php index fd2c926..d961c58 100644 --- a/app/Observers/ModObserver.php +++ b/app/Observers/ModObserver.php @@ -1,5 +1,7 @@ dependencyVersionService = $dependencyVersionService; - } + public function __construct(protected DependencyVersionService $dependencyVersionService) {} /** * Handle the Mod "saved" event. diff --git a/app/Observers/ModVersionObserver.php b/app/Observers/ModVersionObserver.php index 535a467..81c3b88 100644 --- a/app/Observers/ModVersionObserver.php +++ b/app/Observers/ModVersionObserver.php @@ -1,5 +1,7 @@ dependencyVersionService = $dependencyVersionService; - $this->sptVersionService = $sptVersionService; - } + public function __construct(protected DependencyVersionService $dependencyVersionService, protected SptVersionService $sptVersionService) {} /** * Handle the ModVersion "saved" event. diff --git a/app/Observers/SptVersionObserver.php b/app/Observers/SptVersionObserver.php index 1b547fa..2e8daa3 100644 --- a/app/Observers/SptVersionObserver.php +++ b/app/Observers/SptVersionObserver.php @@ -1,5 +1,7 @@ sptVersionService = $sptVersionService; - } + public function __construct(protected SptVersionService $sptVersionService) {} /** * Handle the SptVersion "saved" event. diff --git a/app/Policies/ModPolicy.php b/app/Policies/ModPolicy.php index b5e9873..d45b724 100644 --- a/app/Policies/ModPolicy.php +++ b/app/Policies/ModPolicy.php @@ -1,5 +1,7 @@ registerLivewireOverrides(); // This gate determines who can access the Pulse dashboard. - Gate::define('viewPulse', function (User $user) { - return $user->isAdmin(); - }); + Gate::define('viewPulse', fn (User $user): bool => $user->isAdmin()); // Register the Discord socialite provider. - Event::listen(function (SocialiteWasCalled $event) { - $event->extendSocialite('discord', Provider::class); + Event::listen(function (SocialiteWasCalled $socialiteWasCalled): void { + $socialiteWasCalled->extendSocialite('discord', Provider::class); }); } @@ -81,14 +83,12 @@ class AppServiceProvider extends ServiceProvider private function registerNumberMacros(): void { // Format download numbers. - Number::macro('downloads', function (int|float $number) { - return Number::forHumans( - $number, - $number > 1000000 ? 2 : ($number > 1000 ? 1 : 0), - maxPrecision: null, - abbreviate: true - ); - }); + Number::macro('downloads', fn (int|float $number) => Number::forHumans( + $number, + $number > 1000000 ? 2 : ($number > 1000 ? 1 : 0), + maxPrecision: null, + abbreviate: true + )); } /** @@ -97,10 +97,11 @@ class AppServiceProvider extends ServiceProvider private function registerCarbonMacros(): void { // Format dates dynamically based on the time passed. - Carbon::macro('dynamicFormat', function (Carbon $date) { + Carbon::macro('dynamicFormat', function (Carbon $date): string { if ($date->diff(now())->m > 1) { return $date->format('M jS, Y'); } + if ($date->diff(now())->d === 0) { return $date->diffForHumans(); } diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 04e4909..ef184d7 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -1,15 +1,18 @@ discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources') ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages') ->pages([ - Pages\Dashboard::class, + Dashboard::class, ]) ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets') ->widgets([ - Widgets\AccountWidget::class, - Widgets\FilamentInfoWidget::class, + AccountWidget::class, + FilamentInfoWidget::class, ]) ->middleware([ EncryptCookies::class, diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index 2d741e3..8ca2c12 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -1,5 +1,7 @@ by($throttleKey); }); - RateLimiter::for('two-factor', function (Request $request) { - return Limit::perMinute(5)->by($request->session()->get('login.id')); - }); + RateLimiter::for('two-factor', fn (Request $request) => Limit::perMinute(5)->by($request->session()->get('login.id'))); } } diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php index 376ad84..27eb1ec 100644 --- a/app/Providers/HorizonServiceProvider.php +++ b/app/Providers/HorizonServiceProvider.php @@ -1,15 +1,19 @@ isAdmin(); - }); + Gate::define('viewHorizon', fn ($user) => $user->isAdmin()); } } diff --git a/app/Providers/JetstreamServiceProvider.php b/app/Providers/JetstreamServiceProvider.php index 9139849..11be71f 100644 --- a/app/Providers/JetstreamServiceProvider.php +++ b/app/Providers/JetstreamServiceProvider.php @@ -1,16 +1,20 @@ dependentMod->versions()->get(); // Filter the dependent mod versions to find the ones that satisfy the dependency constraint. - $matchedVersions = $dependentModVersions->filter(function ($version) use ($dependency) { - return Semver::satisfies($version->version, $dependency->constraint); - }); + $matchedVersions = $dependentModVersions->filter(fn ($version) => Semver::satisfies($version->version, $dependency->constraint)); // Map the matched versions to the sync data. foreach ($matchedVersions as $matchedVersion) { diff --git a/app/Services/SptVersionService.php b/app/Services/SptVersionService.php index 8eba213..62ad0a0 100644 --- a/app/Services/SptVersionService.php +++ b/app/Services/SptVersionService.php @@ -1,5 +1,7 @@ version = $version; $this->parseVersion(); } diff --git a/app/Traits/ApiResponses.php b/app/Traits/ApiResponses.php index 7117318..c2a42dd 100644 --- a/app/Traits/ApiResponses.php +++ b/app/Traits/ApiResponses.php @@ -1,5 +1,7 @@ json($response, $code); diff --git a/app/Traits/HasCoverPhoto.php b/app/Traits/HasCoverPhoto.php index b366079..2322166 100644 --- a/app/Traits/HasCoverPhoto.php +++ b/app/Traits/HasCoverPhoto.php @@ -1,5 +1,7 @@ cover_photo_path, function ($previous) use ($cover, $storagePath) { + tap($this->cover_photo_path, function ($previous) use ($uploadedFile, $storagePath): void { $this->forceFill([ - 'cover_photo_path' => $cover->storePublicly( + 'cover_photo_path' => $uploadedFile->storePublicly( $storagePath, ['disk' => $this->coverPhotoDisk()] ), ])->save(); diff --git a/app/Traits/V1/FilterMethods.php b/app/Traits/V1/FilterMethods.php index d20b94c..2a32d17 100644 --- a/app/Traits/V1/FilterMethods.php +++ b/app/Traits/V1/FilterMethods.php @@ -1,5 +1,7 @@ with([ - 'latestVersion', - 'latestVersion.latestSptVersion', - 'users:id,name', - 'license:id,name,link', - ]) - ->inRandomOrder() - ->limit(6) - ->get(); - }); + return Cache::flexible('homepage-featured-mods', [5, 10], fn () => Mod::whereFeatured(true) + ->with([ + 'latestVersion', + 'latestVersion.latestSptVersion', + 'users:id,name', + 'license:id,name,link', + ]) + ->inRandomOrder() + ->limit(6) + ->get()); } /** @@ -55,17 +55,15 @@ class HomepageMods extends Component */ private function fetchLatestMods(): Collection { - return Cache::flexible('homepage-latest-mods', [5, 10], function () { - return Mod::orderByDesc('created_at') - ->with([ - 'latestVersion', - 'latestVersion.latestSptVersion', - 'users:id,name', - 'license:id,name,link', - ]) - ->limit(6) - ->get(); - }); + return Cache::flexible('homepage-latest-mods', [5, 10], fn () => Mod::orderByDesc('created_at') + ->with([ + 'latestVersion', + 'latestVersion.latestSptVersion', + 'users:id,name', + 'license:id,name,link', + ]) + ->limit(6) + ->get()); } /** @@ -73,16 +71,14 @@ class HomepageMods extends Component */ private function fetchUpdatedMods(): Collection { - return Cache::flexible('homepage-updated-mods', [5, 10], function () { - return Mod::orderByDesc('updated_at') - ->with([ - 'latestUpdatedVersion', - 'latestUpdatedVersion.latestSptVersion', - 'users:id,name', - 'license:id,name,link', - ]) - ->limit(6) - ->get(); - }); + return Cache::flexible('homepage-updated-mods', [5, 10], fn () => Mod::orderByDesc('updated_at') + ->with([ + 'latestUpdatedVersion', + 'latestUpdatedVersion.latestSptVersion', + 'users:id,name', + 'license:id,name,link', + ]) + ->limit(6) + ->get()); } } diff --git a/bootstrap/app.php b/bootstrap/app.php index 58f289c..302cda0 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,5 +1,7 @@ prefix('api/v0') ->name('api.v0.') ->group(base_path('routes/api_v0.php')); }, ) - ->withMiddleware(function (Middleware $middleware) { + ->withMiddleware(function (Middleware $middleware): void { $middleware->append(IPBanned::class); }) - ->withExceptions(function (Exceptions $exceptions) { + ->withExceptions(function (Exceptions $exceptions): void { // }) ->create(); diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 843676d..bb18df5 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -1,10 +1,19 @@ [ ...array_filter( - explode(',', env('APP_PREVIOUS_KEYS', '')) + explode(',', (string) env('APP_PREVIOUS_KEYS', '')) ), ], @@ -137,7 +140,7 @@ return [ */ 'aliases' => Facade::defaultAliases()->merge([ - 'Carbon' => \Carbon\Carbon::class, + 'Carbon' => Carbon::class, ])->toArray(), ]; diff --git a/config/auth.php b/config/auth.php index 0ba5d5d..a927937 100644 --- a/config/auth.php +++ b/config/auth.php @@ -1,5 +1,9 @@ [ 'users' => [ 'driver' => 'eloquent', - 'model' => env('AUTH_MODEL', App\Models\User::class), + 'model' => env('AUTH_MODEL', User::class), ], // 'users' => [ diff --git a/config/ban.php b/config/ban.php index c84b709..a96bc10 100644 --- a/config/ban.php +++ b/config/ban.php @@ -1,5 +1,9 @@ \Mchev\Banhammer\Models\Ban::class, + 'model' => Ban::class, /* |-------------------------------------------------------------------------- diff --git a/config/cache.php b/config/cache.php index 6b57b18..d1de0c0 100644 --- a/config/cache.php +++ b/config/cache.php @@ -1,5 +1,7 @@ [ 'driver' => 'stack', - 'channels' => explode(',', env('LOG_STACK', 'single')), + 'channels' => explode(',', (string) env('LOG_STACK', 'single')), 'ignore_exceptions' => false, ], diff --git a/config/mail.php b/config/mail.php index 07342fc..69b5c67 100644 --- a/config/mail.php +++ b/config/mail.php @@ -1,5 +1,7 @@ [ - \Barryvdh\Debugbar\LaravelDebugbar::class, + LaravelDebugbar::class, ], /* diff --git a/config/pulse.php b/config/pulse.php index e417066..7d4585e 100644 --- a/config/pulse.php +++ b/config/pulse.php @@ -1,8 +1,19 @@ [ - Recorders\CacheInteractions::class => [ + CacheInteractions::class => [ 'enabled' => env('PULSE_CACHE_INTERACTIONS_ENABLED', true), 'sample_rate' => env('PULSE_CACHE_INTERACTIONS_SAMPLE_RATE', 1), 'ignore' => [ @@ -145,7 +156,7 @@ return [ ], ], - Recorders\Exceptions::class => [ + Exceptions::class => [ 'enabled' => env('PULSE_EXCEPTIONS_ENABLED', true), 'sample_rate' => env('PULSE_EXCEPTIONS_SAMPLE_RATE', 1), 'location' => env('PULSE_EXCEPTIONS_LOCATION', true), @@ -154,7 +165,7 @@ return [ ], ], - Recorders\Queues::class => [ + Queues::class => [ 'enabled' => env('PULSE_QUEUES_ENABLED', true), 'sample_rate' => env('PULSE_QUEUES_SAMPLE_RATE', 1), 'ignore' => [ @@ -162,12 +173,12 @@ return [ ], ], - Recorders\Servers::class => [ + Servers::class => [ 'server_name' => env('PULSE_SERVER_NAME', gethostname()), - 'directories' => explode(':', env('PULSE_SERVER_DIRECTORIES', '/')), + 'directories' => explode(':', (string) env('PULSE_SERVER_DIRECTORIES', '/')), ], - Recorders\SlowJobs::class => [ + SlowJobs::class => [ 'enabled' => env('PULSE_SLOW_JOBS_ENABLED', true), 'sample_rate' => env('PULSE_SLOW_JOBS_SAMPLE_RATE', 1), 'threshold' => env('PULSE_SLOW_JOBS_THRESHOLD', 1000), @@ -176,7 +187,7 @@ return [ ], ], - Recorders\SlowOutgoingRequests::class => [ + SlowOutgoingRequests::class => [ 'enabled' => env('PULSE_SLOW_OUTGOING_REQUESTS_ENABLED', true), 'sample_rate' => env('PULSE_SLOW_OUTGOING_REQUESTS_SAMPLE_RATE', 1), 'threshold' => env('PULSE_SLOW_OUTGOING_REQUESTS_THRESHOLD', 1000), @@ -190,7 +201,7 @@ return [ ], ], - Recorders\SlowQueries::class => [ + SlowQueries::class => [ 'enabled' => env('PULSE_SLOW_QUERIES_ENABLED', true), 'sample_rate' => env('PULSE_SLOW_QUERIES_SAMPLE_RATE', 1), 'threshold' => env('PULSE_SLOW_QUERIES_THRESHOLD', 1000), @@ -202,7 +213,7 @@ return [ ], ], - Recorders\SlowRequests::class => [ + SlowRequests::class => [ 'enabled' => env('PULSE_SLOW_REQUESTS_ENABLED', true), 'sample_rate' => env('PULSE_SLOW_REQUESTS_SAMPLE_RATE', 1), 'threshold' => env('PULSE_SLOW_REQUESTS_THRESHOLD', 1000), @@ -212,7 +223,7 @@ return [ ], ], - Recorders\UserJobs::class => [ + UserJobs::class => [ 'enabled' => env('PULSE_USER_JOBS_ENABLED', true), 'sample_rate' => env('PULSE_USER_JOBS_SAMPLE_RATE', 1), 'ignore' => [ @@ -220,7 +231,7 @@ return [ ], ], - Recorders\UserRequests::class => [ + UserRequests::class => [ 'enabled' => env('PULSE_USER_REQUESTS_ENABLED', true), 'sample_rate' => env('PULSE_USER_REQUESTS_SAMPLE_RATE', 1), 'ignore' => [ diff --git a/config/purify.php b/config/purify.php index 7a3d86d..0578cfa 100644 --- a/config/purify.php +++ b/config/purify.php @@ -1,5 +1,8 @@ [ 'driver' => env('CACHE_DRIVER', 'file'), - 'cache' => \Stevebauman\Purify\Cache\CacheDefinitionCache::class, + 'cache' => CacheDefinitionCache::class, ], ]; diff --git a/config/queue.php b/config/queue.php index 1f5a9d4..07b0059 100644 --- a/config/queue.php +++ b/config/queue.php @@ -1,5 +1,7 @@ explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + 'stateful' => explode(',', (string) env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', Sanctum::currentApplicationUrlWithPort() @@ -75,9 +80,9 @@ return [ */ 'middleware' => [ - 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, - 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, - 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, + 'authenticate_session' => AuthenticateSession::class, + 'encrypt_cookies' => EncryptCookies::class, + 'validate_csrf_token' => ValidateCsrfToken::class, ], ]; diff --git a/config/scout.php b/config/scout.php index c9653f9..00bc750 100644 --- a/config/scout.php +++ b/config/scout.php @@ -1,5 +1,7 @@ for the generated documentation. If this is empty, Scribe will infer it from config('app.name'). @@ -201,23 +225,23 @@ INTRO // If you create or install a custom strategy, add it here. 'strategies' => [ 'metadata' => [ - Strategies\Metadata\GetFromDocBlocks::class, - Strategies\Metadata\GetFromMetadataAttributes::class, + GetFromDocBlocks::class, + GetFromMetadataAttributes::class, ], 'urlParameters' => [ - Strategies\UrlParameters\GetFromLaravelAPI::class, - Strategies\UrlParameters\GetFromUrlParamAttribute::class, - Strategies\UrlParameters\GetFromUrlParamTag::class, + GetFromLaravelAPI::class, + GetFromUrlParamAttribute::class, + GetFromUrlParamTag::class, ], 'queryParameters' => [ - Strategies\QueryParameters\GetFromFormRequest::class, - Strategies\QueryParameters\GetFromInlineValidator::class, - Strategies\QueryParameters\GetFromQueryParamAttribute::class, - Strategies\QueryParameters\GetFromQueryParamTag::class, + GetFromFormRequest::class, + GetFromInlineValidator::class, + GetFromQueryParamAttribute::class, + GetFromQueryParamTag::class, ], 'headers' => [ - Strategies\Headers\GetFromHeaderAttribute::class, - Strategies\Headers\GetFromHeaderTag::class, + GetFromHeaderAttribute::class, + GetFromHeaderTag::class, [ 'override', [ @@ -229,17 +253,17 @@ INTRO 'bodyParameters' => [ Strategies\BodyParameters\GetFromFormRequest::class, Strategies\BodyParameters\GetFromInlineValidator::class, - Strategies\BodyParameters\GetFromBodyParamAttribute::class, - Strategies\BodyParameters\GetFromBodyParamTag::class, + GetFromBodyParamAttribute::class, + GetFromBodyParamTag::class, ], 'responses' => [ - Strategies\Responses\UseResponseAttributes::class, - Strategies\Responses\UseTransformerTags::class, - Strategies\Responses\UseApiResourceTags::class, - Strategies\Responses\UseResponseTag::class, - Strategies\Responses\UseResponseFileTag::class, + UseResponseAttributes::class, + UseTransformerTags::class, + UseApiResourceTags::class, + UseResponseTag::class, + UseResponseFileTag::class, [ - Strategies\Responses\ResponseCalls::class, + ResponseCalls::class, [ 'only' => ['GET *'], // Disable debug mode when generating response calls to avoid error stack traces in responses @@ -250,8 +274,8 @@ INTRO ], ], 'responseFields' => [ - Strategies\ResponseFields\GetFromResponseFieldAttribute::class, - Strategies\ResponseFields\GetFromResponseFieldTag::class, + GetFromResponseFieldAttribute::class, + GetFromResponseFieldTag::class, ], ], @@ -265,5 +289,5 @@ INTRO 'serializer' => null, ], - 'routeMatcher' => \Knuckles\Scribe\Matching\RouteMatcher::class, + 'routeMatcher' => RouteMatcher::class, ]; diff --git a/config/services.php b/config/services.php index 2e068e7..e2cce67 100644 --- a/config/services.php +++ b/config/services.php @@ -1,5 +1,7 @@ withSkip([ + __DIR__.'*.blade.php', + ]) ->withCache( cacheDirectory: '.rector/cache', cacheClass: FileCacheStorage::class @@ -30,4 +33,5 @@ return RectorConfig::configure() rectorPreset: true, ) ->withPhpSets() - ->withImportNames(removeUnusedImports: true); + ->withImportNames(removeUnusedImports: true) + ->withAttributesSets(); diff --git a/routes/api.php b/routes/api.php index 1c1426f..68aeeeb 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,10 +1,12 @@ 'auth:sanctum'], function () { +Route::group(['middleware' => 'auth:sanctum'], function (): void { Route::delete('/logout', [AuthController::class, 'logout']); Route::delete('/logout/all', [AuthController::class, 'logoutAll']); }); diff --git a/routes/api_v0.php b/routes/api_v0.php index aa4bd6c..2ac50ae 100644 --- a/routes/api_v0.php +++ b/routes/api_v0.php @@ -1,10 +1,12 @@ 'auth:sanctum'], function () { +Route::group(['middleware' => 'auth:sanctum'], function (): void { Route::apiResource('users', UsersController::class); Route::apiResource('mods', ModController::class); }); diff --git a/routes/console.php b/routes/console.php index 6ab56fc..130efd5 100644 --- a/routes/console.php +++ b/routes/console.php @@ -1,5 +1,7 @@ group(function () { +Route::middleware(['auth.banned'])->group(function (): void { - Route::controller(SocialiteController::class)->group(function () { + Route::controller(SocialiteController::class)->group(function (): void { Route::get('/login/{provider}/redirect', 'redirect')->name('login.socialite'); Route::get('/login/{provider}/callback', 'callback'); }); - Route::get('/', function () { - return view('home'); - })->name('home'); + Route::get('/', fn () => view('home'))->name('home'); - Route::controller(ModController::class)->group(function () { + Route::controller(ModController::class)->group(function (): void { Route::get('/mods', 'index')->name('mods'); Route::get('/mod/{mod}/{slug}', 'show')->where(['mod' => '[0-9]+'])->name('mod.show'); }); // Download Link - Route::controller(ModVersionController::class)->group(function () { + Route::controller(ModVersionController::class)->group(function (): void { Route::get('/mod/download/{mod}/{slug}/{version}', 'show') ->where(['mod' => '[0-9]+', 'slug' => '[a-z0-9-]+']) ->name('mod.version.download'); }); - Route::controller(UserController::class)->group(function () { + Route::controller(UserController::class)->group(function (): void { Route::get('/user/{user}/{username}', 'show')->where(['user' => '[0-9]+'])->name('user.show'); }); - Route::middleware(['auth:sanctum', config('jetstream.auth_session'), 'verified'])->group(function () { - Route::get('/dashboard', function () { - return view('dashboard'); - })->name('dashboard'); + Route::middleware(['auth:sanctum', config('jetstream.auth_session'), 'verified'])->group(function (): void { + Route::get('/dashboard', fn () => view('dashboard'))->name('dashboard'); }); }); diff --git a/tests/Feature/Api/V1/ModFilterTest.php b/tests/Feature/Api/V1/ModFilterTest.php index 67db6a4..ed33dd8 100644 --- a/tests/Feature/Api/V1/ModFilterTest.php +++ b/tests/Feature/Api/V1/ModFilterTest.php @@ -1,5 +1,7 @@ create(['name' => 'Mod C', 'slug' => 'mod-c', 'featured' => true]); Mod::factory()->create(['name' => 'Mod B', 'slug' => 'mod-b', 'featured' => false]); Mod::factory()->create(['name' => 'Mod A', 'slug' => 'mod-a', 'featured' => true]); }); -it('can filter mods by id', function () { +it('can filter mods by id', function (): void { $request = new Request(['id' => '1,2']); $filter = new ModFilter($request); - $query = $filter->apply(Mod::query()); + $builder = $filter->apply(Mod::query()); - expect($query->get()->pluck('id')->toArray())->toBe([1, 2]); + expect($builder->get()->pluck('id')->toArray())->toBe([1, 2]); }); -it('can filter mods by name with wildcard', function () { +it('can filter mods by name with wildcard', function (): void { $request = new Request(['name' => 'Mod*']); $filter = new ModFilter($request); - $query = $filter->apply(Mod::query()); + $builder = $filter->apply(Mod::query()); - expect($query->get()->pluck('name')->toArray())->toContain('Mod A', 'Mod B', 'Mod C'); + expect($builder->get()->pluck('name')->toArray())->toContain('Mod A', 'Mod B', 'Mod C'); }); -it('can filter mods by featured status', function () { +it('can filter mods by featured status', function (): void { $request = new Request(['featured' => 'true']); $filter = new ModFilter($request); - $query = $filter->apply(Mod::query()); + $builder = $filter->apply(Mod::query()); - expect($query->get()->pluck('name')->toArray())->toContain('Mod A', 'Mod C'); + expect($builder->get()->pluck('name')->toArray())->toContain('Mod A', 'Mod C'); }); -it('can sort mods by name in ascending order', function () { +it('can sort mods by name in ascending order', function (): void { $request = new Request(['sort' => 'name']); $filter = new ModFilter($request); - $query = $filter->apply(Mod::query()); + $builder = $filter->apply(Mod::query()); - expect($query->get()->pluck('name')->toArray())->toBe(['Mod A', 'Mod B', 'Mod C']); + expect($builder->get()->pluck('name')->toArray())->toBe(['Mod A', 'Mod B', 'Mod C']); }); -it('can sort mods by name in descending order', function () { +it('can sort mods by name in descending order', function (): void { $request = new Request(['sort' => '-name']); $filter = new ModFilter($request); - $query = $filter->apply(Mod::query()); + $builder = $filter->apply(Mod::query()); - expect($query->get()->pluck('name')->toArray())->toBe(['Mod C', 'Mod B', 'Mod A']); + expect($builder->get()->pluck('name')->toArray())->toBe(['Mod C', 'Mod B', 'Mod A']); }); diff --git a/tests/Feature/Mod/ModDependencyTest.php b/tests/Feature/Mod/ModDependencyTest.php index a03f109..f54c555 100644 --- a/tests/Feature/Mod/ModDependencyTest.php +++ b/tests/Feature/Mod/ModDependencyTest.php @@ -1,5 +1,7 @@ create(); $dependentMod = Mod::factory()->create(); @@ -27,7 +29,7 @@ it('resolves mod version dependencies on create', function () { ->resolved_mod_version_id->toBe($dependentVersion1->id); }); -it('resolves multiple matching versions', function () { +it('resolves multiple matching versions', function (): void { $modVersion = ModVersion::factory()->create(); $dependentMod = Mod::factory()->create(); @@ -48,7 +50,7 @@ it('resolves multiple matching versions', function () { ->toContain($dependentVersion2->id); }); -it('does not resolve dependencies when no versions match', function () { +it('does not resolve dependencies when no versions match', function (): void { $modVersion = ModVersion::factory()->create(); $dependentMod = Mod::factory()->create(); @@ -64,7 +66,7 @@ it('does not resolve dependencies when no versions match', function () { expect(ModResolvedDependency::where('mod_version_id', $modVersion->id)->exists())->toBeFalse(); }); -it('updates resolved dependencies when constraint changes', function () { +it('updates resolved dependencies when constraint changes', function (): void { $modVersion = ModVersion::factory()->create(); $dependentMod = Mod::factory()->create(); @@ -86,7 +88,7 @@ it('updates resolved dependencies when constraint changes', function () { expect($resolvedDependency->resolved_mod_version_id)->toBe($dependentVersion2->id); }); -it('removes resolved dependencies when dependency is removed', function () { +it('removes resolved dependencies when dependency is removed', function (): void { $modVersion = ModVersion::factory()->create(); $dependentMod = Mod::factory()->create(); @@ -107,7 +109,7 @@ it('removes resolved dependencies when dependency is removed', function () { expect(ModResolvedDependency::where('mod_version_id', $modVersion->id)->exists())->toBeFalse(); }); -it('handles mod versions with no dependencies gracefully', function () { +it('handles mod versions with no dependencies gracefully', function (): void { $serviceSpy = $this->spy(DependencyVersionService::class); $modVersion = ModVersion::factory()->create(['version' => '1.0.0']); @@ -117,7 +119,7 @@ it('handles mod versions with no dependencies gracefully', function () { expect(ModResolvedDependency::where('mod_version_id', $modVersion->id)->exists())->toBeFalse(); }); -it('resolves the correct versions with a complex semver constraint', function () { +it('resolves the correct versions with a complex semver constraint', function (): void { $modVersion = ModVersion::factory()->create(['version' => '1.0.0']); $dependentMod = Mod::factory()->create(); @@ -141,7 +143,7 @@ it('resolves the correct versions with a complex semver constraint', function () ->not->toContain($dependentVersion4->id); }); -it('resolves overlapping version constraints from multiple dependencies correctly', function () { +it('resolves overlapping version constraints from multiple dependencies correctly', function (): void { $modVersion = ModVersion::factory()->create(['version' => '1.0.0']); $dependentMod1 = Mod::factory()->create(); @@ -170,7 +172,7 @@ it('resolves overlapping version constraints from multiple dependencies correctl ->not->toContain($dependentVersion2_1->id); }); -it('handles the case where a dependent mod has no versions available', function () { +it('handles the case where a dependent mod has no versions available', function (): void { $modVersion = ModVersion::factory()->create(['version' => '1.0.0']); $dependentMod = Mod::factory()->create(); @@ -183,13 +185,13 @@ it('handles the case where a dependent mod has no versions available', function expect(ModResolvedDependency::where('mod_version_id', $modVersion->id)->exists())->toBeFalse(); }); -it('handles a large number of versions efficiently', function () { +it('handles a large number of versions efficiently', function (): void { $startTime = microtime(true); $versionCount = 100; $dependentMod = Mod::factory()->create(); - for ($i = 0; $i < $versionCount; $i++) { - ModVersion::factory()->recycle($dependentMod)->create(['version' => "1.0.$i"]); + for ($i = 0; $i < $versionCount; ++$i) { + ModVersion::factory()->recycle($dependentMod)->create(['version' => '1.0.'.$i]); } // Create a mod and mod version, and then create a dependency for all versions of the dependent mod. @@ -205,7 +207,7 @@ it('handles a large number of versions efficiently', function () { ->and($executionTime)->toBeLessThan(5); // Arbitrarily picked out of my ass. })->skip('This is a performance test and is skipped by default. It will probably fail.'); -it('calls DependencyVersionService when a Mod is updated', function () { +it('calls DependencyVersionService when a Mod is updated', function (): void { $mod = Mod::factory()->create(); ModVersion::factory(2)->recycle($mod)->create(); @@ -221,7 +223,7 @@ it('calls DependencyVersionService when a Mod is updated', function () { } }); -it('calls DependencyVersionService when a Mod is deleted', function () { +it('calls DependencyVersionService when a Mod is deleted', function (): void { $mod = Mod::factory()->create(); ModVersion::factory(2)->recycle($mod)->create(); @@ -237,7 +239,7 @@ it('calls DependencyVersionService when a Mod is deleted', function () { } }); -it('calls DependencyVersionService when a ModVersion is updated', function () { +it('calls DependencyVersionService when a ModVersion is updated', function (): void { $modVersion = ModVersion::factory()->create(); $serviceSpy = $this->spy(DependencyVersionService::class); @@ -247,7 +249,7 @@ it('calls DependencyVersionService when a ModVersion is updated', function () { $serviceSpy->shouldHaveReceived('resolve'); }); -it('calls DependencyVersionService when a ModVersion is deleted', function () { +it('calls DependencyVersionService when a ModVersion is deleted', function (): void { $modVersion = ModVersion::factory()->create(); $serviceSpy = $this->spy(DependencyVersionService::class); @@ -257,7 +259,7 @@ it('calls DependencyVersionService when a ModVersion is deleted', function () { $serviceSpy->shouldHaveReceived('resolve'); }); -it('calls DependencyVersionService when a ModDependency is updated', function () { +it('calls DependencyVersionService when a ModDependency is updated', function (): void { $modVersion = ModVersion::factory()->create(['version' => '1.0.0']); $dependentMod = Mod::factory()->create(); $modDependency = ModDependency::factory()->recycle([$modVersion, $dependentMod])->create([ @@ -271,7 +273,7 @@ it('calls DependencyVersionService when a ModDependency is updated', function () $serviceSpy->shouldHaveReceived('resolve'); }); -it('calls DependencyVersionService when a ModDependency is deleted', function () { +it('calls DependencyVersionService when a ModDependency is deleted', function (): void { $modVersion = ModVersion::factory()->create(['version' => '1.0.0']); $dependentMod = Mod::factory()->create(); $modDependency = ModDependency::factory()->recycle([$modVersion, $dependentMod])->create([ @@ -285,7 +287,7 @@ it('calls DependencyVersionService when a ModDependency is deleted', function () $serviceSpy->shouldHaveReceived('resolve'); }); -it('displays the latest resolved dependencies on the mod detail page', function () { +it('displays the latest resolved dependencies on the mod detail page', function (): void { $dependentMod1 = Mod::factory()->create(); $dependentMod1Version1 = ModVersion::factory()->recycle($dependentMod1)->create(['version' => '1.0.0']); $dependentMod1Version2 = ModVersion::factory()->recycle($dependentMod1)->create(['version' => '2.0.0']); @@ -311,6 +313,6 @@ it('displays the latest resolved dependencies on the mod detail page', function $response = $this->get(route('mod.show', ['mod' => $mod->id, 'slug' => $mod->slug])); - $response->assertSeeInOrder(explode(' ', __('Dependencies: ')."$dependentMod1->name ($dependentMod1Version2->version)")); - $response->assertSeeInOrder(explode(' ', __('Dependencies: ')."$dependentMod2->name ($dependentMod2Version4->version)")); + $response->assertSeeInOrder(explode(' ', __('Dependencies: ').sprintf('%s (%s)', $dependentMod1->name, $dependentMod1Version2->version))); + $response->assertSeeInOrder(explode(' ', __('Dependencies: ').sprintf('%s (%s)', $dependentMod2->name, $dependentMod2Version4->version))); }); diff --git a/tests/Feature/Mod/ModFilterTest.php b/tests/Feature/Mod/ModFilterTest.php index a2b5b26..df22322 100644 --- a/tests/Feature/Mod/ModFilterTest.php +++ b/tests/Feature/Mod/ModFilterTest.php @@ -1,5 +1,7 @@ create(['version' => '1.0.0']); $sptVersion2 = SptVersion::factory()->create(['version' => '2.0.0']); @@ -35,7 +37,7 @@ it('filters mods by a single SPT version', function () { ->and($filteredMods->first()->id)->toBe($mod1->id); }); -it('filters mods by multiple SPT versions', function () { +it('filters mods by multiple SPT versions', function (): void { // Create the SPT versions $sptVersion1 = SptVersion::factory()->create(['version' => '1.0.0']); $sptVersion2 = SptVersion::factory()->create(['version' => '2.0.0']); @@ -71,7 +73,7 @@ it('filters mods by multiple SPT versions', function () { ->and($filteredMods->pluck('id')->toArray())->toContain($mod1->id, $mod3->id); }); -it('returns no mods when no SPT versions match', function () { +it('returns no mods when no SPT versions match', function (): void { // Create the SPT versions $sptVersion1 = SptVersion::factory()->create(['version' => '1.0.0']); $sptVersion2 = SptVersion::factory()->create(['version' => '2.0.0']); @@ -99,7 +101,7 @@ it('returns no mods when no SPT versions match', function () { expect($filteredMods)->toBeEmpty(); }); -it('filters mods based on a exact search term', function () { +it('filters mods based on a exact search term', function (): void { SptVersion::factory()->create(['version' => '1.0.0']); $mod = Mod::factory()->create(['name' => 'BigBrain']); @@ -114,7 +116,7 @@ it('filters mods based on a exact search term', function () { expect($filteredMods)->toHaveCount(1)->and($filteredMods->first()->id)->toBe($mod->id); }); -it('filters mods based featured status', function () { +it('filters mods based featured status', function (): void { SptVersion::factory()->create(['version' => '1.0.0']); $mod = Mod::factory()->create(['name' => 'BigBrain', 'featured' => true]); @@ -129,7 +131,7 @@ it('filters mods based featured status', function () { expect($filteredMods)->toHaveCount(1)->and($filteredMods->first()->id)->toBe($mod->id); }); -it('filters mods correctly with combined filters', function () { +it('filters mods correctly with combined filters', function (): void { // Create the SPT versions $sptVersion1 = SptVersion::factory()->create(['version' => '1.0.0']); $sptVersion2 = SptVersion::factory()->create(['version' => '2.0.0']); @@ -161,7 +163,7 @@ it('filters mods correctly with combined filters', function () { expect($filteredMods)->toHaveCount(1)->and($filteredMods->first()->id)->toBe($mod1->id); }); -it('handles an empty SPT versions array correctly', function () { +it('handles an empty SPT versions array correctly', function (): void { // Create the SPT versions $sptVersion1 = SptVersion::factory()->create(['version' => '1.0.0']); $sptVersion2 = SptVersion::factory()->create(['version' => '2.0.0']); diff --git a/tests/Feature/Mod/ModTest.php b/tests/Feature/Mod/ModTest.php index aeb7355..81abb50 100644 --- a/tests/Feature/Mod/ModTest.php +++ b/tests/Feature/Mod/ModTest.php @@ -1,9 +1,11 @@ toBe('2.1.0'); // Assert the latest version is next to the mod's name - $response->assertSeeInOrder(explode(' ', "$mod->name $latestVersion")); + $response->assertSeeInOrder(explode(' ', sprintf('%s %s', $mod->name, $latestVersion))); // Assert the latest version is in the latest download button - $response->assertSeeText(__('Download Latest Version')." ($latestVersion)"); + $response->assertSeeText(__('Download Latest Version').sprintf(' (%s)', $latestVersion)); }); -it('builds download links using the latest mod version', function () { +it('builds download links using the latest mod version', function (): void { $mod = Mod::factory()->create(['id' => 1, 'slug' => 'test-mod']); ModVersion::factory()->recycle($mod)->create(['version' => '1.2.3']); ModVersion::factory()->recycle($mod)->create(['version' => '1.3.0']); diff --git a/tests/Feature/Mod/ModVersionTest.php b/tests/Feature/Mod/ModVersionTest.php index ebbdd58..807798a 100644 --- a/tests/Feature/Mod/ModVersionTest.php +++ b/tests/Feature/Mod/ModVersionTest.php @@ -1,5 +1,7 @@ create(['version' => '1.0.0']); SptVersion::factory()->create(['version' => '1.1.0']); SptVersion::factory()->create(['version' => '1.1.1']); @@ -24,7 +26,7 @@ it('resolves spt versions when mod version is created', function () { ->and($sptVersions->pluck('version'))->toContain('1.1.0', '1.1.1'); }); -it('resolves spt versions when constraint is updated', function () { +it('resolves spt versions when constraint is updated', function (): void { SptVersion::factory()->create(['version' => '1.0.0']); SptVersion::factory()->create(['version' => '1.1.0']); SptVersion::factory()->create(['version' => '1.1.1']); @@ -50,7 +52,7 @@ it('resolves spt versions when constraint is updated', function () { ->and($sptVersions->pluck('version'))->toContain('1.2.0'); }); -it('resolves spt versions when spt version is created', function () { +it('resolves spt versions when spt version is created', function (): void { SptVersion::factory()->create(['version' => '1.0.0']); SptVersion::factory()->create(['version' => '1.1.0']); SptVersion::factory()->create(['version' => '1.1.1']); @@ -75,7 +77,7 @@ it('resolves spt versions when spt version is created', function () { ->and($sptVersions->pluck('version'))->toContain('1.1.0', '1.1.1', '1.1.2'); }); -it('resolves spt versions when spt version is deleted', function () { +it('resolves spt versions when spt version is deleted', function (): void { SptVersion::factory()->create(['version' => '1.0.0']); SptVersion::factory()->create(['version' => '1.1.0']); SptVersion::factory()->create(['version' => '1.1.1']); @@ -84,6 +86,7 @@ it('resolves spt versions when spt version is deleted', function () { $modVersion = ModVersion::factory()->create(['spt_version_constraint' => '~1.1.0']); $modVersion->refresh(); + $sptVersions = $modVersion->sptVersions; expect($sptVersions)->toHaveCount(3) @@ -98,7 +101,7 @@ it('resolves spt versions when spt version is deleted', function () { ->and($sptVersions->pluck('version'))->toContain('1.1.0', '1.1.1'); }); -it('includes only published mod versions', function () { +it('includes only published mod versions', function (): void { $publishedMod = ModVersion::factory()->create([ 'published_at' => Carbon::now()->subDay(), ]); @@ -120,7 +123,7 @@ it('includes only published mod versions', function () { ->and($mods->contains($noPublishedDateMod))->toBeFalse(); }); -it('handles null published_at as not published', function () { +it('handles null published_at as not published', function (): void { $modWithNoPublishDate = ModVersion::factory()->create([ 'published_at' => null, ]); @@ -130,11 +133,11 @@ it('handles null published_at as not published', function () { expect($mods->contains($modWithNoPublishDate))->toBeFalse(); }); -it('updates the parent mods updated_at column when updated', function () { +it('updates the parent mods updated_at column when updated', function (): void { $originalDate = now()->subDays(10); $version = ModVersion::factory()->create(['updated_at' => $originalDate]); - $version->downloads++; + ++$version->downloads; $version->save(); $version->refresh(); @@ -143,18 +146,18 @@ it('updates the parent mods updated_at column when updated', function () { ->and($version->mod->updated_at->format('Y-m-d'))->toEqual(now()->format('Y-m-d')); }); -it('builds download links using the specified version', function () { +it('builds download links using the specified version', function (): void { $mod = Mod::factory()->create(['id' => 1, 'slug' => 'test-mod']); $modVersion1 = ModVersion::factory()->recycle($mod)->create(['version' => '1.2.3']); $modVersion2 = ModVersion::factory()->recycle($mod)->create(['version' => '1.3.0']); $modVersion3 = ModVersion::factory()->recycle($mod)->create(['version' => '1.3.4']); - expect($modVersion1->downloadUrl())->toEqual("/mod/download/$mod->id/$mod->slug/$modVersion1->version") - ->and($modVersion2->downloadUrl())->toEqual("/mod/download/$mod->id/$mod->slug/$modVersion2->version") - ->and($modVersion3->downloadUrl())->toEqual("/mod/download/$mod->id/$mod->slug/$modVersion3->version"); + expect($modVersion1->downloadUrl())->toEqual(sprintf('/mod/download/%s/%s/%s', $mod->id, $mod->slug, $modVersion1->version)) + ->and($modVersion2->downloadUrl())->toEqual(sprintf('/mod/download/%s/%s/%s', $mod->id, $mod->slug, $modVersion2->version)) + ->and($modVersion3->downloadUrl())->toEqual(sprintf('/mod/download/%s/%s/%s', $mod->id, $mod->slug, $modVersion3->version)); }); -it('increments download counts when downloaded', function () { +it('increments download counts when downloaded', function (): void { $mod = Mod::factory()->create(['downloads' => 0]); $modVersion = ModVersion::factory()->recycle($mod)->create(['downloads' => 0]); @@ -167,12 +170,12 @@ it('increments download counts when downloaded', function () { ->and($modVersion->mod->downloads)->toEqual(1); }); -it('rate limits download links from being hit', function () { +it('rate limits download links from being hit', function (): void { $mod = Mod::factory()->create(['downloads' => 0]); $modVersion = ModVersion::factory()->recycle($mod)->create(['downloads' => 0]); // The first 5 requests should be fine. - for ($i = 0; $i < 5; $i++) { + for ($i = 0; $i < 5; ++$i) { $request = $this->get($modVersion->downloadUrl()); $request->assertStatus(307); } diff --git a/tests/Feature/Mod/SptVersionTest.php b/tests/Feature/Mod/SptVersionTest.php index 0dc17d8..f0871fd 100644 --- a/tests/Feature/Mod/SptVersionTest.php +++ b/tests/Feature/Mod/SptVersionTest.php @@ -1,11 +1,13 @@ create(['version' => '1.1.1']); SptVersion::factory()->create(['version' => '1.2.0']); $version = SptVersion::factory()->create(['version' => '1.3.0']); @@ -15,7 +17,7 @@ it("returns true if the version is part of the latest version's minor releases", expect($version->isLatestMinor())->toBeTrue(); }); -it("returns false if the version is not part of the latest version's minor releases", function () { +it("returns false if the version is not part of the latest version's minor releases", function (): void { SptVersion::factory()->create(['version' => '1.1.1']); SptVersion::factory()->create(['version' => '1.2.0']); $version = SptVersion::factory()->create(['version' => '1.2.1']); @@ -25,7 +27,7 @@ it("returns false if the version is not part of the latest version's minor relea expect($version->isLatestMinor())->toBeFalse(); }); -it('returns false if there is no latest version in the database', function () { +it('returns false if there is no latest version in the database', function (): void { $version = SptVersion::factory()->make(['version' => '1.0.0']); expect($version->isLatestMinor())->toBeFalse(); diff --git a/tests/Feature/User/ApiTokenPermissionsTest.php b/tests/Feature/User/ApiTokenPermissionsTest.php index 6d2fcf0..a8ecfcd 100755 --- a/tests/Feature/User/ApiTokenPermissionsTest.php +++ b/tests/Feature/User/ApiTokenPermissionsTest.php @@ -1,12 +1,14 @@ actingAs($user = User::factory()->withPersonalTeam()->create()); } else { @@ -33,6 +35,4 @@ test('api token permissions can be updated', function () { ->can('delete')->toBeTrue() ->can('read')->toBeFalse() ->can('missing-permission')->toBeFalse(); -})->skip(function () { - return ! Features::hasApiFeatures(); -}, 'API support is not enabled.'); +})->skip(fn (): bool => ! Features::hasApiFeatures(), 'API support is not enabled.'); diff --git a/tests/Feature/User/AuthenticationTest.php b/tests/Feature/User/AuthenticationTest.php index e392fa6..5f508e1 100755 --- a/tests/Feature/User/AuthenticationTest.php +++ b/tests/Feature/User/AuthenticationTest.php @@ -1,14 +1,16 @@ get('/login'); $response->assertStatus(200); }); -test('users can authenticate using the login screen', function () { +test('users can authenticate using the login screen', function (): void { $user = User::factory()->create(); $response = $this->post('/login', [ @@ -20,7 +22,7 @@ test('users can authenticate using the login screen', function () { $response->assertRedirect(route('dashboard', absolute: false)); }); -test('users cannot authenticate with invalid password', function () { +test('users cannot authenticate with invalid password', function (): void { $user = User::factory()->create(); $this->post('/login', [ @@ -31,14 +33,14 @@ test('users cannot authenticate with invalid password', function () { $this->assertGuest(); }); -test('users can authenticate using Discord', function () { +test('users can authenticate using Discord', function (): void { $response = $this->get(route('login.socialite', ['provider' => 'discord'])); $response->assertStatus(302); $response->assertRedirect(); }); -test('user can not authenticate using a null password', function () { +test('user can not authenticate using a null password', function (): void { $user = User::factory()->create(); $response = $this->post('/login', [ diff --git a/tests/Feature/User/BrowserSessionsTest.php b/tests/Feature/User/BrowserSessionsTest.php index 5f6e5f6..209ead6 100755 --- a/tests/Feature/User/BrowserSessionsTest.php +++ b/tests/Feature/User/BrowserSessionsTest.php @@ -1,10 +1,12 @@ actingAs(User::factory()->create()); Livewire::test(LogoutOtherBrowserSessionsForm::class) diff --git a/tests/Feature/User/CreateApiTokenTest.php b/tests/Feature/User/CreateApiTokenTest.php index 6168895..0e9f792 100755 --- a/tests/Feature/User/CreateApiTokenTest.php +++ b/tests/Feature/User/CreateApiTokenTest.php @@ -1,11 +1,13 @@ actingAs($user = User::factory()->withPersonalTeam()->create()); } else { @@ -27,6 +29,4 @@ test('api tokens can be created', function () { ->name->toEqual('Test Token') ->can('read')->toBeTrue() ->can('delete')->toBeFalse(); -})->skip(function () { - return ! Features::hasApiFeatures(); -}, 'API support is not enabled.'); +})->skip(fn (): bool => ! Features::hasApiFeatures(), 'API support is not enabled.'); diff --git a/tests/Feature/User/DeleteAccountTest.php b/tests/Feature/User/DeleteAccountTest.php index 80d14df..161ac10 100755 --- a/tests/Feature/User/DeleteAccountTest.php +++ b/tests/Feature/User/DeleteAccountTest.php @@ -1,11 +1,13 @@ actingAs($user = User::factory()->create()); Livewire::test(DeleteUserForm::class) @@ -13,11 +15,9 @@ test('user accounts can be deleted', function () { ->call('deleteUser'); expect($user->fresh())->toBeNull(); -})->skip(function () { - return ! Features::hasAccountDeletionFeatures(); -}, 'Account deletion is not enabled.'); +})->skip(fn (): bool => ! Features::hasAccountDeletionFeatures(), 'Account deletion is not enabled.'); -test('correct password must be provided before account can be deleted', function () { +test('correct password must be provided before account can be deleted', function (): void { $this->actingAs($user = User::factory()->create()); Livewire::test(DeleteUserForm::class) @@ -26,6 +26,4 @@ test('correct password must be provided before account can be deleted', function ->assertHasErrors(['password']); expect($user->fresh())->not->toBeNull(); -})->skip(function () { - return ! Features::hasAccountDeletionFeatures(); -}, 'Account deletion is not enabled.'); +})->skip(fn (): bool => ! Features::hasAccountDeletionFeatures(), 'Account deletion is not enabled.'); diff --git a/tests/Feature/User/DeleteApiTokenTest.php b/tests/Feature/User/DeleteApiTokenTest.php index 7f38922..5d0f0b1 100755 --- a/tests/Feature/User/DeleteApiTokenTest.php +++ b/tests/Feature/User/DeleteApiTokenTest.php @@ -1,12 +1,14 @@ actingAs($user = User::factory()->withPersonalTeam()->create()); } else { @@ -24,6 +26,4 @@ test('api tokens can be deleted', function () { ->call('deleteApiToken'); expect($user->fresh()->tokens)->toHaveCount(0); -})->skip(function () { - return ! Features::hasApiFeatures(); -}, 'API support is not enabled.'); +})->skip(fn (): bool => ! Features::hasApiFeatures(), 'API support is not enabled.'); diff --git a/tests/Feature/User/EmailVerificationTest.php b/tests/Feature/User/EmailVerificationTest.php index e743624..ba4fb5f 100755 --- a/tests/Feature/User/EmailVerificationTest.php +++ b/tests/Feature/User/EmailVerificationTest.php @@ -1,12 +1,14 @@ create([ 'email_verified_at' => null, ]); @@ -14,11 +16,9 @@ test('email verification screen can be rendered', function () { $response = $this->actingAs($user)->get('/email/verify'); $response->assertStatus(200); -})->skip(function () { - return ! Features::enabled(Features::emailVerification()); -}, 'Email verification not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::emailVerification()), 'Email verification not enabled.'); -test('email can be verified', function () { +test('email can be verified', function (): void { Event::fake(); $user = User::factory()->create([ @@ -28,7 +28,7 @@ test('email can be verified', function () { $verificationUrl = URL::temporarySignedRoute( 'verification.verify', now()->addMinutes(60), - ['id' => $user->id, 'hash' => sha1($user->email)] + ['id' => $user->id, 'hash' => sha1((string) $user->email)] ); $response = $this->actingAs($user)->get($verificationUrl); @@ -37,11 +37,9 @@ test('email can be verified', function () { expect($user->fresh()->hasVerifiedEmail())->toBeTrue(); $response->assertRedirect(route('dashboard', absolute: false).'?verified=1'); -})->skip(function () { - return ! Features::enabled(Features::emailVerification()); -}, 'Email verification not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::emailVerification()), 'Email verification not enabled.'); -test('email can not verified with invalid hash', function () { +test('email can not verified with invalid hash', function (): void { $user = User::factory()->create([ 'email_verified_at' => null, ]); @@ -55,6 +53,4 @@ test('email can not verified with invalid hash', function () { $this->actingAs($user)->get($verificationUrl); expect($user->fresh()->hasVerifiedEmail())->toBeFalse(); -})->skip(function () { - return ! Features::enabled(Features::emailVerification()); -}, 'Email verification not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::emailVerification()), 'Email verification not enabled.'); diff --git a/tests/Feature/User/FollowTest.php b/tests/Feature/User/FollowTest.php index d86275c..070a8af 100644 --- a/tests/Feature/User/FollowTest.php +++ b/tests/Feature/User/FollowTest.php @@ -1,8 +1,10 @@ create(); $user->follow($user); @@ -11,7 +13,7 @@ test('confirm a user cannot follow themself', function () { $this->assertEmpty($user->following); }); -test('confirm a user can follow and unfollow another user', function () { +test('confirm a user can follow and unfollow another user', function (): void { $user1 = User::factory()->create(); $user2 = User::factory()->create(); @@ -24,7 +26,7 @@ test('confirm a user can follow and unfollow another user', function () { $this->assertFalse($user1->isFollowing($user2)); }); -test('confirm following a user cannot be done twice', function () { +test('confirm following a user cannot be done twice', function (): void { $user1 = User::factory()->create(); $user2 = User::factory()->create(); @@ -35,7 +37,7 @@ test('confirm following a user cannot be done twice', function () { $this->assertCount(1, $user2->followers); }); -test('confirm unfollowing a user that isnt being followed doesnt throw', function () { +test('confirm unfollowing a user that isnt being followed doesnt throw', function (): void { $user1 = User::factory()->create(); $user2 = User::factory()->create(); @@ -45,7 +47,7 @@ test('confirm unfollowing a user that isnt being followed doesnt throw', functio $this->assertEmpty($user2->followers); }); -test('confirm unfollowing random number doesnt perform detach all', function () { +test('confirm unfollowing random number doesnt perform detach all', function (): void { $user1 = User::factory()->create(); $user2 = User::factory()->create(); $user3 = User::factory()->create(); @@ -66,7 +68,7 @@ test('confirm unfollowing random number doesnt perform detach all', function () $this->assertTrue($user1->isFollowing($user3)); }); -test('confirm null follow input fails', function () { +test('confirm null follow input fails', function (): void { $this->expectException(TypeError::class); $user = User::factory()->create(); @@ -74,7 +76,7 @@ test('confirm null follow input fails', function () { $user->follow(null); }); -test('confirm empty follow input fails', function () { +test('confirm empty follow input fails', function (): void { $this->expectException(ArgumentCountError::class); $user = User::factory()->create(); @@ -82,7 +84,7 @@ test('confirm empty follow input fails', function () { $user->follow(); }); -test('confirm null unfollow input fails', function () { +test('confirm null unfollow input fails', function (): void { $this->expectException(TypeError::class); $user = User::factory()->create(); @@ -90,7 +92,7 @@ test('confirm null unfollow input fails', function () { $user->unfollow(null); }); -test('confirm empty unfollow input fails', function () { +test('confirm empty unfollow input fails', function (): void { $this->expectException(ArgumentCountError::class); $user = User::factory()->create(); diff --git a/tests/Feature/User/OAuthAccountTest.php b/tests/Feature/User/OAuthAccountTest.php index f1689da..f1abcb7 100644 --- a/tests/Feature/User/OAuthAccountTest.php +++ b/tests/Feature/User/OAuthAccountTest.php @@ -1,23 +1,25 @@ shouldReceive('getId')->andReturn('provider-user-id'); - $socialiteUser->shouldReceive('getEmail')->andReturn('newuser@example.com'); - $socialiteUser->shouldReceive('getName')->andReturn('New User'); - $socialiteUser->shouldReceive('getNickname')->andReturn(null); - $socialiteUser->shouldReceive('getAvatar')->andReturn('avatar-url'); - $socialiteUser->token = 'access-token'; - $socialiteUser->refreshToken = 'refresh-token'; + $mock = Mockery::mock(SocialiteUser::class); + $mock->shouldReceive('getId')->andReturn('provider-user-id'); + $mock->shouldReceive('getEmail')->andReturn('newuser@example.com'); + $mock->shouldReceive('getName')->andReturn('New User'); + $mock->shouldReceive('getNickname')->andReturn(null); + $mock->shouldReceive('getAvatar')->andReturn('avatar-url'); + $mock->token = 'access-token'; + $mock->refreshToken = 'refresh-token'; // Mock Socialite facade - Socialite::shouldReceive('driver->user')->andReturn($socialiteUser); + Socialite::shouldReceive('driver->user')->andReturn($mock); // Hit the callback route $response = $this->get('/login/discord/callback'); @@ -39,7 +41,7 @@ it('creates a new user and attaches the OAuth provider when logging in via OAuth $response->assertRedirect(route('dashboard')); }); -it('attaches a new OAuth provider to an existing user when logging in via OAuth', function () { +it('attaches a new OAuth provider to an existing user when logging in via OAuth', function (): void { // Create an existing user $user = User::factory()->create([ 'email' => 'existinguser@example.com', @@ -48,17 +50,17 @@ it('attaches a new OAuth provider to an existing user when logging in via OAuth' ]); // Mock the Socialite user - $socialiteUser = Mockery::mock(SocialiteUser::class); - $socialiteUser->shouldReceive('getId')->andReturn('new-provider-user-id'); - $socialiteUser->shouldReceive('getEmail')->andReturn('existinguser@example.com'); - $socialiteUser->shouldReceive('getName')->andReturn('Existing User Updated'); - $socialiteUser->shouldReceive('getNickname')->andReturn(null); - $socialiteUser->shouldReceive('getAvatar')->andReturn('new-avatar-url'); - $socialiteUser->token = 'new-access-token'; - $socialiteUser->refreshToken = 'new-refresh-token'; + $mock = Mockery::mock(SocialiteUser::class); + $mock->shouldReceive('getId')->andReturn('new-provider-user-id'); + $mock->shouldReceive('getEmail')->andReturn('existinguser@example.com'); + $mock->shouldReceive('getName')->andReturn('Existing User Updated'); + $mock->shouldReceive('getNickname')->andReturn(null); + $mock->shouldReceive('getAvatar')->andReturn('new-avatar-url'); + $mock->token = 'new-access-token'; + $mock->refreshToken = 'new-refresh-token'; // Mock Socialite facade - Socialite::shouldReceive('driver->user')->andReturn($socialiteUser); + Socialite::shouldReceive('driver->user')->andReturn($mock); // Hit the callback route $response = $this->get('/login/discord/callback'); @@ -82,7 +84,7 @@ it('attaches a new OAuth provider to an existing user when logging in via OAuth' $response->assertRedirect(route('dashboard')); }); -it('hides the current password field when the user has no password', function () { +it('hides the current password field when the user has no password', function (): void { // Create a user with no password $user = User::factory()->create([ 'password' => null, @@ -98,7 +100,7 @@ it('hides the current password field when the user has no password', function () $response->assertDontSee(__('Current Password')); }); -it('shows the current password field when the user has a password', function () { +it('shows the current password field when the user has a password', function (): void { // Create a user with a password $user = User::factory()->create([ 'password' => bcrypt('password123'), @@ -114,7 +116,7 @@ it('shows the current password field when the user has a password', function () $response->assertSee(__('Current Password')); }); -it('allows a user without a password to set a new password without entering the current password', function () { +it('allows a user without a password to set a new password without entering the current password', function (): void { // Create a user with a NULL password $user = User::factory()->create([ 'password' => null, @@ -136,7 +138,7 @@ it('allows a user without a password to set a new password without entering the expect(Hash::check('newpassword123', $user->password))->toBeTrue(); }); -it('requires a user with a password to enter the current password to set a new password', function () { +it('requires a user with a password to enter the current password to set a new password', function (): void { $user = User::factory()->create([ 'password' => Hash::make('oldpassword'), ]); diff --git a/tests/Feature/User/PasswordConfirmationTest.php b/tests/Feature/User/PasswordConfirmationTest.php index 009a462..ee1846d 100755 --- a/tests/Feature/User/PasswordConfirmationTest.php +++ b/tests/Feature/User/PasswordConfirmationTest.php @@ -1,9 +1,11 @@ withPersonalTeam()->create() : User::factory()->create(); @@ -13,7 +15,7 @@ test('confirm password screen can be rendered', function () { $response->assertStatus(200); }); -test('password can be confirmed', function () { +test('password can be confirmed', function (): void { $user = User::factory()->create(); $response = $this->actingAs($user)->post('/user/confirm-password', [ @@ -24,7 +26,7 @@ test('password can be confirmed', function () { $response->assertSessionHasNoErrors(); }); -test('password is not confirmed with invalid password', function () { +test('password is not confirmed with invalid password', function (): void { $user = User::factory()->create(); $response = $this->actingAs($user)->post('/user/confirm-password', [ diff --git a/tests/Feature/User/PasswordResetTest.php b/tests/Feature/User/PasswordResetTest.php index ec3362e..c36cdc6 100755 --- a/tests/Feature/User/PasswordResetTest.php +++ b/tests/Feature/User/PasswordResetTest.php @@ -1,19 +1,19 @@ get('/forgot-password'); $response->assertStatus(200); -})->skip(function () { - return ! Features::enabled(Features::resetPasswords()); -}, 'Password updates are not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::resetPasswords()), 'Password updates are not enabled.'); -test('reset password link can be requested', function () { +test('reset password link can be requested', function (): void { Notification::fake(); $user = User::factory()->create(); @@ -23,11 +23,9 @@ test('reset password link can be requested', function () { ]); Notification::assertSentTo($user, ResetPassword::class); -})->skip(function () { - return ! Features::enabled(Features::resetPasswords()); -}, 'Password updates are not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::resetPasswords()), 'Password updates are not enabled.'); -test('reset password screen can be rendered', function () { +test('reset password screen can be rendered', function (): void { Notification::fake(); $user = User::factory()->create(); @@ -36,18 +34,16 @@ test('reset password screen can be rendered', function () { 'email' => $user->email, ]); - Notification::assertSentTo($user, ResetPassword::class, function (object $notification) { + Notification::assertSentTo($user, ResetPassword::class, function (object $notification): true { $response = $this->get('/reset-password/'.$notification->token); $response->assertStatus(200); return true; }); -})->skip(function () { - return ! Features::enabled(Features::resetPasswords()); -}, 'Password updates are not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::resetPasswords()), 'Password updates are not enabled.'); -test('password can be reset with valid token', function () { +test('password can be reset with valid token', function (): void { Notification::fake(); $user = User::factory()->create(); @@ -56,7 +52,7 @@ test('password can be reset with valid token', function () { 'email' => $user->email, ]); - Notification::assertSentTo($user, ResetPassword::class, function (object $notification) use ($user) { + Notification::assertSentTo($user, ResetPassword::class, function (object $notification) use ($user): true { $response = $this->post('/reset-password', [ 'token' => $notification->token, 'email' => $user->email, @@ -68,6 +64,4 @@ test('password can be reset with valid token', function () { return true; }); -})->skip(function () { - return ! Features::enabled(Features::resetPasswords()); -}, 'Password updates are not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::resetPasswords()), 'Password updates are not enabled.'); diff --git a/tests/Feature/User/ProfileInformationTest.php b/tests/Feature/User/ProfileInformationTest.php index c549497..d03e54f 100755 --- a/tests/Feature/User/ProfileInformationTest.php +++ b/tests/Feature/User/ProfileInformationTest.php @@ -1,19 +1,21 @@ actingAs($user = User::factory()->create()); - $component = Livewire::test(UpdateProfileInformationForm::class); + $testable = Livewire::test(UpdateProfileInformationForm::class); - expect($component->state['name'])->toEqual($user->name); - expect($component->state['email'])->toEqual($user->email); + expect($testable->state['name'])->toEqual($user->name); + expect($testable->state['email'])->toEqual($user->email); }); -test('profile information can be updated', function () { +test('profile information can be updated', function (): void { $this->actingAs($user = User::factory()->create()); Livewire::test(UpdateProfileInformationForm::class) diff --git a/tests/Feature/User/RegistrationTest.php b/tests/Feature/User/RegistrationTest.php index c1b9ea9..78bb71b 100755 --- a/tests/Feature/User/RegistrationTest.php +++ b/tests/Feature/User/RegistrationTest.php @@ -1,25 +1,23 @@ get('/register'); $response->assertStatus(200); -})->skip(function () { - return ! Features::enabled(Features::registration()); -}, 'Registration support is not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::registration()), 'Registration support is not enabled.'); -test('registration screen cannot be rendered if support is disabled', function () { +test('registration screen cannot be rendered if support is disabled', function (): void { $response = $this->get('/register'); $response->assertStatus(404); -})->skip(function () { - return Features::enabled(Features::registration()); -}, 'Registration support is enabled.'); +})->skip(fn () => Features::enabled(Features::registration()), 'Registration support is enabled.'); -test('new users can register', function () { +test('new users can register', function (): void { $response = $this->post('/register', [ 'name' => 'Test User', 'email' => 'test@example.com', @@ -30,6 +28,4 @@ test('new users can register', function () { $this->assertAuthenticated(); $response->assertRedirect(route('dashboard', absolute: false)); -})->skip(function () { - return ! Features::enabled(Features::registration()); -}, 'Registration support is not enabled.'); +})->skip(fn (): bool => ! Features::enabled(Features::registration()), 'Registration support is not enabled.'); diff --git a/tests/Feature/User/TwoFactorAuthenticationSettingsTest.php b/tests/Feature/User/TwoFactorAuthenticationSettingsTest.php index 96da66a..669ea45 100755 --- a/tests/Feature/User/TwoFactorAuthenticationSettingsTest.php +++ b/tests/Feature/User/TwoFactorAuthenticationSettingsTest.php @@ -1,11 +1,13 @@ actingAs($user = User::factory()->create()->fresh()); $this->withSession(['auth.password_confirmed_at' => time()]); @@ -17,11 +19,9 @@ test('two factor authentication can be enabled', function () { expect($user->two_factor_secret)->not->toBeNull(); expect($user->recoveryCodes())->toHaveCount(8); -})->skip(function () { - return ! Features::canManageTwoFactorAuthentication(); -}, 'Two factor authentication is not enabled.'); +})->skip(fn (): bool => ! Features::canManageTwoFactorAuthentication(), 'Two factor authentication is not enabled.'); -test('recovery codes can be regenerated', function () { +test('recovery codes can be regenerated', function (): void { $this->actingAs($user = User::factory()->create()->fresh()); $this->withSession(['auth.password_confirmed_at' => time()]); @@ -36,11 +36,9 @@ test('recovery codes can be regenerated', function () { expect($user->recoveryCodes())->toHaveCount(8); expect(array_diff($user->recoveryCodes(), $user->fresh()->recoveryCodes()))->toHaveCount(8); -})->skip(function () { - return ! Features::canManageTwoFactorAuthentication(); -}, 'Two factor authentication is not enabled.'); +})->skip(fn (): bool => ! Features::canManageTwoFactorAuthentication(), 'Two factor authentication is not enabled.'); -test('two factor authentication can be disabled', function () { +test('two factor authentication can be disabled', function (): void { $this->actingAs($user = User::factory()->create()->fresh()); $this->withSession(['auth.password_confirmed_at' => time()]); @@ -53,6 +51,4 @@ test('two factor authentication can be disabled', function () { $component->call('disableTwoFactorAuthentication'); expect($user->fresh()->two_factor_secret)->toBeNull(); -})->skip(function () { - return ! Features::canManageTwoFactorAuthentication(); -}, 'Two factor authentication is not enabled.'); +})->skip(fn (): bool => ! Features::canManageTwoFactorAuthentication(), 'Two factor authentication is not enabled.'); diff --git a/tests/Feature/User/UpdatePasswordTest.php b/tests/Feature/User/UpdatePasswordTest.php index bd2400f..91ff5db 100755 --- a/tests/Feature/User/UpdatePasswordTest.php +++ b/tests/Feature/User/UpdatePasswordTest.php @@ -1,11 +1,13 @@ actingAs($user = User::factory()->create()); Livewire::test(UpdatePasswordForm::class) @@ -19,7 +21,7 @@ test('password can be updated', function () { expect(Hash::check('new-password', $user->fresh()->password))->toBeTrue(); }); -test('current password must be correct', function () { +test('current password must be correct', function (): void { $this->actingAs($user = User::factory()->create()); Livewire::test(UpdatePasswordForm::class) @@ -34,7 +36,7 @@ test('current password must be correct', function () { expect(Hash::check('password', $user->fresh()->password))->toBeTrue(); }); -test('new passwords must match', function () { +test('new passwords must match', function (): void { $this->actingAs($user = User::factory()->create()); Livewire::test(UpdatePasswordForm::class) diff --git a/tests/Pest.php b/tests/Pest.php index e2eb380..904fcbf 100755 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,5 +1,7 @@ in('Feature'); | */ -expect()->extend('toBeOne', function () { - return $this->toBe(1); -}); +expect()->extend('toBeOne', fn () => $this->toBe(1)); /* |-------------------------------------------------------------------------- @@ -42,7 +42,7 @@ expect()->extend('toBeOne', function () { | */ -function something() +function something(): void { // .. } diff --git a/tests/TestCase.php b/tests/TestCase.php index fe1ffc2..6ac0072 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,5 +1,7 @@ toBe(true); });