buildNormalizer()->normalize($ticket, 'json', ['groups' => 'read']); self::assertEqualsCanonicalizing(array_keys($expected), array_keys($actual)); foreach (array_keys($expected) as $k) { if ('history' === $k) { continue; } self::assertEqualsCanonicalizing($expected[$k], $actual[$k], sprintf("assert the content of the '%s' key", $k)); } self::assertArrayHasKey('history', $actual); self::assertIsArray($actual['history']); foreach ($actual['history'] as $k => $eventType) { self::assertEquals($expected['history'][$k]['event_type'], $eventType['event_type']); } } public static function provideTickets(): iterable { $t = new Ticket(); // added by action new StateHistory(StateEnum::OPEN, $t, new \DateTimeImmutable('2024-06-16T00:00:00Z')); // those are added by doctrine listeners $t->setCreatedAt(new \DateTimeImmutable('2024-06-16T00:00:00Z')); $t->setCreatedBy(new User()); $t->setUpdatedAt(new \DateTimeImmutable('2024-06-16T00:00:00Z')); $t->setUpdatedBy(new User()); yield [ // this a nearly empty ticket $t, [ 'type' => 'ticket_ticket', 'createdAt' => $t->getCreatedAt()?->getTimestamp(), 'createdBy' => ['user'], 'id' => null, 'externalRef' => '', 'currentPersons' => [], 'currentAddressees' => [], 'currentInputs' => [], 'currentMotive' => null, 'history' => [ [ 'event_type' => 'create_ticket', 'at' => 1718495999, 'by' => [ 0 => 'user', ], 'data' => [], ], [ 'event_type' => 'state_change', 'at' => 1718495999, 'by' => [ 0 => 'user', ], 'data' => [ 'new_state' => 'open', ], ], ], 'currentState' => 'open', 'updatedAt' => $t->getUpdatedAt()->getTimestamp(), 'updatedBy' => ['user'], 'emergency' => 'no', ], ]; // ticket with more features $ticket = new Ticket(); // added by action new StateHistory(StateEnum::OPEN, $ticket, new \DateTimeImmutable('2024-06-16T00:00:00Z')); new EmergencyStatusHistory(EmergencyStatusEnum::YES, $ticket, new \DateTimeImmutable('2024-06-16T00:00:10Z')); // those are added by doctrine listeners $ticket->setCreatedAt(new \DateTimeImmutable('2024-06-16T00:00:00Z')); $ticket->setCreatedBy(new User()); $ticket->setUpdatedAt(new \DateTimeImmutable('2024-06-16T00:00:00Z')); $ticket->setUpdatedBy(new User()); $ticket->setExternalRef('2134'); $personHistory = new PersonHistory(new Person(), $ticket, new \DateTimeImmutable('2024-04-01T12:00:00')); $ticketHistory = new MotiveHistory(new Motive(), $ticket, new \DateTimeImmutable('2024-04-01T12:02:00')); $comment = new Comment('blabla test', $ticket); $comment->setCreatedAt(new \DateTimeImmutable('2024-04-01T12:04:00')); $comment->setCreatedBy(new User()); $addresseeHistory = new AddresseeHistory(new User(), new \DateTimeImmutable('2024-04-01T12:05:00'), $ticket); $addresseeHistory->setEndDate(new \DateTimeImmutable('2024-04-01T12:06:00')); new AddresseeHistory(new UserGroup(), new \DateTimeImmutable('2024-04-01T12:07:00'), $ticket); yield [ $ticket, [ 'type' => 'ticket_ticket', 'createdAt' => $ticket->getCreatedAt()?->getTimestamp(), 'createdBy' => ['user'], 'id' => null, 'externalRef' => '2134', 'currentPersons' => ['embedded'], 'currentAddressees' => ['embedded'], 'currentInputs' => [], 'currentMotive' => ['type' => 'motive', 'id' => 0], 'history' => [ ['event_type' => 'add_person'], ['event_type' => 'persons_state'], ['event_type' => 'set_motive'], ['event_type' => 'add_comment'], ['event_type' => 'addressees_state'], ['event_type' => 'addressees_state'], ['event_type' => 'addressees_state'], ['event_type' => 'create_ticket'], ['event_type' => 'state_change'], ['event_type' => 'emergency_change'], ], 'currentState' => 'open', 'updatedAt' => $ticket->getUpdatedAt()->getTimestamp(), 'updatedBy' => ['user'], 'emergency' => 'yes', ], ]; } private function buildNormalizer(): TicketNormalizer { $normalizer = $this->prophesize(NormalizerInterface::class); // empty array $normalizer->normalize( Argument::that(fn ($arg) => is_array($arg) && 0 === count($arg)), 'json', Argument::type('array') )->willReturn([]); // array of mixed objects $normalizer->normalize( Argument::that(fn ($arg) => is_array($arg) && 0 < count($arg) && is_object($arg[0])), 'json', Argument::type('array') )->will(fn ($args) => array_fill(0, count($args[0]), 'embedded')); // array of event type $normalizer->normalize( Argument::that(fn ($arg) => is_array($arg) && 0 < count($arg) && is_array($arg[0]) && array_key_exists('event_type', $arg[0])), 'json', Argument::type('array') )->will(function ($args): array { $events = []; foreach ($args[0] as $event) { $events[] = $event['event_type']; } return $events; }); // array of persons $normalizer->normalize( Argument::that(fn ($arg) => is_array($arg) && 1 === count($arg) && array_key_exists('persons', $arg)), 'json', ['groups' => 'read'] )->will(fn ($args): array => ['persons' => []]); // array of addresses $normalizer->normalize( Argument::that(fn ($arg) => is_array($arg) && 1 === count($arg) && array_key_exists('addressees', $arg)), 'json', ['groups' => 'read'] )->will(fn ($args): array => ['addressees' => []]); // state data $normalizer->normalize( Argument::that(fn ($arg) => is_array($arg) && 1 === count($arg) && array_key_exists('new_state', $arg)), 'json', ['groups' => 'read'] )->will(fn ($args): array => $args[0]); $normalizer->normalize( Argument::that(fn ($arg) => is_array($arg) && 1 === count($arg) && array_key_exists('new_emergency', $arg)), 'json', ['groups' => 'read'] )->will(fn ($args): array => $args[0]); // datetime $normalizer->normalize(Argument::type(\DateTimeImmutable::class), 'json', Argument::type('array')) ->will(fn ($args) => $args[0]->getTimestamp()); // user $normalizer->normalize(Argument::type(User::class), 'json', Argument::type('array')) ->willReturn(['user']); // motive $normalizer->normalize(Argument::type(Motive::class), 'json', Argument::type('array'))->willReturn(['type' => 'motive', 'id' => 0]); // person history $normalizer->normalize(Argument::type(PersonHistory::class), 'json', Argument::type('array')) ->willReturn(['personHistory']); // motive history $normalizer->normalize(Argument::type(MotiveHistory::class), 'json', Argument::type('array')) ->willReturn(['motiveHistory']); $normalizer->normalize(Argument::type(Comment::class), 'json', Argument::type('array')) ->willReturn(['comment']); $normalizer->normalize(Argument::type(AddresseeHistory::class), 'json', Argument::type('array')) ->willReturn(['addresseeHistory']); // null values $normalizer->normalize(null, 'json', Argument::type('array'))->willReturn(null); $ticketNormalizer = new TicketNormalizer(); $ticketNormalizer->setNormalizer($normalizer->reveal()); return $ticketNormalizer; } }