prophesize(EntityManagerInterface::class); $entityManager->wrapInTransaction(Argument::type('callable'))->will(function ($args) use ($entityManager) { call_user_func_array($args[0], [$entityManager->reveal()]); })->shouldBeCalled(); $entityManager->remove($toRemove)->shouldBeCalled(); $connection = $this->prophesize(Connection::class); $connection->executeQuery(Argument::type('string'), Argument::type('array'))->shouldBeCalled(); $entityManager->getConnection()->willReturn($connection->reveal()); return new AccompanyingPeriodWorkMergeService($entityManager->reveal()); } /** * @dataProvider provideStartDateMoveData */ public function testStartDateMove(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete, ?\DateTime $expected): void { $service = $this->buildMergeService($toDelete); $return = $service->merge($toKeep, $toDelete); self::assertEquals($expected, $return->getStartDate()); } public static function provideStartDateMoveData(): array { return [ 'Earliest date kept when toKeep is earlier' => [ (new AccompanyingPeriodWork())->setStartDate(new \DateTime('2023-01-01')), (new AccompanyingPeriodWork())->setStartDate(new \DateTime('2023-06-01')), new \DateTime('2023-01-01'), ], 'Earliest date kept when toDelete is earlier' => [ (new AccompanyingPeriodWork())->setStartDate(new \DateTime('2023-06-01')), (new AccompanyingPeriodWork())->setStartDate(new \DateTime('2023-01-01')), new \DateTime('2023-01-01'), ], 'Same start dates remain unchanged' => [ (new AccompanyingPeriodWork())->setStartDate(new \DateTime('2023-01-01')), (new AccompanyingPeriodWork())->setStartDate(new \DateTime('2023-01-01')), new \DateTime('2023-01-01'), ], ]; } /** * @dataProvider provideEndDateMoveData */ public function testEndDateMove(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete, ?\DateTimeImmutable $expected): void { $service = $this->buildMergeService($toDelete); $return = $service->merge($toKeep, $toDelete); self::assertEquals($expected, $return->getEndDate()); } public static function provideEndDateMoveData(): array { return [ 'Oldest date kept when toKeep is older' => [ (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2022-01-01'))->setStartDate(new \DateTime('2021-01-01')), (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2023-06-01'))->setStartDate(new \DateTime('2021-01-01')), new \DateTimeImmutable('2023-06-01'), ], 'Oldest date kept when toDelete is older' => [ (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2023-06-01'))->setStartDate(new \DateTime('2021-01-01')), (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2022-01-01'))->setStartDate(new \DateTime('2021-01-01')), new \DateTimeImmutable('2023-06-01'), ], 'Same end dates remain unchanged' => [ (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2023-01-01'))->setStartDate(new \DateTime('2021-01-01')), (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2023-01-01'))->setStartDate(new \DateTime('2021-01-01')), new \DateTimeImmutable('2023-01-01'), ], 'End date is null if toKeep is null' => [ (new AccompanyingPeriodWork())->setEndDate(null)->setStartDate(new \DateTime('2021-01-01')), (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2023-01-01'))->setStartDate(new \DateTime('2021-01-01')), null, ], 'End date is null if toDelete is null' => [ (new AccompanyingPeriodWork())->setEndDate(new \DateTimeImmutable('2023-01-01'))->setStartDate(new \DateTime('2021-01-01')), (new AccompanyingPeriodWork())->setEndDate(null)->setStartDate(new \DateTime('2021-01-01')), null, ], 'End date is null if both are null' => [ (new AccompanyingPeriodWork())->setEndDate(null)->setStartDate(new \DateTime('2021-01-01')), (new AccompanyingPeriodWork())->setEndDate(null)->setStartDate(new \DateTime('2021-01-01')), null, ], ]; } /** * @dataProvider provideMoveHandlingThirdPartyData */ public function testMoveHandlingThirdParty(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete, ?ThirdParty $expected): void { $service = $this->buildMergeService($toDelete); $return = $service->merge($toKeep, $toDelete); self::assertSame($expected, $return->getHandlingThierParty()); } public static function provideMoveHandlingThirdPartyData(): iterable { yield 'Third party not change when existing in kept' => [ (new AccompanyingPeriodWork())->setStartDate(new \DateTimeImmutable('2022-01-01'))->setHandlingThierParty($tpA = new ThirdParty()), (new AccompanyingPeriodWork())->setStartDate(new \DateTimeImmutable('2022-01-01'))->setHandlingThierParty(new ThirdParty()), $tpA, ]; yield 'Third party will change when not existing in kept' => [ (new AccompanyingPeriodWork())->setStartDate(new \DateTimeImmutable('2022-01-01')), (new AccompanyingPeriodWork())->setStartDate(new \DateTimeImmutable('2022-01-01'))->setHandlingThierParty($tpB = new ThirdParty()), $tpB, ]; yield 'Third party do not change when not existing in removed' => [ (new AccompanyingPeriodWork())->setStartDate(new \DateTimeImmutable('2022-01-01'))->setHandlingThierParty($tpC = new ThirdParty()), (new AccompanyingPeriodWork())->setStartDate(new \DateTimeImmutable('2022-01-01')), $tpC, ]; } public function testMergeAccompanyingPeriodWorks(): void { $em = self::getContainer()->get(EntityManagerInterface::class); $userA = new User(); $userA->setUsername('someUser'); $userA->setEmail('someUser@example.com'); $em->persist($userA); $toKeep = new AccompanyingPeriodWork(); $toKeep->setStartDate(new \DateTime('2022-01-02')); $toKeep->setNote('Keep note'); $toKeep->setCreatedBy($userA); $toKeep->setUpdatedBy($userA); $toKeep->addReferrer($userA); $em->persist($toKeep); $userB = new User(); $userB->setUsername('anotherUser'); $userB->setEmail('anotherUser@example.com'); $em->persist($userB); $toDelete = new AccompanyingPeriodWork(); $toDelete->setStartDate(new \DateTime('2022-01-01')); $toDelete->setNote('Delete note'); $toDelete->setCreatedBy($userB); $toDelete->setUpdatedBy($userB); $toDelete->addReferrer($userB); $em->persist($toDelete); $evaluation = new AccompanyingPeriodWorkEvaluation(); $evaluation->setAccompanyingPeriodWork($toDelete); $em->persist($evaluation); $em->flush(); $service = new AccompanyingPeriodWorkMergeService($em); $merged = $service->merge($toKeep, $toDelete); $em->refresh($merged); // Assertions $this->assertEquals(new \DateTime('2022-01-01'), $merged->getStartDate()); $this->assertStringContainsString('Keep note', $merged->getNote()); $this->assertStringContainsString('Delete note', $merged->getNote()); $em->refresh($evaluation); $this->assertEquals($toKeep->getId(), $evaluation->getAccompanyingPeriodWork()->getId()); $em->remove($evaluation); $em->remove($toKeep); $em->remove($toDelete); $em->remove($userA); $em->remove($userB); $em->flush(); } }