diff --git a/src/LiveComponent/src/Test/InteractsWithLiveComponents.php b/src/LiveComponent/src/Test/InteractsWithLiveComponents.php index 377fbad1f34..192555a1734 100644 --- a/src/LiveComponent/src/Test/InteractsWithLiveComponents.php +++ b/src/LiveComponent/src/Test/InteractsWithLiveComponents.php @@ -44,4 +44,24 @@ protected function createLiveComponent(string $name, array $data = [], ?KernelBr self::getContainer()->get('router'), ); } + + protected function assertComponentEmitEvent(TestLiveComponent $testLiveComponent, string $eventName, ?array $parameters = null): void + { + $eventData = $testLiveComponent->getEmittedEvent($testLiveComponent->render(), $eventName); + + $this->assertNotNull($eventData, \sprintf('Event %s not emitted', $eventName)); + + if (null === $parameters) { + return; + } + + foreach ($parameters as $key => $value) { + $this->assertSame($value, $eventData['data'][$key] ?? null, \sprintf('EventData (%s) is not valid', $key)); + } + } + + protected function assertComponentNotEmitEvent(TestLiveComponent $testLiveComponent, string $eventName): void + { + $this->assertNull($testLiveComponent->getEmittedEvent($testLiveComponent->render(), $eventName), \sprintf('Event %s emitted', $eventName)); + } } diff --git a/src/LiveComponent/src/Test/TestLiveComponent.php b/src/LiveComponent/src/Test/TestLiveComponent.php index 0e587a38256..58822479ded 100644 --- a/src/LiveComponent/src/Test/TestLiveComponent.php +++ b/src/LiveComponent/src/Test/TestLiveComponent.php @@ -229,4 +229,35 @@ private function flattenFormValues(array $values, string $prefix = ''): array return $result; } + + /** + * @return ?array{data: array, event: string} + */ + public function getEmittedEvent(RenderedComponent $render, string $eventName): ?array + { + $eventsData = $this->getEmittedEvents($render); + + foreach ($eventsData as $eventData) { + if ($eventData['event'] === $eventName) { + return $eventData; + } + } + + return null; + } + + /** + * @return array, event: string}> + */ + public function getEmittedEvents(RenderedComponent $render): array + { + $div = $render->crawler()->filter('[data-live-name-value]'); + $emit = $div->attr('data-live-events-to-emit-value'); + + if (null === $emit) { + return []; + } + + return json_decode($emit, true); + } } diff --git a/src/LiveComponent/tests/Functional/Test/InteractsWithLiveComponentsTest.php b/src/LiveComponent/tests/Functional/Test/InteractsWithLiveComponentsTest.php index 097e4d770f7..e7e760a45b2 100644 --- a/src/LiveComponent/tests/Functional/Test/InteractsWithLiveComponentsTest.php +++ b/src/LiveComponent/tests/Functional/Test/InteractsWithLiveComponentsTest.php @@ -11,6 +11,7 @@ namespace Symfony\UX\LiveComponent\Tests\Functional\Test; +use PHPUnit\Framework\AssertionFailedError; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\User\InMemoryUser; @@ -217,4 +218,38 @@ public function testSetLocaleRenderLocalizedComponent(): void $testComponent->setRouteLocale('de'); $this->assertStringContainsString('Locale: de', $testComponent->render()); } + + public function testComponentEmitsExpectedEventWithParameters(): void + { + $testComponent = $this->createLiveComponent('component_with_emit'); + + $testComponent->call('actionThatEmits'); + + $this->assertComponentEmitEvent($testComponent, 'event1', [ + 'foo' => 'bar', + ]); + } + + public function testComponentDoesNotEmitUnexpectedEvent(): void + { + $testComponent = $this->createLiveComponent('component_with_emit'); + + $testComponent->call('actionThatEmits'); + + $this->assertComponentNotEmitEvent($testComponent, 'non_emitted_event'); + } + + public function testComponentEmitsEventWithWrongParametersFails(): void + { + $testComponent = $this->createLiveComponent('component_with_emit'); + + $testComponent->call('actionThatEmits'); + + $this->expectException(AssertionFailedError::class); + $this->expectExceptionMessage('EventData (foo2) is not valid'); + $this->assertComponentEmitEvent($testComponent, 'event1', [ + 'foo' => 'bar', + 'foo2' => 'bar2', + ]); + } }