From fa556bbba1f7a6a74360c90df3059028ae7efb05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Jun 2021 11:44:36 +0200 Subject: [PATCH 1/5] basic context for household --- .../Controller/HouseholdController.php | 34 +++++++++++++++ .../Menu/HouseholdMenuBuilder.php | 42 +++++++++++++++++++ .../views/Household/banner.html.twig | 26 ++++++++++++ .../views/Household/layout.html.twig | 17 ++++++++ .../Resources/views/Household/menu.html.twig | 7 ++++ .../views/Household/summary.html.twig | 14 +++++++ .../config/services/menu.yaml | 36 +++++++++------- 7 files changed, 161 insertions(+), 15 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Controller/HouseholdController.php create mode 100644 src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Household/banner.html.twig create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Household/layout.html.twig create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Household/menu.html.twig create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Household/summary.html.twig diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php new file mode 100644 index 000000000..008a569e1 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php @@ -0,0 +1,34 @@ +render('@ChillPerson/Household/summary.html.twig', + [ + 'household' => $household + ] + ); + } +} diff --git a/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php new file mode 100644 index 000000000..03c9b4306 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php @@ -0,0 +1,42 @@ +translator = $translator; + } + + public static function getMenuIds(): array + { + return [ 'household' ]; + } + + public function buildMenu($menuId, MenuItem $menu, array $parameters): void + { + $household = $parameters['household']; + + $menu->addChild($this->translator->trans('Summary'), [ + 'route' => 'chill_person_household_summary', + 'routeParameters' => [ + 'household_id' => $household->getId() + ]]) + ->setExtras(['order' => 10]); + + } + + +} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/banner.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/banner.html.twig new file mode 100644 index 000000000..9ea33c8d4 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/banner.html.twig @@ -0,0 +1,26 @@ +
+
+
+ +
{% set title = title %} +

+ + {{ 'Household'|trans }} + (n°{{ household.id }}) +

+
+ + + + + +
+
+
+
+ + + +
+
+
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/layout.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/layout.html.twig new file mode 100644 index 000000000..6b8faa4b0 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/layout.html.twig @@ -0,0 +1,17 @@ +{% extends "ChillMainBundle::layoutWithVerticalMenu.html.twig" %} + +{% block top_banner %} + {{ include('@ChillPerson/Household/banner.html.twig', { title: block('title') }) }} +{% endblock %} + +{% block layout_wvm_content %} + {% block content %}{% endblock %} +{% endblock %} + +{% block vertical_menu_content %} + {{ chill_menu('household', { + 'layout': '@ChillPerson/Household/menu.html.twig', + 'args' : { 'household': household } + }) }} +{% endblock %} + diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/menu.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/menu.html.twig new file mode 100644 index 000000000..a60abe7eb --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/menu.html.twig @@ -0,0 +1,7 @@ + diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/summary.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/summary.html.twig new file mode 100644 index 000000000..d0305d183 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/summary.html.twig @@ -0,0 +1,14 @@ +{% extends '@ChillPerson/Household/layout.html.twig' %} + +{% block title 'Household summary'|trans %} + +{% block content %} +

{{ block('title') }}

+ +

Household with id {{ household.id }}

+ +

{{ 'Actual household members'|trans }}

+ +

TODO

+ +{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/config/services/menu.yaml b/src/Bundle/ChillPersonBundle/config/services/menu.yaml index e94a81572..344eb2a17 100644 --- a/src/Bundle/ChillPersonBundle/config/services/menu.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/menu.yaml @@ -1,17 +1,23 @@ services: - Chill\PersonBundle\Menu\SectionMenuBuilder: - arguments: - $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface' - $translator: '@Symfony\Component\Translation\TranslatorInterface' - tags: - - { name: 'chill.menu_builder' } - - Chill\PersonBundle\Menu\AdminMenuBuilder: - arguments: - $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface' + Chill\PersonBundle\Menu\: + resource: './../../Menu' + autowire: true tags: - { name: 'chill.menu_builder' } + # Chill\PersonBundle\Menu\SectionMenuBuilder: + # arguments: + # $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface' + # $translator: '@Symfony\Component\Translation\TranslatorInterface' + # tags: + # - { name: 'chill.menu_builder' } + # + # Chill\PersonBundle\Menu\AdminMenuBuilder: + # arguments: + # $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface' + # tags: + # - { name: 'chill.menu_builder' } + # Chill\PersonBundle\Menu\PersonMenuBuilder: arguments: $showAccompanyingPeriod: '%chill_person.accompanying_period%' @@ -19,8 +25,8 @@ services: tags: - { name: 'chill.menu_builder' } - Chill\PersonBundle\Menu\AccompanyingCourseMenuBuilder: - arguments: - $translator: '@Symfony\Contracts\Translation\TranslatorInterface' - tags: - - { name: 'chill.menu_builder' } + # Chill\PersonBundle\Menu\AccompanyingCourseMenuBuilder: + # arguments: + # $translator: '@Symfony\Contracts\Translation\TranslatorInterface' + # tags: + # - { name: 'chill.menu_builder' } From a133f56dcefb0750e7477b7ab5e01ecd6c3ad8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Jun 2021 15:45:39 +0200 Subject: [PATCH 2/5] add routes for household addresses, members, and addresses_moves --- .../Controller/HouseholdController.php | 54 +++++++++++++++++++ .../Menu/HouseholdMenuBuilder.php | 14 +++++ .../views/Household/address_move.html.twig | 11 ++++ .../views/Household/addresses.html.twig | 14 +++++ .../views/Household/members.html.twig | 10 ++++ 5 files changed, 103 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Household/address_move.html.twig create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig create mode 100644 src/Bundle/ChillPersonBundle/Resources/views/Household/members.html.twig diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php index 008a569e1..14ee42669 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdController.php @@ -31,4 +31,58 @@ class HouseholdController extends AbstractController ] ); } + + /** + * @Route( + * "/{household_id}/members", + * name="chill_person_household_members", + * methods={"GET", "HEAD"} + * ) + * @ParamConverter("household", options={"id" = "household_id"}) + */ + public function members(Request $request, Household $household) + { + // TODO ACL + return $this->render('@ChillPerson/Household/members.html.twig', + [ + 'household' => $household + ] + ); + } + + /** + * @Route( + * "/{household_id}/addresses", + * name="chill_person_household_addresses", + * methods={"GET", "HEAD"} + * ) + * @ParamConverter("household", options={"id" = "household_id"}) + */ + public function addresses(Request $request, Household $household) + { + // TODO ACL + return $this->render('@ChillPerson/Household/addresses.html.twig', + [ + 'household' => $household + ] + ); + } + + /** + * @Route( + * "/{household_id}/address/move", + * name="chill_person_household_address_move", + * methods={"GET", "HEAD", "POST"} + * ) + * @ParamConverter("household", options={"id" = "household_id"}) + */ + public function addressMove(Request $request, Household $household) + { + // TODO ACL + return $this->render('@ChillPerson/Household/address_move.html.twig', + [ + 'household' => $household + ] + ); + } } diff --git a/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php index 03c9b4306..2146bbb7c 100644 --- a/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php +++ b/src/Bundle/ChillPersonBundle/Menu/HouseholdMenuBuilder.php @@ -35,6 +35,20 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface 'household_id' => $household->getId() ]]) ->setExtras(['order' => 10]); + + $menu->addChild($this->translator->trans('Members'), [ + 'route' => 'chill_person_household_members', + 'routeParameters' => [ + 'household_id' => $household->getId() + ]]) + ->setExtras(['order' => 20]); + + $menu->addChild($this->translator->trans('Addresses'), [ + 'route' => 'chill_person_household_addresses', + 'routeParameters' => [ + 'household_id' => $household->getId() + ]]) + ->setExtras(['order' => 30]); } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/address_move.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/address_move.html.twig new file mode 100644 index 000000000..755ad8acf --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/address_move.html.twig @@ -0,0 +1,11 @@ +{% extends '@ChillPerson/Household/layout.html.twig' %} + +{% block title 'Move household'|trans %} + +{% block content %} +

{{ block('title') }}

+ +

Household with id {{ household.id }}

+ + +{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig new file mode 100644 index 000000000..9a15b6ecd --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig @@ -0,0 +1,14 @@ +{% extends '@ChillPerson/Household/layout.html.twig' %} + +{% block title 'Addresses history for household'|trans %} + +{% block content %} +

{{ block('title') }}

+ +

Household with id {{ household.id }}

+ + + {{ 'Move household'|trans }} + + +{% endblock %} diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/members.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/members.html.twig new file mode 100644 index 000000000..bd6d54a0b --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/members.html.twig @@ -0,0 +1,10 @@ +{% extends '@ChillPerson/Household/layout.html.twig' %} + +{% block title 'Household members'|trans %} + +{% block content %} +

{{ block('title') }}

+ +

Household with id {{ household.id }}

+ +{% endblock %} From ff5b0bc258690235d793d6e90bb5aab10a923105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Jun 2021 16:20:46 +0200 Subject: [PATCH 3/5] add list for addresses --- .../Entity/Household/Household.php | 62 ++++++++++++++++--- .../views/Household/addresses.html.twig | 3 +- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php index ac22b6e8b..bbec0612a 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php @@ -2,10 +2,12 @@ namespace Chill\PersonBundle\Entity\Household; +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\Collection; -use Chill\MainBundle\Entity\Address; use Symfony\Component\Serializer\Annotation as Serializer; +use Chill\MainBundle\Entity\Address; +use Chill\PersonBundle\Entity\Household\HouseholdMember; /** * @ORM\Entity @@ -24,16 +26,10 @@ class Household * @ORM\Column(type="integer") * @Serializer\Groups({"read"}) */ - private $id; - - public function getId(): ?int - { - return $this->id; - } + private ?int $id; /** * Addresses - * @var Collection * * @ORM\ManyToMany( * targetEntity="Chill\MainBundle\Entity\Address", @@ -41,8 +37,26 @@ class Household * @ORM\JoinTable(name="chill_person_household_to_addresses") * @ORM\OrderBy({"validFrom" = "DESC"}) */ - private $addresses; + private Collection $addresses; + /** + * @ORM\OneToMany( + * targetEntity=HouseholdMember::class, + * mappedBy="household" + * ) + */ + private Collection $members; + + public function __construct() + { + $this->addresses = new ArrayCollection(); + $this->members = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } /** * @param Address $address @@ -74,4 +88,34 @@ class Household return $this->addresses; } + /** + * @return Collection|HouseholdMember[] + */ + public function getMembers(): Collection + { + return $this->members; + } + + public function addMember(HouseholdMember $member): self + { + if (!$this->members->contains($member)) { + $this->members[] = $member; + $member->setHousehold($this); + } + + return $this; + } + + public function removeMember(HouseholdMember $member): self + { + if ($this->members->removeElement($member)) { + // set the owning side to null (unless already changed) + if ($member->getHousehold() === $this) { + $member->setHousehold(null); + } + } + + return $this; + } + } diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig index 9a15b6ecd..aa0aa443b 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Household/addresses.html.twig @@ -7,7 +7,8 @@

Household with id {{ household.id }}

- + {{ 'Move household'|trans }} From 0158c6f2ed7584b49eec58ad5ef337d87e46ac74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Jun 2021 16:21:01 +0200 Subject: [PATCH 4/5] add tests for household --- .../Controller/HouseholdControllerTest.php | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdControllerTest.php diff --git a/src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdControllerTest.php b/src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdControllerTest.php new file mode 100644 index 000000000..33e930e23 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Controller/HouseholdControllerTest.php @@ -0,0 +1,97 @@ +client = $this->getClientAuthenticated(); + } + + /** + * @dataProvider generateValidHouseholdIds + */ + public function testSummary($householdId) + { + $this->client->request( + Request::METHOD_GET, + "/fr/person/household/{$householdId}/summary" + ); + + $this->assertResponseIsSuccessful(); + } + + /** + * @dataProvider generateValidHouseholdIds + */ + public function testMembers($householdId) + { + $this->client->request( + Request::METHOD_GET, + "/fr/person/household/{$householdId}/members" + ); + + $this->assertResponseIsSuccessful(); + } + + /** + * @dataProvider generateValidHouseholdIds + */ + public function testAddresses($householdId) + { + $this->client->request( + Request::METHOD_GET, + "/fr/person/household/{$householdId}/addresses" + ); + + $this->assertResponseIsSuccessful(); + } + + /** + * @dataProvider generateValidHouseholdIds + */ + public function testAddressMove($householdId) + { + $this->client->request( + Request::METHOD_GET, + "/fr/person/household/{$householdId}/address/move" + ); + + $this->assertResponseIsSuccessful(); + + // ici, il faudrait tester la requête POST + } + + public function generateValidHouseholdIds() + { + self::bootKernel(); + $em = self::$container->get(EntityManagerInterface::class); + + $ids = $em->createQuery("SELECT DISTINCT h.id FROM ".Household::class." h ". + "JOIN h.members m ". + "JOIN m.person p ". + "JOIN p.center c ". + "WHERE c.name = :center" + ) + ->setParameter('center', "Center A") + ->setMaxResults(100) + ->getScalarResult() + ; + + \shuffle($ids); + + yield [ \array_pop($ids)['id'] ]; + } +} From e9caa7b4b86fcb2e5b015bd6b10de8d42fba44a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Wed, 2 Jun 2021 21:44:49 +0200 Subject: [PATCH 5/5] add groups on household serialization --- .../Controller/HouseholdMemberController.php | 15 +++--- .../Entity/Household/Household.php | 3 +- .../Entity/Household/HouseholdMember.php | 11 +++++ .../Normalizer/HouseholdNormalizerTest.php | 48 +++++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php index c6fd4dd59..eafdd2ae9 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php @@ -9,6 +9,7 @@ use Symfony\Component\Serializer\Exception; use Symfony\Component\Routing\Annotation\Route; use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\PersonBundle\Household\MembersEditor; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; class HouseholdMemberController extends ApiController { @@ -27,24 +28,20 @@ class HouseholdMemberController extends ApiController } catch (Exception\InvalidArgumentException | Exception\UnexpectedValueException $e) { throw new BadRequestException("Deserialization error: {$e->getMessage()}", 45896, $e); } - dump($editor); + // TODO ACL // // TODO validation // $em = $this->getDoctrine()->getManager(); - // to ensure closing membership before creating one, we must manually open a transaction - $em->beginTransaction(); - foreach ($editor->getPersistable() as $el) { $em->persist($el); } - $em->flush(); - $em->commit(); - - - return $this->json($editor->getHousehold(), Response::HTTP_OK, ["groups" => ["read"]]); + + return $this->json($editor->getHousehold(), Response::HTTP_OK, [], [ + "groups" => ["read"], + ]); } } diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php index bbec0612a..f95b177f9 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/Household.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/Household.php @@ -26,7 +26,7 @@ class Household * @ORM\Column(type="integer") * @Serializer\Groups({"read"}) */ - private ?int $id; + private ?int $id = null; /** * Addresses @@ -44,6 +44,7 @@ class Household * targetEntity=HouseholdMember::class, * mappedBy="household" * ) + * @Serializer\Groups({"read"}) */ private Collection $members; diff --git a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php index 52bd969fc..cd58af565 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php +++ b/src/Bundle/ChillPersonBundle/Entity/Household/HouseholdMember.php @@ -6,6 +6,7 @@ use Doctrine\ORM\Mapping as ORM; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\Position; +use Symfony\Component\Serializer\Annotation as Serializer; /** @@ -20,26 +21,31 @@ class HouseholdMember * @ORM\Id * @ORM\GeneratedValue * @ORM\Column(type="integer") + * @Serializer\Groups({"read"}) */ private $id; /** * @ORM\ManyToOne(targetEntity=Position::class) + * @Serializer\Groups({"read"}) */ private ?Position $position = null; /** * @ORM\Column(type="date_immutable", nullable=true, options={"default": null}) + * @Serializer\Groups({"read"}) */ private ?\DateTimeImmutable $startDate = null; /** * @ORM\Column(type="date_immutable", nullable= true, options={"default": null}) + * @Serializer\Groups({"read"}) */ private ?\DateTimeImmutable $endDate = null; /** * @ORM\Column(type="string", length=255, nullable=true) + * @Serializer\Groups({"read"}) */ private ?string $comment = NULL; @@ -50,6 +56,7 @@ class HouseholdMember /** * @ORM\Column(type="boolean", options={"default": false}) + * @Serializer\Groups({"read"}) */ private bool $holder = false; @@ -59,6 +66,7 @@ class HouseholdMember * @ORM\ManyToOne( * targetEntity="\Chill\PersonBundle\Entity\Person" * ) + * @Serializer\Groups({"read"}) */ private ?Person $person = null; @@ -131,6 +139,9 @@ class HouseholdMember return $this; } + /** + * @Serializer\Groups({"read"}) + */ public function getShareHousehold(): ?bool { return $this->sharedHousehold; diff --git a/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php new file mode 100644 index 000000000..9dd348c82 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Tests/Serializer/Normalizer/HouseholdNormalizerTest.php @@ -0,0 +1,48 @@ +normalizer= self::$container->get(NormalizerInterface::class); + } + + public function testNormalizationRecursive() + { + $person = new Person(); + $member = new HouseholdMember(); + $household = new Household(); + $position = (new Position()) + ->setShareHousehold(true) + ->setAllowHolder(true) + ; + + $member->setPerson($person) + ->setStartDate(new \DateTimeImmutable('1 year ago')) + ->setEndDate(new \DateTimeImmutable('1 month ago')); + + $household->addMember($member); + + $normalized = $this->normalizer->normalize($household, + 'json', [ 'groups' => [ 'read' ]]); + + $this->assertIsArray($normalized); + $this->assertArrayHasKey('type', $normalized); + $this->assertEquals('household', $normalized['type']); + } + +}