diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f11b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/src/app/Packages/Features/CommandUseCases/UseCase/User/UpdateUserUseCase.php b/src/app/Packages/Features/CommandUseCases/UseCase/User/UpdateUserUseCase.php new file mode 100644 index 0000000..a99e045 --- /dev/null +++ b/src/app/Packages/Features/CommandUseCases/UseCase/User/UpdateUserUseCase.php @@ -0,0 +1,30 @@ + $command->id, + 'first_name' => $command->firstName, + 'last_name' => $command->lastName, + 'email' => $command->email, + 'age_range' => $command->ageRange, + 'subscription_tier' => $command->subscriptionTier, + 'subscription_expires_at' => $command->subscriptionExpiresAt, + ]); + + return $this->userRepository->updateUser($entity); + } +} \ No newline at end of file diff --git a/src/app/Packages/Features/CommandUseCases/UseCommand/User/UpdateUserCommand.php b/src/app/Packages/Features/CommandUseCases/UseCommand/User/UpdateUserCommand.php new file mode 100644 index 0000000..4176a5c --- /dev/null +++ b/src/app/Packages/Features/CommandUseCases/UseCommand/User/UpdateUserCommand.php @@ -0,0 +1,46 @@ + $faker->unique()->randomNumber(5), + 'first_name' => $faker->firstName(), + 'last_name' => $faker->lastName(), + 'email' => $faker->unique()->safeEmail(), + 'age_range' => $faker->randomElement(['teens', '20s', '30s', '40s', '50s', '60plus']), + 'subscription_tier' => $faker->randomElement(['free', 'premium']), + ], $overrides); + } + + public function test_fromArray_creates_command_with_valid_data(): void + { + $data = $this->validData(); + $command = UpdateUserCommand::fromArray($data); + + $this->assertSame((int) $data['id'], $command->id); + $this->assertSame($data['first_name'], $command->firstName); + $this->assertSame($data['last_name'], $command->lastName); + $this->assertSame($data['email'], $command->email); + $this->assertSame($data['age_range'], $command->ageRange); + $this->assertSame($data['subscription_tier'], $command->subscriptionTier); + $this->assertNull($command->subscriptionExpiresAt); + } + + public function test_fromArray_sets_subscription_expires_at_when_provided(): void + { + $command = UpdateUserCommand::fromArray($this->validData([ + 'subscription_expires_at' => '2027-01-01 00:00:00', + ])); + + $this->assertSame('2027-01-01 00:00:00', $command->subscriptionExpiresAt); + } + + #[\PHPUnit\Framework\Attributes\DataProvider('missingKeyProvider')] + public function test_fromArray_throws_when_required_key_is_missing(string $missingKey): void + { + $data = $this->validData(); + unset($data[$missingKey]); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("Missing required key: {$missingKey}"); + + UpdateUserCommand::fromArray($data); + } + + public static function missingKeyProvider(): array + { + return [ + ['id'], + ['first_name'], + ['last_name'], + ['email'], + ['age_range'], + ['subscription_tier'], + ]; + } +} diff --git a/src/app/Packages/Features/Tests/CommandUseCases/UpdateUserUseCaseTest.php b/src/app/Packages/Features/Tests/CommandUseCases/UpdateUserUseCaseTest.php new file mode 100644 index 0000000..1c205db --- /dev/null +++ b/src/app/Packages/Features/Tests/CommandUseCases/UpdateUserUseCaseTest.php @@ -0,0 +1,68 @@ + $faker->unique()->randomNumber(5), + 'first_name' => $faker->firstName(), + 'last_name' => $faker->lastName(), + 'email' => $faker->unique()->safeEmail(), + 'age_range' => $faker->randomElement(['teens', '20s', '30s', '40s', '50s', '60plus']), + 'subscription_tier' => 'free', + ]); + } + + private function buildDto(): UserDto + { + $faker = FakerFactory::create(); + + return new UserDto( + id: $faker->unique()->randomNumber(5), + firstName: $faker->firstName(), + lastName: $faker->lastName(), + email: $faker->unique()->safeEmail(), + ageRange: 'teens', + subscriptionTier: 'free', + subscriptionExpiresAt: null, + ); + } + + public function test_handle_passes_entity_to_repository_and_returns_dto(): void + { + $command = $this->buildCommand(); + $dto = $this->buildDto(); + + /** @var UserRepositroyInterface|MockInterface $repository */ + $repository = Mockery::mock(UserRepositroyInterface::class); + $repository->shouldReceive('updateUser') + ->once() + ->with(Mockery::type(UserEntity::class)) + ->andReturn($dto); + + $result = (new UpdateUserUseCase($repository))->handle($command); + + $this->assertSame($dto, $result); + } +} \ No newline at end of file