Skip to content

Commit 1fe48f1

Browse files
test: update tests
1 parent 0e4e0a3 commit 1fe48f1

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

tests/Doctrine/EventListener/PublishMercureUpdatesListenerTest.php

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use ApiPlatform\Metadata\ApiResource;
2323
use ApiPlatform\Metadata\Get;
2424
use ApiPlatform\Metadata\Operations;
25+
use ApiPlatform\Metadata\Post;
2526
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2627
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2728
use ApiPlatform\Tests\Fixtures\NotAResource;
@@ -30,6 +31,7 @@
3031
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\DummyFriend;
3132
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\DummyMercure;
3233
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\DummyOffer;
34+
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\MercureWithTopics;
3335
use Doctrine\ORM\EntityManagerInterface;
3436
use Doctrine\ORM\Event\OnFlushEventArgs;
3537
use Doctrine\ORM\UnitOfWork;
@@ -169,6 +171,123 @@ public function testPublishUpdate(): void
169171
$this->assertEquals([null, null, null, null, null, 10, null], $retry);
170172
}
171173

174+
public function testPublishUpdateMultipleTopicsUsingExpressionLanguage(): void
175+
{
176+
$mercure = [
177+
'topics' => [
178+
'@=iri(object)',
179+
'@=iri(object, '.UrlGeneratorInterface::ABS_PATH.')',
180+
'@=iri(object, '.UrlGeneratorInterface::ABS_URL.', getOperation(object, "/custom_resource/mercure_with_topics/{id}{._format}"))',
181+
],
182+
];
183+
184+
$toInsert = new MercureWithTopics();
185+
$toInsert->id = 1;
186+
$toInsert->name = 'Hello World!';
187+
188+
$toUpdate = new MercureWithTopics();
189+
$toUpdate->id = 2;
190+
$toUpdate->name = 'Hello World!';
191+
192+
$toDelete = new MercureWithTopics();
193+
$toDelete->id = 3;
194+
$toDelete->name = 'Hello World!';
195+
196+
// Even if it's the Post operation which sends Updates to Mercure,
197+
// the `mercure` configuration is retrieved from the first operation
198+
// of the resource because the Doctrine Listener doesn't have a
199+
// reference to the operation.
200+
$getOperation = (new Get())->withMercure($mercure)->withShortName('MercureWithTopics');
201+
$customGetOperation = (new Get(uriTemplate: '/custom_resource/mercure_with_topics/{id}{._format}'));
202+
$postOperation = (new Post());
203+
204+
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
205+
$resourceClassResolverProphecy->getResourceClass(Argument::type(MercureWithTopics::class))->willReturn(MercureWithTopics::class);
206+
$resourceClassResolverProphecy->isResourceClass(MercureWithTopics::class)->willReturn(true);
207+
208+
$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
209+
210+
$iriConverterProphecy->getIriFromResource($toInsert, UrlGeneratorInterface::ABS_URL, null)->willReturn('http://example.com/mercure_with_topics/1')->shouldBeCalled();
211+
$iriConverterProphecy->getIriFromResource($toInsert, UrlGeneratorInterface::ABS_PATH, null)->willReturn('/mercure_with_topics/1')->shouldBeCalled();
212+
$iriConverterProphecy->getIriFromResource($toInsert, UrlGeneratorInterface::ABS_URL, Argument::exact($customGetOperation))->willReturn('http://example.com/custom_resource/mercure_with_topics/1')->shouldBeCalled();
213+
214+
$iriConverterProphecy->getIriFromResource($toUpdate, UrlGeneratorInterface::ABS_URL, null)->willReturn('http://example.com/mercure_with_topics/2')->shouldBeCalled();
215+
$iriConverterProphecy->getIriFromResource($toUpdate, UrlGeneratorInterface::ABS_PATH, null)->willReturn('/mercure_with_topics/2')->shouldBeCalled();
216+
$iriConverterProphecy->getIriFromResource($toUpdate, UrlGeneratorInterface::ABS_URL, Argument::exact($customGetOperation))->willReturn('http://example.com/custom_resource/mercure_with_topics/2')->shouldBeCalled();
217+
218+
$iriConverterProphecy->getIriFromResource($toDelete)->willReturn('/mercure_with_topics/3')->shouldBeCalled();
219+
$iriConverterProphecy->getIriFromResource($toDelete, UrlGeneratorInterface::ABS_URL, null)->willReturn('http://example.com/mercure_with_topics/3')->shouldBeCalled();
220+
$iriConverterProphecy->getIriFromResource($toDelete, UrlGeneratorInterface::ABS_PATH, null)->willReturn('/mercure_with_topics/3')->shouldBeCalled();
221+
$iriConverterProphecy->getIriFromResource($toDelete, UrlGeneratorInterface::ABS_URL, Argument::exact($customGetOperation))->willReturn('http://example.com/custom_resource/mercure_with_topics/3')->shouldBeCalled();
222+
223+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
224+
225+
$resourceMetadataFactoryProphecy->create(MercureWithTopics::class)->willReturn(new ResourceMetadataCollection(MercureWithTopics::class, [
226+
(new ApiResource())->withOperations(new Operations([
227+
'get' => $getOperation,
228+
'custom_get' => $customGetOperation,
229+
'post' => $postOperation,
230+
])),
231+
]))->shouldBeCalled();
232+
233+
$serializerProphecy = $this->prophesize(SerializerInterface::class);
234+
$serializerProphecy->serialize($toInsert, 'jsonld', [])->willReturn('{"@type":"MercureWithTopics","@id":"/mercure_with_topics/1","id":1,"name":"Hello World!"}')->shouldBeCalled();
235+
$serializerProphecy->serialize($toUpdate, 'jsonld', [])->willReturn('{"@type":"MercureWithTopics","@id":"/mercure_with_topics/2","id":2,"name":"Hello World!"}')->shouldBeCalled();
236+
237+
$formats = ['jsonld' => ['application/ld+json'], 'jsonhal' => ['application/hal+json']];
238+
239+
$topics = [];
240+
$private = [];
241+
$retry = [];
242+
$data = [];
243+
244+
$defaultHub = $this->createMockHub(function (Update $update) use (&$topics, &$private, &$retry, &$data): string {
245+
$topics = array_merge($topics, $update->getTopics());
246+
$private[] = $update->isPrivate();
247+
$retry[] = $update->getRetry();
248+
$data[] = $update->getData();
249+
250+
return 'id';
251+
});
252+
253+
$listener = new PublishMercureUpdatesListener(
254+
$resourceClassResolverProphecy->reveal(),
255+
$iriConverterProphecy->reveal(),
256+
$resourceMetadataFactoryProphecy->reveal(),
257+
$serializerProphecy->reveal(),
258+
$formats,
259+
null,
260+
new HubRegistry($defaultHub, ['default' => $defaultHub]),
261+
null,
262+
null,
263+
null,
264+
true,
265+
);
266+
267+
$uowProphecy = $this->prophesize(UnitOfWork::class);
268+
$uowProphecy->getScheduledEntityInsertions()->willReturn([$toInsert])->shouldBeCalled();
269+
$uowProphecy->getScheduledEntityUpdates()->willReturn([$toUpdate])->shouldBeCalled();
270+
$uowProphecy->getScheduledEntityDeletions()->willReturn([$toDelete])->shouldBeCalled();
271+
272+
$emProphecy = $this->prophesize(EntityManagerInterface::class);
273+
$emProphecy->getUnitOfWork()->willReturn($uowProphecy->reveal())->shouldBeCalled();
274+
$eventArgs = new OnFlushEventArgs($emProphecy->reveal());
275+
276+
$listener->onFlush($eventArgs);
277+
$listener->postFlush();
278+
279+
$this->assertEquals([
280+
'{"@type":"MercureWithTopics","@id":"/mercure_with_topics/1","id":1,"name":"Hello World!"}',
281+
'{"@type":"MercureWithTopics","@id":"/mercure_with_topics/2","id":2,"name":"Hello World!"}',
282+
'{"@id":"\/mercure_with_topics\/3","@type":"MercureWithTopics"}',
283+
], $data);
284+
$this->assertEquals([
285+
'http://example.com/mercure_with_topics/1', '/mercure_with_topics/1', 'http://example.com/custom_resource/mercure_with_topics/1',
286+
'http://example.com/mercure_with_topics/2', '/mercure_with_topics/2', 'http://example.com/custom_resource/mercure_with_topics/2',
287+
'http://example.com/mercure_with_topics/3', '/mercure_with_topics/3', 'http://example.com/custom_resource/mercure_with_topics/3',
288+
], $topics);
289+
}
290+
172291
public function testPublishGraphQlUpdates(): void
173292
{
174293
$toUpdate = new Dummy();

0 commit comments

Comments
 (0)