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 testMerge(): void { $accompanyingPeriodWork = new AccompanyingPeriodWork(); $accompanyingPeriodWork->setStartDate(new \DateTime('2022-01-01')); $accompanyingPeriodWork->addReferrer($userA = new User()); $accompanyingPeriodWork->addReferrer($userC = new User()); $accompanyingPeriodWork->addAccompanyingPeriodWorkEvaluation($evaluationA = new AccompanyingPeriodWorkEvaluation()); $accompanyingPeriodWork->setNote('blabla'); $accompanyingPeriodWork->addThirdParty($thirdPartyA = new ThirdParty()); $toDelete = new AccompanyingPeriodWork(); $toDelete->setStartDate(new \DateTime('2022-01-01')); $toDelete->addReferrer($userB = new User()); $toDelete->addReferrer($userC); $toDelete->addAccompanyingPeriodWorkEvaluation($evaluationB = new AccompanyingPeriodWorkEvaluation()); $toDelete->setNote('boum'); $toDelete->addThirdParty($thirdPartyB = new ThirdParty()); $toDelete->addGoal($goalA = new AccompanyingPeriodWorkGoal()); $toDelete->addResult($resultA = new Result()); $service = $this->buildMergeService($toDelete); $service->merge($accompanyingPeriodWork, $toDelete); self::assertTrue($accompanyingPeriodWork->getReferrers()->contains($userA)); self::assertTrue($accompanyingPeriodWork->getReferrers()->contains($userB)); self::assertTrue($accompanyingPeriodWork->getReferrers()->contains($userC)); self::assertTrue($accompanyingPeriodWork->getAccompanyingPeriodWorkEvaluations()->contains($evaluationA)); self::assertTrue($accompanyingPeriodWork->getAccompanyingPeriodWorkEvaluations()->contains($evaluationB)); foreach ($accompanyingPeriodWork->getAccompanyingPeriodWorkEvaluations() as $evaluation) { self::assertSame($accompanyingPeriodWork, $evaluation->getAccompanyingPeriodWork()); } self::assertStringContainsString('blabla', $accompanyingPeriodWork->getNote()); self::assertStringContainsString('boum', $toDelete->getNote()); self::assertTrue($accompanyingPeriodWork->getThirdParties()->contains($thirdPartyA)); self::assertTrue($accompanyingPeriodWork->getThirdParties()->contains($thirdPartyB)); self::assertTrue($accompanyingPeriodWork->getGoals()->contains($goalA)); self::assertTrue($accompanyingPeriodWork->getResults()->contains($resultA)); } }