From 7d130277d684380290cba7e87efdcc0d8a7ea320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 30 Apr 2021 00:24:21 +0200 Subject: [PATCH] fix person last address (from @loophp on old framagit repo) See https://framagit.org/Chill-project/Chill-Person/-/merge_requests/13 --- .../ChillPersonBundle/Entity/Person.php | 20 ++-- .../Tests/Entity/PersonTest.php | 92 ++++++++++--------- 2 files changed, 62 insertions(+), 50 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index a25f84fbb..e23af8dfb 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -1022,18 +1022,20 @@ class Person implements HasCenterInterface */ public function getLastAddress(\DateTime $date = null) { - if ($date === null) { - $date = new \DateTime('now'); - } + $from ??= new DateTime('now'); - $addresses = $this->getAddresses(); + /** @var ArrayIterator $addressesIterator */ + $addressesIterator = $this->getAddresses() + ->filter(static fn (Address $address): bool => $address->getValidFrom() <= $from) + ->getIterator(); - if ($addresses == null) { + $addressesIterator->uasort( + static fn (Address $left, Address $right): int => $right->getValidFrom() <=> $left->getValidFrom() + ); - return null; - } - - return $addresses->first(); + return [] === ($addresses = iterator_to_array($addressesIterator)) ? + null : + current($addresses); } /** diff --git a/src/Bundle/ChillPersonBundle/Tests/Entity/PersonTest.php b/src/Bundle/ChillPersonBundle/Tests/Entity/PersonTest.php index cffa0e731..784d9546b 100644 --- a/src/Bundle/ChillPersonBundle/Tests/Entity/PersonTest.php +++ b/src/Bundle/ChillPersonBundle/Tests/Entity/PersonTest.php @@ -25,6 +25,10 @@ namespace Chill\PersonBundle\Tests\Entity; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\MainBundle\Entity\Address; +use DateInterval; +use DateTime; +use Generator; + /** * Unit tests for the person Entity @@ -152,47 +156,53 @@ class PersonTest extends \PHPUnit\Framework\TestCase $this->assertEquals($r['result'], Person::ERROR_ADDIND_PERIOD_AFTER_AN_OPEN_PERIOD); } - - public function testGetLastAddress() + + public function dateProvider(): Generator { - $date0 = (\DateTime::createFromFormat('Y-m-d', '2021-02-05'))->settime(0,0); - $date1 = (\DateTime::createFromFormat('Y-m-d', '2021-03-05'))->settime(0,0); - $date2 = (\DateTime::createFromFormat('Y-m-d', '2021-04-05'))->settime(0,0); - $date3 = (\DateTime::createFromFormat('Y-m-d', '2021-05-05'))->settime(0,0); - $date4 = (\DateTime::createFromFormat('Y-m-d', '2021-06-05'))->settime(0,0); - $date5 = (\DateTime::createFromFormat('Y-m-d', '2021-07-05'))->settime(0,0); - $date6 = (\DateTime::createFromFormat('Y-m-d', '2021-08-05'))->settime(0,0); - $p = new Person($date1); - - $this->assertNull($p->getLastAddress($date1)); - - // add some address - $add1 = (new Address())->setValidFrom($date1); - // no address with date 2 - $add3 = (new Address())->setValidFrom($date3); - // no address with date 4 - $add5 = (new Address())->setValidFrom($date5); - - $p->addAddress($add1); - - // test that, if only one address, that does work: - $this->assertSame($add1, $p->getLastAddress($date1)); - $this->assertSame($add1, $p->getLastAddress($date2)); - $this->assertSame($add1, $p->getLastAddress()); - - // adress before the date should not work - $this->assertNull($p->getLastAddress($date0)); - - // add addresses - $p->addAddress($add3); - $p->addAddress($add5); - - // test retrieval of address - $this->assertSame($add1, $p->getLastAddress($date2)); - //$this->assertSame($add3, $p->getLastAddress($date3)); - dump($p->getLastAddress($date4), $add3); - $this->assertSame($add3, $p->getLastAddress($date4)); - //$this->assertSame($add5, $p->getLastAddress($date5)); - $this->assertSame($add5, $p->getLastAddress($date6)); + yield [(DateTime::createFromFormat('Y-m-d', '2021-01-05'))->settime(0, 0)]; + yield [(DateTime::createFromFormat('Y-m-d', '2021-02-05'))->settime(0, 0)]; + yield [(DateTime::createFromFormat('Y-m-d', '2021-03-05'))->settime(0, 0)]; + } + + /** + * @dataProvider dateProvider + */ + public function testGetLastAddress(DateTime $date) + { + $p = new Person($date); + + // Make sure that there is no last address. + $this::assertNull($p->getLastAddress()); + + // Take an arbitrary date before the $date in parameter. + $addressDate = clone $date; + + // 1. Smoke test: Test that the first address added is the last one. + $address1 = (new Address())->setValidFrom($addressDate->sub(new DateInterval('PT180M'))); + $p->addAddress($address1); + + $this::assertCount(1, $p->getAddresses()); + $this::assertSame($address1, $p->getLastAddress()); + + // 2. Add an older address, which should not be the last address. + $addressDate2 = clone $addressDate; + $address2 = (new Address())->setValidFrom($addressDate2->sub(new DateInterval('PT30M'))); + $p->addAddress($address2); + + $this::assertCount(2, $p->getAddresses()); + $this::assertSame($address1, $p->getLastAddress()); + + // 3. Add a newer address, which should be the last address. + $addressDate3 = clone $addressDate; + $address3 = (new Address())->setValidFrom($addressDate3->add(new DateInterval('PT30M'))); + $p->addAddress($address3); + + $this::assertCount(3, $p->getAddresses()); + $this::assertSame($address3, $p->getLastAddress()); + + // 4. Get the last address from a specific date. + $this::assertEquals($address1, $p->getLastAddress($addressDate)); + $this::assertEquals($address2, $p->getLastAddress($addressDate2)); + $this::assertEquals($address3, $p->getLastAddress($addressDate3)); } }