factory = $this->buildMembersEditorFactory(); } public function testAddingParticipationNotSharingHouseholdCloseTheOldOnes() { $person = new Person(); $position = (new Position())->setShareHousehold(false); $household = new Household(); // set a first time the person in position $factory = $this->buildMembersEditorFactory(); $editor = $factory->createEditor($household); $editor->addMovement($aMonthAgo = new DateTimeImmutable('1 month ago'), $person, $position); // set a second time the person in position $factory = $this->buildMembersEditorFactory(); $editor = $factory->createEditor($household); $editor->addMovement($yesterday = new DateTimeImmutable('yesterday'), $person, $position); $this->assertCount(2, $person->getHouseholdParticipationsNotShareHousehold()); $startDates = []; $endDates = []; foreach ($person->getHouseholdParticipationsNotShareHousehold() as $participation) { $startDates[] = $participation->getStartDate(); $endDates[] = $participation->getEndDate(); } $this->assertContains($aMonthAgo, $startDates); $this->assertContains($yesterday, $startDates); $this->assertContains($yesterday, $endDates); $this->assertContains(null, $endDates); } /** * We test here a move for a person:. * * * which was in a position "sharing household" * * which move to the another household, in a position "not sharing household" * * The person should stays in the two households */ public function testMoveFromSharingHouseholdToNotSharingHousehouldInDifferentHousehold() { $person = new Person(); $household = new Household(); $positionSharing = (new Position())->setShareHousehold(true); $positionNotSharing = (new Position())->setShareHousehold(false); $factory = $this->buildMembersEditorFactory(); $editor = $factory->createEditor($household); // we add the member to the household $editor->addMovement(new DateTimeImmutable('1 month ago'), $person, $positionSharing); // double check that the person is in the household $this->assertContains($person, $household->getCurrentPersons()); // we do the move to the position not sharing household $editor = $factory->createEditor($household2 = new Household()); $editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionNotSharing); $sharings = $household->getCurrentMembers()->filter(static function (HouseholdMember $m) { return $m->getShareHousehold(); }); $notSharing = $household2->getCurrentMembers()->filter(static function (HouseholdMember $m) { return !$m->getShareHousehold(); }); $this->assertCount(1, $notSharing); $this->assertCount(1, $sharings); $getPerson = static function (HouseholdMember $m) { return $m->getPerson(); }; $this->assertContains($person, $notSharing->map($getPerson)); } /** * We test here a move for a person:. * * * which was in a position "sharing household" * * which move to the same household, in a position "not sharing household" */ public function testMoveFromSharingHouseholdToNotSharingHousehouldInSamehousehold() { $person = new Person(); $household = new Household(); $positionSharing = (new Position())->setShareHousehold(true); $positionNotSharing = (new Position())->setShareHousehold(false); $factory = $this->buildMembersEditorFactory(); $editor = $factory->createEditor($household); // we add the member to the household $editor->addMovement(new DateTimeImmutable('1 month ago'), $person, $positionSharing); // double check that the person is in the household $this->assertContains($person, $household->getCurrentPersons()); // we do the move to the position not sharing household $editor = $factory->createEditor($household); $editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionNotSharing); $sharings = $household->getCurrentMembers()->filter(static function (HouseholdMember $m) { return $m->getShareHousehold(); }); $notSharing = $household->getCurrentMembers()->filter(static function (HouseholdMember $m) { return !$m->getShareHousehold(); }); $this->assertCount(1, $notSharing); $this->assertCount(0, $sharings); $getPerson = static function (HouseholdMember $m) { return $m->getPerson(); }; $this->assertContains($person, $notSharing->map($getPerson)); } public function testMovePersonWithoutSharedHousehold() { $person = new Person(); $position = (new Position()) ->setShareHousehold(false); $household1 = new Household(); $household2 = new Household(); $editor = $this->factory->createEditor($household1); $editor->addMovement( DateTimeImmutable::createFromFormat('Y-m-d', '2020-01-01'), $person, $position ); $persistables = $editor->getPersistable(); $this->assertEquals(1, count($persistables)); $membership1 = $person->getHouseholdParticipations()->first(); $this->assertSame($household1, $membership1->getHousehold()); $this->assertNull($membership1->getEndDate()); // move to another household $date = DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01'); $editor = $this->factory->createEditor($household2); $editor->addMovement( $date, $person, $position ); $persistables = $editor->getPersistable(); $this->assertEquals(1, count($persistables)); $membership2 = $person->getHouseholdParticipations()->last(); $this->assertNull($membership2->getEndDate()); $this->assertSame($household2, $membership2->getHousehold()); $this->assertNull( $membership1->getEndDate(), 'assert that the membership1 is not closed' ); } public function testMovePersonWithSharedHousehold() { $person = new Person(); $position = (new Position()) ->setShareHousehold(true); $household1 = new Household(); $household2 = new Household(); $editor = $this->factory->createEditor($household1); $editor->addMovement( DateTimeImmutable::createFromFormat('Y-m-d', '2020-01-01'), $person, $position ); $persistables = $editor->getPersistable(); $this->assertEquals(count($persistables), 1); $membership1 = $persistables[0]; $this->assertSame($household1, $membership1->getHousehold()); $this->assertNull($membership1->getEndDate()); // move to another household $date = DateTimeImmutable::createFromFormat('Y-m-d', '2021-01-01'); $editor = $this->factory->createEditor($household2); $editor->addMovement( $date, $person, $position ); $persistables = $editor->getPersistable(); $this->assertEquals(1, count($persistables)); $membership2 = $persistables[0]; $this->assertSame($household2, $membership2->getHousehold()); $this->assertNull($membership2->getEndDate()); $this->assertNotNull( $membership1->getEndDate(), 'assert that the membership1 is closed' ); $this->assertEquals($date, $membership1->getEndDate()); } public function testPostMoveToAPositionNotSharingHousehold() { $person = new Person(); $position = (new Position()) ->setShareHousehold(false); $household1 = new Household(); $household2 = new Household(); $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); $eventDispatcher ->dispatch(Argument::type(PersonAddressMoveEvent::class)) ->shouldNotBeCalled(); $factory = $this->buildMembersEditorFactory( $eventDispatcher->reveal(), null ); $editor = $factory->createEditor($household1); $editor->addMovement(new DateTimeImmutable('now'), $person, $position); $editor->postMove(); } public function testPostMoveToAPositionSharingHouseholdAndSameHousehold() { $person = new Person(); $position = (new Position()) ->setShareHousehold(true); $position2 = (new Position()) ->setShareHousehold(true); $household1 = new Household(); // set into the first household $editor = $this->buildMembersEditorFactory() ->createEditor($household1); $editor->addMovement(new DateTimeImmutable('1 year ago'), $person, $position); // prepare for next move $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); $eventDispatcher ->dispatch(Argument::type(PersonAddressMoveEvent::class)) ->shouldNotBeCalled(); $factory = $this->buildMembersEditorFactory( $eventDispatcher->reveal(), null ); $editor = $factory->createEditor($household1); $editor->addMovement(new DateTimeImmutable('now'), $person, $position2); $editor->postMove(); } public function testPostMoveToAPositionSharingHouseholdFromDifferentHousehold() { $person = new Person(); $position = (new Position()) ->setShareHousehold(true); $household1 = new Household(); $household2 = new Household(); // set into the first household $editor = $this->buildMembersEditorFactory() ->createEditor($household1); $editor->addMovement(new DateTimeImmutable('1 year ago'), $person, $position); // perform now the movement $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); $eventDispatcher ->dispatch(Argument::type(PersonAddressMoveEvent::class)) ->shouldBeCalled(); $factory = $this->buildMembersEditorFactory( $eventDispatcher->reveal(), null ); $editor = $factory->createEditor($household2); $editor->addMovement(new DateTimeImmutable('now'), $person, $position); $editor->postMove(); } public function testPostMoveToAPositionSharingHouseholdFromNoHousehold() { $person = new Person(); $position = (new Position()) ->setShareHousehold(true); $household1 = new Household(); $eventDispatcher = $this->prophesize(EventDispatcherInterface::class); $eventDispatcher ->dispatch(Argument::type(PersonAddressMoveEvent::class)) ->shouldBeCalled(); $factory = $this->buildMembersEditorFactory( $eventDispatcher->reveal(), null ); $editor = $factory->createEditor($household1); $editor->addMovement(new DateTimeImmutable('now'), $person, $position); $editor->postMove(); } private function buildMembersEditorFactory( ?EventDispatcherInterface $eventDispatcher = null, ?ValidatorInterface $validator = null ) { if (null === $eventDispatcher) { $double = $this->getProphet()->prophesize(); $double->willImplement(EventDispatcherInterface::class); $double->dispatch(Argument::type(PersonAddressMoveEvent::class)); $eventDispatcher = $double->reveal(); } if (null === $validator) { $double = $this->getProphet()->prophesize(); $double->willImplement(ValidatorInterface::class); $validator = $double->reveal(); } return new MembersEditorFactory( $eventDispatcher, $validator ); } }