diff --git a/src/app/User/Domain/RepositoryInterface/UserRepositoryInterface.php b/src/app/User/Domain/RepositoryInterface/UserRepositoryInterface.php index 04d6f13..3f4d87b 100644 --- a/src/app/User/Domain/RepositoryInterface/UserRepositoryInterface.php +++ b/src/app/User/Domain/RepositoryInterface/UserRepositoryInterface.php @@ -23,4 +23,10 @@ public function savePasswordResetToken( UserId $userId, PasswordResetToken $token ): void; + + public function resetPassword( + UserId $userId, + PasswordResetToken $token, + string $newPassword + ): void; } \ No newline at end of file diff --git a/src/app/User/Infrastructure/InfrastructureTest/UserRepository_resetPasswordTest.php b/src/app/User/Infrastructure/InfrastructureTest/UserRepository_resetPasswordTest.php new file mode 100644 index 0000000..b2c3842 --- /dev/null +++ b/src/app/User/Infrastructure/InfrastructureTest/UserRepository_resetPasswordTest.php @@ -0,0 +1,96 @@ +refresh(); + $this->user = $this->createUser(); + $this->repository = new UserRepository( + new BcryptPasswordHasher(), + $this->user + ); + } + + protected function tearDown(): void + { + $this->refresh(); + parent::tearDown(); + } + + private function refresh(): void + { + if (env('APP_ENV') === 'testing') { + DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=0;'); + User::truncate(); + PasswordResetRequest::truncate(); + DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;'); + } + } + + private function createUser(): User + { + return User::create([ + 'first_name' => 'Sergio', + 'last_name' => 'Ramos', + 'email' => 'real-madrid15@test.com', + 'password' => 'el-capitán-1234', + 'bio' => 'Real Madrid player', + 'location' => 'Madrid', + 'skills' => ['Football', 'Leadership'], + 'profile_image' => 'https://example.com/sergio.jpg' + ]); + } + + public function test_reset_password_ok(): void + { + $objectId = new UserId($this->user->id); + $token = new PasswordResetToken(bin2hex(random_bytes(32))); + $newPassword = 'test1234test1234test1234test1234'; + + $this->repository->savePasswordResetToken($objectId, $token); + + $this->repository->resetPassword($objectId, $token, $newPassword); + + $updatedUser = $this->user->find($this->user->id); + + $this->assertTrue( + Hash::check($newPassword, $updatedUser->password) + ); + } + + public function test_reset_password_invalid_userId(): void + { + $this->expectException(Exception::class); + + $objectId = new UserId(100); + $token = new PasswordResetToken(bin2hex(random_bytes(32))); + $newPassword = 'test1234test1234test1234test1234'; + + $this->repository->savePasswordResetToken($objectId, $token); + + $this->repository->resetPassword($objectId, $token, $newPassword); + + $updatedUser = $this->user->find($this->user->id); + + $this->assertTrue( + Hash::check($newPassword, $updatedUser->password) + ); + } +} \ No newline at end of file diff --git a/src/app/User/Infrastructure/Repository/UserRepository.php b/src/app/User/Infrastructure/Repository/UserRepository.php index 169d2bb..44042bd 100644 --- a/src/app/User/Infrastructure/Repository/UserRepository.php +++ b/src/app/User/Infrastructure/Repository/UserRepository.php @@ -117,4 +117,22 @@ public function savePasswordResetToken( ]); } } + + public function resetPassword( + UserId $userId, + PasswordResetToken $token, + string $newPassword + ): void { + $userModel = $this->user->find($userId->getValue()); + + if ($userModel === null) { + throw new Exception('User not found'); + } + + $hashedPassword = $this->hasher->hash($newPassword); + + $userModel->update([ + 'password' => $hashedPassword + ]); + } }