*/ private static $entitiesToDelete = []; public function setUp(): void { self::bootKernel(); $this->em = self::$container->get(EntityManagerInterface::class); $this->personMoveManager = self::$container->get(PersonMoveManager::class); $this->eventDispatcher = self::$container->get(EventDispatcherInterface::class); $this->centerRepository = self::$container->get(CenterRepositoryInterface::class); } public static function tearDownAfterClass(): void { self::bootKernel(); $em = self::$container->get(EntityManagerInterface::class); foreach (self::$entitiesToDelete as [$class, $id]) { $entity = $em->find($class, $id); if (null !== $entity) { $em->remove($entity); } } $em->flush(); } /** * @dataProvider dataProviderMovePerson */ public function testMovePersonSimple(Person $personA, Person $personB, string $message): void { $move = new PersonMove($this->em, $this->personMoveManager, $this->eventDispatcher); $sqls = $move->getSQL($personA, $personB); $this->em->getConnection()->transactional(function (Connection $conn) use ($personA, $personB, $sqls) { foreach ($sqls as $sql) { $conn->executeStatement($sql); } }); $personsByIdOfA = $this->em->createQuery("SELECT p FROM " . Person::class . " p WHERE p.id = :id") ->setParameter('id', $personA->getId()) ->getResult(); $personB = $this->em->find(Person::class, $personB->getId()); self::assertCount(0, $personsByIdOfA); self::assertNotNull($personB?->getId(), $message); } public function testMovePersonCenterHistory(): void { $personA = new Person(); $personB = new Person(); [$centerA, $centerB] = $this->centerRepository->findAll(); $this->em->persist($personA); $this->em->persist($personB); $personCenterHistoryAFirst = (new Person\PersonCenterHistory())->setCenter($centerA) ->setStartDate(new \DateTimeImmutable('2023-01-01')) ->setEndDate(new \DateTimeImmutable('2023-06-30')); $personCenterHistoryASecond = (new Person\PersonCenterHistory())->setCenter($centerB) ->setStartDate(new \DateTimeImmutable('2023-06-30')) ->setEndDate(new \DateTimeImmutable('2023-09-30')); $personCenterHistoryBFirst = (new Person\PersonCenterHistory())->setCenter($centerA) ->setStartDate(new \DateTimeImmutable('2023-03-01')) ->setEndDate(new \DateTimeImmutable('2023-07-15')); $personCenterHistoryBSecond = (new Person\PersonCenterHistory())->setCenter($centerB) ->setStartDate(new \DateTimeImmutable('2023-07-15')) ->setEndDate(new \DateTimeImmutable('2023-09-30')); $this->em->persist($personCenterHistoryAFirst); $this->em->persist($personCenterHistoryASecond); $this->em->persist($personCenterHistoryBFirst); $this->em->persist($personCenterHistoryBSecond); $personA->addCenterHistory($personCenterHistoryAFirst); $personA->addCenterHistory($personCenterHistoryASecond); $personB->addCenterHistory($personCenterHistoryBFirst); $personB->addCenterHistory($personCenterHistoryBSecond); $this->em->flush(); $this->em->clear(); $move = new PersonMove($this->em, $this->personMoveManager, $this->eventDispatcher); $sqls = $move->getSQL($personA, $personB); $this->em->getConnection()->transactional(function (Connection $conn) use ($personA, $personB, $sqls) { foreach ($sqls as $sql) { $conn->executeStatement($sql); } }); $personsByIdOfA = $this->em->createQuery("SELECT p FROM " . Person::class . " p WHERE p.id = :id") ->setParameter('id', $personA->getId()) ->getResult(); /** @var Person $personB */ $personB = $this->em->find(Person::class, $personB->getId()); $message = 'Move persons with overlapping center histories'; $this->em->refresh($personB); self::assertCount(0, $personsByIdOfA); self::assertNotNull($personB?->getId(), $message); $centerHistoriesB = $personB->getCenterHistory(); $oldestDate = new \DateTimeImmutable('2023-01-01'); $this->em->refresh($centerHistoriesB->first()); self::assertCount(2, $centerHistoriesB); self::assertEquals($oldestDate, $centerHistoriesB->first()->getStartDate()); self::$entitiesToDelete[] = [Person::class, $personA]; self::$entitiesToDelete[] = [Person::class, $personB]; self::$entitiesToDelete[] = [Person\PersonCenterHistory::class, $personCenterHistoryAFirst]; self::$entitiesToDelete[] = [Person\PersonCenterHistory::class, $personCenterHistoryASecond]; self::$entitiesToDelete[] = [Person\PersonCenterHistory::class, $personCenterHistoryBFirst]; self::$entitiesToDelete[] = [Person\PersonCenterHistory::class, $personCenterHistoryBSecond]; } public function dataProviderMovePerson(): iterable { $this->setUp(); $personA = new Person(); $personB = new Person(); $this->em->persist($personA); $this->em->persist($personB); self::$entitiesToDelete[] = [Person::class, $personA]; self::$entitiesToDelete[] = [Person::class, $personB]; yield [$personA, $personB, "move 2 people without any associated data"]; $personA = new Person(); $personB = new Person(); $activity = new Activity(); $activity->setDate(new \DateTime('today')); $activity->addPerson($personA); $activity->addPerson($personB); $this->em->persist($personA); $this->em->persist($personB); $this->em->persist($activity); self::$entitiesToDelete[] = [Person::class, $personA]; self::$entitiesToDelete[] = [Person::class, $personB]; self::$entitiesToDelete[] = [Activity::class, $activity]; yield [$personA, $personB, "move 2 people having an activity"]; $personA = new Person(); $personB = new Person(); $household = new Household(); $household->addMember( $memberA = (new HouseholdMember())->setPerson($personA)->setShareHousehold(true) ->setStartDate(new \DateTimeImmutable('2023-01-01')) ); $household->addMember( $memberB = (new HouseholdMember())->setPerson($personB)->setShareHousehold(true) ->setStartDate(new \DateTimeImmutable('2023-01-01')) ); $this->em->persist($personA); $this->em->persist($personB); $this->em->persist($household); $this->em->persist($memberA); $this->em->persist($memberB); self::$entitiesToDelete[] = [Person::class, $personA]; self::$entitiesToDelete[] = [Person::class, $personB]; self::$entitiesToDelete[] = [HouseholdMember::class, $memberA]; self::$entitiesToDelete[] = [HouseholdMember::class, $memberB]; self::$entitiesToDelete[] = [Household::class, $household]; yield [$personA, $personB, "move 2 people having the same household at the same time"]; $personA = new Person(); $personB = new Person(); $parcours = new AccompanyingPeriod(); $parcours->addPerson($personA); $parcours->addPerson($personB); $this->em->persist($personA); $this->em->persist($personB); $this->em->persist($parcours); self::$entitiesToDelete[] = [Person::class, $personA]; self::$entitiesToDelete[] = [Person::class, $personB]; self::$entitiesToDelete[] = [AccompanyingPeriod::class, $parcours]; yield [$personA, $personB, "move 2 people participating to the same parcours"]; $personA = new Person(); $personB = new Person(); $relationship = new Relationship(); $relation = new Relation(); $user = (new User())->setUsername(uniqid())->setEmail(uniqid() . '@foo.com'); $relationship->setRelation($relation); $relationship->setToPerson($personA); $relationship->setFromPerson($personB); $relationship->setReverse(false); $relationship->setCreatedBy($user); $this->em->persist($personA); $this->em->persist($personB); $this->em->persist($relation); $this->em->persist($user); $this->em->persist($relationship); self::$entitiesToDelete[] = [Person::class, $personA]; self::$entitiesToDelete[] = [Person::class, $personB]; self::$entitiesToDelete[] = [Relation::class, $relation]; self::$entitiesToDelete[] = [User::class, $user]; self::$entitiesToDelete[] = [Relationship::class, $relationship]; yield [$personA, $personB, "move 2 people with a relationship"]; $this->em->flush(); $this->em->clear(); } }