From 857507abe50b2f5276caa426a0eb6d151b690102 Mon Sep 17 00:00:00 2001 From: Ondrej Vlach Date: Fri, 2 Aug 2024 14:13:25 +0200 Subject: [PATCH] feat(db): add entities --- src/Entity/Database/Comments/Comment.php | 32 ++++++++ src/Entity/Database/Posts/Post.php | 39 +++++++++ src/Entity/Database/Users/Address.php | 40 ++++++++++ src/Entity/Database/Users/Company.php | 39 +++++++++ src/Entity/Database/Users/User.php | 42 ++++++++++ .../Comments/CommentsRepository.php | 20 +++++ src/Repository/Post/PostRepository.php | 20 +++++ src/Repository/Users/AddressRepository.php | 20 +++++ src/Repository/Users/CompanyRepository.php | 40 ++++++++++ src/Repository/Users/UserRepository.php | 41 ++++++++++ tests/Common/DatabaseTestTrait.php | 49 ++++++++++++ tests/Common/FakerTrait.php | 27 +++++++ .../Generators/CommentGeneratorTrait.php | 34 ++++++++ .../Common/Generators/PostGeneratorTrait.php | 37 +++++++++ .../Common/Generators/UserGeneratorTrait.php | 55 +++++++++++++ tests/Db/Users/CompanyRepositoryTest.php | 79 +++++++++++++++++++ tests/Db/Users/UserRepositoryTest.php | 38 +++++++++ 17 files changed, 652 insertions(+) create mode 100644 src/Entity/Database/Comments/Comment.php create mode 100644 src/Entity/Database/Posts/Post.php create mode 100644 src/Entity/Database/Users/Address.php create mode 100644 src/Entity/Database/Users/Company.php create mode 100644 src/Entity/Database/Users/User.php create mode 100644 src/Repository/Comments/CommentsRepository.php create mode 100644 src/Repository/Post/PostRepository.php create mode 100644 src/Repository/Users/AddressRepository.php create mode 100644 src/Repository/Users/CompanyRepository.php create mode 100644 src/Repository/Users/UserRepository.php create mode 100644 tests/Common/DatabaseTestTrait.php create mode 100644 tests/Common/FakerTrait.php create mode 100644 tests/Common/Generators/CommentGeneratorTrait.php create mode 100644 tests/Common/Generators/PostGeneratorTrait.php create mode 100644 tests/Common/Generators/UserGeneratorTrait.php create mode 100644 tests/Db/Users/CompanyRepositoryTest.php create mode 100644 tests/Db/Users/UserRepositoryTest.php diff --git a/src/Entity/Database/Comments/Comment.php b/src/Entity/Database/Comments/Comment.php new file mode 100644 index 0000000..314c196 --- /dev/null +++ b/src/Entity/Database/Comments/Comment.php @@ -0,0 +1,32 @@ + $comments + */ + #[OneToMany(targetEntity: Comment::class, mappedBy: "post")] + public Collection $comments, + ) { + } +} diff --git a/src/Entity/Database/Users/Address.php b/src/Entity/Database/Users/Address.php new file mode 100644 index 0000000..d8e3ddc --- /dev/null +++ b/src/Entity/Database/Users/Address.php @@ -0,0 +1,40 @@ + $users + */ + #[OneToMany(targetEntity: User::class, mappedBy: 'company')] + public Collection $users, + // TODO: prepokladam ze tohle muzu povazovat za klic a vsechny dalsi parametry budou stejne pro kazdou company se stejnym jmenem + #[Column(type: "text", unique: true)] + public string $name, + #[Column(type: "text")] + public string $catchPhrase, + #[Column(type: "text")] + public string $bs, + ) { + } +} diff --git a/src/Entity/Database/Users/User.php b/src/Entity/Database/Users/User.php new file mode 100644 index 0000000..d4eff4f --- /dev/null +++ b/src/Entity/Database/Users/User.php @@ -0,0 +1,42 @@ +address->user)) { + $this->address->user = $this; + } + } +} diff --git a/src/Repository/Comments/CommentsRepository.php b/src/Repository/Comments/CommentsRepository.php new file mode 100644 index 0000000..a712e8b --- /dev/null +++ b/src/Repository/Comments/CommentsRepository.php @@ -0,0 +1,20 @@ + + */ +class CommentsRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Comment::class); + } +} diff --git a/src/Repository/Post/PostRepository.php b/src/Repository/Post/PostRepository.php new file mode 100644 index 0000000..e675952 --- /dev/null +++ b/src/Repository/Post/PostRepository.php @@ -0,0 +1,20 @@ + + */ +class PostRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Post::class); + } +} diff --git a/src/Repository/Users/AddressRepository.php b/src/Repository/Users/AddressRepository.php new file mode 100644 index 0000000..7e93f83 --- /dev/null +++ b/src/Repository/Users/AddressRepository.php @@ -0,0 +1,20 @@ + + */ +class AddressRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Address::class); + } +} diff --git a/src/Repository/Users/CompanyRepository.php b/src/Repository/Users/CompanyRepository.php new file mode 100644 index 0000000..288e3eb --- /dev/null +++ b/src/Repository/Users/CompanyRepository.php @@ -0,0 +1,40 @@ + + */ +class CompanyRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Company::class); + } + + /** + * Find company by name + * @param string $name + * @return Company|null + */ + public function findByName(string $name): ?Company + { + return $this->findOneBy(['name' => $name]); + } + + /** + * Delete companies with no associated users + * @return void + */ + public function deleteOrphanRecords(): void + { + $this->getEntityManager()->createQuery('DELETE FROM App\Entity\Database\Users\Company c WHERE NOT EXISTS (SELECT 1 FROM App\Entity\Database\Users\User u WHERE u.company = c.id)') + ->execute(); + } +} diff --git a/src/Repository/Users/UserRepository.php b/src/Repository/Users/UserRepository.php new file mode 100644 index 0000000..a68ed58 --- /dev/null +++ b/src/Repository/Users/UserRepository.php @@ -0,0 +1,41 @@ + + */ +class UserRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, User::class); + } + + /** + * Find users by IDs. If user not exists, will not be set in the result array. + * @param array $ids + * @return array + */ + public function findByIds(array $ids): array + { + $result = []; + $resultQ = $this->createQueryBuilder('u') + ->where('u.id IN (:ids)') + ->setParameter('ids', $ids) + ->getQuery() + ->getResult(); + + foreach ($resultQ as $user) { + $result[$user->id] = $user; + } + + return $result; + } +} diff --git a/tests/Common/DatabaseTestTrait.php b/tests/Common/DatabaseTestTrait.php new file mode 100644 index 0000000..af01a2e --- /dev/null +++ b/tests/Common/DatabaseTestTrait.php @@ -0,0 +1,49 @@ +getContainer()->get(EntityManagerInterface::class); + $this->em = $em; + $this->em->getConnection()->executeQuery(<<em === null) { + throw new \LogicException('Database has not been booted yet.'); + } + + return $this->em; + } + + protected function getEntityCount(string $entityClass): int + { + return (int) $this->getEntityManager()->createQuery('SELECT COUNT(e) FROM ' . $entityClass . ' e')->getSingleScalarResult(); + } +} diff --git a/tests/Common/FakerTrait.php b/tests/Common/FakerTrait.php new file mode 100644 index 0000000..47cd085 --- /dev/null +++ b/tests/Common/FakerTrait.php @@ -0,0 +1,27 @@ +faker = Factory::create(); + } + + protected function getFaker(): Generator + { + if ($this->faker === null) { + throw new \LogicException('Faker has not been booted yet.'); + } + + return $this->faker; + } +} diff --git a/tests/Common/Generators/CommentGeneratorTrait.php b/tests/Common/Generators/CommentGeneratorTrait.php new file mode 100644 index 0000000..ac93aa2 --- /dev/null +++ b/tests/Common/Generators/CommentGeneratorTrait.php @@ -0,0 +1,34 @@ +getFaker()->name(), + $this->getFaker()->email(), + $this->getFaker()->text(500) + ); + + $this->getEntityManager()->persist($comment); + $this->getEntityManager()->flush(); + + $this->getEntityManager()->refresh($post); + + return $comment; + } +} diff --git a/tests/Common/Generators/PostGeneratorTrait.php b/tests/Common/Generators/PostGeneratorTrait.php new file mode 100644 index 0000000..bcd9652 --- /dev/null +++ b/tests/Common/Generators/PostGeneratorTrait.php @@ -0,0 +1,37 @@ +createUser($id + self::POST_GENERATOR_SYSTEM_POST_USER); + + $post = new Post( + $id, + $user, + $this->getFaker()->text(500), + $this->getFaker()->text(5000), + new ArrayCollection(), + ); + + $this->getEntityManager()->persist($post); + $this->getEntityManager()->flush(); + + return $post; + } +} diff --git a/tests/Common/Generators/UserGeneratorTrait.php b/tests/Common/Generators/UserGeneratorTrait.php new file mode 100644 index 0000000..2b63723 --- /dev/null +++ b/tests/Common/Generators/UserGeneratorTrait.php @@ -0,0 +1,55 @@ +getFaker()->name(), + $this->getFaker()->userName(), + $this->getFaker()->email(), + $this->getFaker()->phoneNumber(), + $this->getFaker()->url(), + new Address( + 1, + null, + $this->getFaker()->streetAddress(), + (string) $this->getFaker()->randomNumber(), + $this->getFaker()->city(), + $this->getFaker()->postcode(), + $this->getFaker()->randomNumber(), + $this->getFaker()->randomNumber(), + ), + new Company( + 1, + new ArrayCollection(), + $this->getFaker()->company(), + $this->getFaker()->text(10), + $this->getFaker()->text(100) + ) + ); + + $this->getEntityManager()->persist($user->address); + $this->getEntityManager()->persist($user->company); + $this->getEntityManager()->persist($user); + $this->getEntityManager()->refresh($user->address); + $this->getEntityManager()->refresh($user->company); + $this->getEntityManager()->flush(); + return $user; + } +} diff --git a/tests/Db/Users/CompanyRepositoryTest.php b/tests/Db/Users/CompanyRepositoryTest.php new file mode 100644 index 0000000..a914d42 --- /dev/null +++ b/tests/Db/Users/CompanyRepositoryTest.php @@ -0,0 +1,79 @@ +bootFaker(); + $this->bootDatabase(); + $this->getFaker()->unique(); + } + + public function testFindByNameWillReturnCompany(): void + { + $c1 = new Company( + 1, + new ArrayCollection(), + $this->getFaker()->company(), + $this->getFaker()->text(50), + $this->getFaker()->text(100) + ); + $this->getEntityManager()->persist($c1); + $this->getEntityManager()->persist(new Company( + 2, + new ArrayCollection(), + $this->getFaker()->company(), + $this->getFaker()->text(50), + $this->getFaker()->text(100) + )); + $this->getEntityManager()->flush(); + /** + * @var CompanyRepository $repository + */ + $repository = parent::getContainer()->get(CompanyRepository::class); + $this->assertNotNull($repository->findByName($c1->name)); + $this->assertNull($repository->findByName($this->getFaker()->text())); + } + + public function testDeleteOrphanRecordsWillDeleteCompaniesWithoutUsers(): void + { + $c1 = new Company( + 1, + new ArrayCollection(), + $this->getFaker()->company(), + $this->getFaker()->text(50), + $this->getFaker()->text(100) + ); + $user = $this->createUser(1); + $this->getEntityManager()->persist($c1); + $this->getEntityManager()->persist($user->address); + $this->getEntityManager()->persist($user->company); + $this->getEntityManager()->persist($user); + $this->getEntityManager()->flush(); + /** + * @var CompanyRepository $repository + */ + $repository = $this->getContainer()->get(CompanyRepository::class); + $repository->deleteOrphanRecords(); + $result = $repository->findAll(); + $this->assertCount(1, $result); + $this->assertSame($user->company, $result[0]); + } +} diff --git a/tests/Db/Users/UserRepositoryTest.php b/tests/Db/Users/UserRepositoryTest.php new file mode 100644 index 0000000..3991011 --- /dev/null +++ b/tests/Db/Users/UserRepositoryTest.php @@ -0,0 +1,38 @@ +bootFaker(); + $this->bootDatabase(); + } + + public function testFindByIdsWillReturnOnlyIdsWhichExists(): void + { + $user = $this->createUser(1); + /** + * @var UserRepository $userRepository + */ + $userRepository = parent::getContainer()->get(UserRepository::class); + $result = $userRepository->findByIds([1, /* non existent ids */ 2]); + $this->assertCount(1, $result); + $this->assertSame(1, $result[1]->id); + } +}