[test][household] add a test to check if leaveMovement write an enddate when member startdate is today

This commit is contained in:
Mathieu Jaumotte 2023-08-30 18:31:44 +02:00 committed by Julie Lenaerts
parent 90c8f1e3cf
commit 758ad9bc87
2 changed files with 300 additions and 59 deletions

View File

@ -55,6 +55,14 @@ class MembersEditor
$this->eventDispatcher = $eventDispatcher;
}
/**
* Add a person to the household
*
* The person is added to the household associated with this editor's instance.
*
* If the person is also a member of another household, or the same household at the same position, the person
* is not associated any more with the previous household.
*/
public function addMovement(DateTimeImmutable $date, Person $person, ?Position $position, ?bool $holder = false, ?string $comment = null): self
{
if (null === $this->household) {
@ -69,8 +77,7 @@ class MembersEditor
->setComment($comment);
$this->household->addMember($membership);
if (null !== $position) {
if ($position->getShareHousehold()) {
if ($membership->getShareHousehold()) {
// launch event only if moving to a "share household" position,
// and if the destination household is different than the previous one
$event = new PersonAddressMoveEvent($person);
@ -115,14 +122,8 @@ class MembersEditor
}
}
} else {
// if a members is moved to the same household than the one he belongs to,
// we should make it leave the household
if ($person->getCurrentHousehold($date) === $this->household) {
$this->leaveMovement($date, $person);
}
// if there are multiple belongings not sharing household, close the others
foreach ($person->getHouseholdParticipationsNotShareHousehold() as $participation) {
foreach ($person->getHouseholdParticipations() as $participation) {
if ($participation === $membership) {
continue;
}
@ -131,6 +132,11 @@ class MembersEditor
&& ($participation->getEndDate() === null || $participation->getEndDate() > $membership->getStartDate())
&& $participation->getStartDate() <= $membership->getStartDate()
) {
if ($participation->getShareHousehold()) {
// if a members is moved to the same household than the one he belongs to,
// we should make it leave the household
$this->leaveMovement($date, $person);
} else {
$participation->setEndDate($membership->getStartDate());
}
}
@ -158,6 +164,15 @@ class MembersEditor
return null !== $this->household;
}
/**
* Makes a person leave the household.
*
* Makes a person leave the household **associated with this editor**.
*
* @param DateTimeImmutable $date
* @param Person $person
* @return $this
*/
public function leaveMovement(
DateTimeImmutable $date,
Person $person
@ -168,7 +183,8 @@ class MembersEditor
$criteria->where(
$expr->andX(
$expr->lte('startDate', $date),
$expr->isNull('endDate')
$expr->isNull('endDate'),
$expr->eq('shareHousehold', true)
)
);

View File

@ -74,6 +74,55 @@ final class MembersEditorTest extends TestCase
$this->assertContains(null, $endDates);
}
/**
* We test that a leave move is possible when member startdate is same as current date
*
*/
public function testLeaveMovementInSameHouseholdFromShareHouseholdToNotShareHouseholdOnSameDate()
{
$person = new Person();
$household = new Household();
$factory = $this->buildMembersEditorFactory();
$positionSharing = (new Position())->setShareHousehold(true);
$positionNotSharing = (new Position())->setShareHousehold(false);
// create add move
$editor = $factory->createEditor($household);
$editor->addMovement(new DateTimeImmutable('today'), $person, $positionSharing);
$editor->postMove();
self::assertContains($person, $household->getCurrentPersons());
self::assertSame($household, $person->getCurrentHousehold());
self::assertCount(1, $household->getMembers());
// create leave move
$eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$eventDispatcher
->dispatch(Argument::type(PersonAddressMoveEvent::class))
->shouldBeCalled();
$factory = $this->buildMembersEditorFactory(
$eventDispatcher->reveal(),
null
);
$editor = $factory->createEditor($household);
$editor->addMovement(new DateTimeImmutable('today'), $person, $positionNotSharing);
$editor->postMove();
$participations = $household->getMembers();
self::assertCount(2, $participations);
$sharing = $participations->filter(fn (HouseholdMember $hm) => $hm->getShareHousehold());
self::assertCount(1, $sharing);
$notSharing = $participations->filter(fn (HouseholdMember $hm) => !$hm->getShareHousehold());
self::assertCount(1, $notSharing);
self::assertNotNull($sharing[0]->getEndDate());
self::assertEquals(new DateTimeImmutable('today'), $sharing[0]->getEndDate());
}
/**
* We test here a move for a person:.
*
@ -98,8 +147,17 @@ final class MembersEditorTest extends TestCase
$this->assertContains($person, $household->getCurrentPersons());
// we do the move to the position not sharing household
$eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$eventDispatcher
->dispatch(Argument::type(PersonAddressMoveEvent::class))
->shouldNotBeCalled();
$factory = $this->buildMembersEditorFactory(
$eventDispatcher->reveal(),
null
);
$editor = $factory->createEditor($household2 = new Household());
$editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionNotSharing);
$editor->postMove();
$sharings = $household->getCurrentMembers()->filter(static fn (HouseholdMember $m) => $m->getShareHousehold());
$notSharing = $household2->getCurrentMembers()->filter(static fn (HouseholdMember $m) => !$m->getShareHousehold());
@ -118,7 +176,7 @@ final class MembersEditorTest extends TestCase
* * which was in a position "sharing household"
* * which move to the same household, in a position "not sharing household"
*/
public function testMoveFromSharingHouseholdToNotSharingHousehouldInSamehousehold()
public function testMoveFromSharingHouseholdToNotSharingHousehouldInSamehouseholdOnDifferentDate()
{
$person = new Person();
$household = new Household();
@ -134,8 +192,17 @@ final class MembersEditorTest extends TestCase
$this->assertContains($person, $household->getCurrentPersons());
// we do the move to the position not sharing household
$eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$eventDispatcher
->dispatch(Argument::type(PersonAddressMoveEvent::class))
->shouldBeCalled();
$factory = $this->buildMembersEditorFactory(
$eventDispatcher->reveal(),
null
);
$editor = $factory->createEditor($household);
$editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionNotSharing);
$editor->postMove();
$sharings = $household->getCurrentMembers()->filter(static fn (HouseholdMember $m) => $m->getShareHousehold());
$notSharing = $household->getCurrentMembers()->filter(static fn (HouseholdMember $m) => !$m->getShareHousehold());
@ -148,6 +215,84 @@ final class MembersEditorTest extends TestCase
$this->assertContains($person, $notSharing->map($getPerson));
}
/**
* We test here a move for a person:.
*
* * which was in a position "not sharing household"
* * which move to the same household, in a position "sharing household"
*/
public function testMoveFromNotSharingHouseholdToSharingHousehouldInSamehousehold()
{
$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, at the position "not sharing"
$editor->addMovement(new DateTimeImmutable('1 month ago'), $person, $positionNotSharing);
// double check that the person is in the household
$this->assertContains($person, $household->getCurrentPersons());
// we do the move to the position sharing household
$editor = $factory->createEditor($household);
$editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionSharing);
self::assertCount(2, $household->getMembers());
$sharings = $household->getCurrentMembers()->filter(static fn (HouseholdMember $m) => $m->getShareHousehold());
$notSharing = $household->getCurrentMembers()->filter(static fn (HouseholdMember $m) => !$m->getShareHousehold());
$this->assertCount(0, $notSharing);
$this->assertCount(1, $sharings);
$getPerson = static fn (HouseholdMember $m) => $m->getPerson();
$this->assertContains($person, $sharings->map($getPerson));
$this->assertNotContains($person, $notSharing->map($getPerson));
}
/**
* We test here a move for a person:.
*
* * which was in a position "not sharing household"
* * which move to the same household, in a position "sharing household"
*/
public function testMoveFromNotSharingHouseholdToSharingHousehouldInSamehouseholdOnSameDate()
{
$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, at the position "not sharing"
$editor->addMovement(new DateTimeImmutable('today'), $person, $positionNotSharing);
// double check that the person is in the household
$this->assertContains($person, $household->getCurrentPersons());
// we do the move to the position sharing household
$editor = $factory->createEditor($household);
$editor->addMovement(new DateTimeImmutable('today'), $person, $positionSharing);
self::assertCount(2, $household->getMembers());
$sharings = $household->getCurrentMembers()->filter(static fn (HouseholdMember $m) => $m->getShareHousehold());
$notSharing = $household->getCurrentMembers()->filter(static fn (HouseholdMember $m) => !$m->getShareHousehold());
$this->assertCount(0, $notSharing);
$this->assertCount(1, $sharings);
$getPerson = static fn (HouseholdMember $m) => $m->getPerson();
$this->assertContains($person, $sharings->map($getPerson));
$this->assertNotContains($person, $notSharing->map($getPerson));
}
public function testMovePersonWithoutSharedHousehold()
{
$person = new Person();
@ -235,13 +380,26 @@ final class MembersEditorTest extends TestCase
$this->assertEquals($date, $membership1->getEndDate());
}
public function testPostMoveToAPositionNotSharingHousehold()
public function testPostMoveToAPositionNotSharingHouseholdOnSameDay()
{
$person = new Person();
$position = (new Position())
$positionNotSharing = (new Position())
->setShareHousehold(false);
$positionSharing = (new Position())->setShareHousehold(true);
$household1 = new Household();
$household2 = new Household();
$factory = $this->buildMembersEditorFactory();
$editor = $factory->createEditor($household1);
$editor->addMovement(new DateTimeImmutable('today'), $person, $positionSharing);
$editor->postMove();
self::assertContains($person, $household1->getCurrentPersons());
self::assertContains($person, $household1->getCurrentMembers()
->filter(fn (HouseholdMember $m) => $m->getShareHousehold())
->map(fn (HouseholdMember $m) => $m->getPerson()));
self::assertSame($household1, $person->getCurrentHousehold());
$eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$eventDispatcher
->dispatch(Argument::type(PersonAddressMoveEvent::class))
@ -250,11 +408,78 @@ final class MembersEditorTest extends TestCase
$eventDispatcher->reveal(),
null
);
$editor = $factory->createEditor($household1);
$editor->addMovement(new DateTimeImmutable('now'), $person, $position);
$editor = $factory->createEditor($household2);
$editor->addMovement(new DateTimeImmutable('today'), $person, $positionNotSharing);
$editor->postMove();
// $household1 still contains $person
self::assertContains($person, $household1->getCurrentPersons());
self::assertContains($person, $household1->getCurrentMembers()
->filter(fn (HouseholdMember $m) => $m->getShareHousehold())
->map(fn (HouseholdMember $m) => $m->getPerson()));
self::assertSame($household1, $person->getCurrentHousehold());
// $household2 contains $person at non-sharing position
self::assertContains($person, $household2->getCurrentMembers()
->filter(fn (HouseholdMember $m) => !$m->getShareHousehold())
->map(fn (HouseholdMember $m) => $m->getPerson()));
self::assertContains(
$household2,
$person->getHouseholdParticipationsNotShareHousehold()
->map(fn (HouseholdMember $hm) => $hm->getHousehold())
);
}
public function testPostMoveToAPositionNotSharingHouseholdOnDifferentDays()
{
$person = new Person();
$positionNotSharing = (new Position())
->setShareHousehold(false);
$positionSharing = (new Position())->setShareHousehold(true);
$household1 = new Household();
$household2 = new Household();
$factory = $this->buildMembersEditorFactory();
$editor = $factory->createEditor($household1);
$editor->addMovement(new DateTimeImmutable('1 year ago'), $person, $positionSharing);
$editor->postMove();
self::assertContains($person, $household1->getCurrentPersons());
self::assertContains($person, $household1->getCurrentMembers()
->filter(fn (HouseholdMember $m) => $m->getShareHousehold())
->map(fn (HouseholdMember $m) => $m->getPerson()));
self::assertSame($household1, $person->getCurrentHousehold());
$eventDispatcher = $this->prophesize(EventDispatcherInterface::class);
$eventDispatcher
->dispatch(Argument::type(PersonAddressMoveEvent::class))
->shouldNotBeCalled();
$factory = $this->buildMembersEditorFactory(
$eventDispatcher->reveal(),
null
);
$editor = $factory->createEditor($household2);
$editor->addMovement(new DateTimeImmutable('yesterday'), $person, $positionNotSharing);
$editor->postMove();
// $household1 still contains $person
self::assertContains($person, $household1->getCurrentPersons());
self::assertContains($person, $household1->getCurrentMembers()
->filter(fn (HouseholdMember $m) => $m->getShareHousehold())
->map(fn (HouseholdMember $m) => $m->getPerson()));
self::assertSame($household1, $person->getCurrentHousehold());
// $household2 contains $person at non-sharing position
self::assertContains($person, $household2->getCurrentMembers()
->filter(fn (HouseholdMember $m) => !$m->getShareHousehold())
->map(fn (HouseholdMember $m) => $m->getPerson()));
self::assertContains(
$household2,
$person->getHouseholdParticipationsNotShareHousehold()
->map(fn (HouseholdMember $hm) => $hm->getHousehold())
);
}
public function testPostMoveToAPositionSharingHouseholdAndSameHousehold()