DoctrineProxySubscriberTest.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. namespace JMS\Serializer\Tests\Serializer\EventDispatcher\Subscriber;
  3. use JMS\Serializer\EventDispatcher\EventDispatcher;
  4. use JMS\Serializer\EventDispatcher\PreSerializeEvent;
  5. use JMS\Serializer\EventDispatcher\Subscriber\DoctrineProxySubscriber;
  6. use JMS\Serializer\Metadata\ClassMetadata;
  7. use JMS\Serializer\Tests\Fixtures\ExclusionStrategy\AlwaysExcludeExclusionStrategy;
  8. use JMS\Serializer\Tests\Fixtures\SimpleObject;
  9. use JMS\Serializer\Tests\Fixtures\SimpleObjectProxy;
  10. use JMS\Serializer\VisitorInterface;
  11. use Metadata\MetadataFactoryInterface;
  12. class DoctrineProxySubscriberTest extends \PHPUnit_Framework_TestCase
  13. {
  14. /** @var VisitorInterface */
  15. private $visitor;
  16. /** @var DoctrineProxySubscriber */
  17. private $subscriber;
  18. /**
  19. * @var EventDispatcher
  20. */
  21. private $dispatcher;
  22. public function testRewritesProxyClassName()
  23. {
  24. $event = $this->createEvent($obj = new SimpleObjectProxy('a', 'b'), array('name' => get_class($obj), 'params' => array()));
  25. $this->subscriber->onPreSerialize($event);
  26. $this->assertEquals(array('name' => get_parent_class($obj), 'params' => array()), $event->getType());
  27. $this->assertTrue($obj->__isInitialized());
  28. }
  29. public function testDoesNotRewriteCustomType()
  30. {
  31. $event = $this->createEvent($obj = new SimpleObjectProxy('a', 'b'), array('name' => 'FakedName', 'params' => array()));
  32. $this->subscriber->onPreSerialize($event);
  33. $this->assertEquals(array('name' => 'FakedName', 'params' => array()), $event->getType());
  34. $this->assertTrue($obj->__isInitialized());
  35. }
  36. public function testProxyLoadingCanBeSkippedForVirtualTypes()
  37. {
  38. $subscriber = new DoctrineProxySubscriber(true);
  39. $event = $this->createEvent($obj = new SimpleObjectProxy('a', 'b'), array('name' => 'FakedName', 'params' => array()));
  40. $subscriber->onPreSerialize($event);
  41. $this->assertEquals(array('name' => 'FakedName', 'params' => array()), $event->getType());
  42. $this->assertFalse($obj->__isInitialized());
  43. }
  44. public function testProxyLoadingCanBeSkippedByExclusionStrategy()
  45. {
  46. $subscriber = new DoctrineProxySubscriber(false, false);
  47. $factoryMock = $this->getMockBuilder(MetadataFactoryInterface::class)->getMock();
  48. $factoryMock->method('getMetadataForClass')->willReturn(new ClassMetadata(SimpleObject::class));
  49. $this->visitor->method('getExclusionStrategy')->willReturn(new AlwaysExcludeExclusionStrategy());
  50. $this->visitor->method('getMetadataFactory')->willReturn($factoryMock);
  51. $event = $this->createEvent($obj = new SimpleObjectProxy('a', 'b'), array('name' => SimpleObjectProxy::class, 'params' => array()));
  52. $subscriber->onPreSerialize($event);
  53. $this->assertFalse($obj->__isInitialized());
  54. // virtual types are still initialized
  55. $event = $this->createEvent($obj = new SimpleObjectProxy('a', 'b'), array('name' => 'FakeName', 'params' => array()));
  56. $subscriber->onPreSerialize($event);
  57. $this->assertTrue($obj->__isInitialized());
  58. }
  59. public function testEventTriggeredOnRealClassName()
  60. {
  61. $proxy = new SimpleObjectProxy('foo', 'bar');
  62. $realClassEventTriggered1 = false;
  63. $this->dispatcher->addListener('serializer.pre_serialize', function () use (&$realClassEventTriggered1) {
  64. $realClassEventTriggered1 = true;
  65. }, get_parent_class($proxy));
  66. $event = $this->createEvent($proxy, array('name' => get_class($proxy), 'params' => array()));
  67. $this->dispatcher->dispatch('serializer.pre_serialize', get_class($proxy), 'json', $event);
  68. $this->assertTrue($realClassEventTriggered1);
  69. }
  70. public function testListenersCanChangeType()
  71. {
  72. $proxy = new SimpleObjectProxy('foo', 'bar');
  73. $realClassEventTriggered1 = false;
  74. $this->dispatcher->addListener('serializer.pre_serialize', function (PreSerializeEvent $event) use (&$realClassEventTriggered1) {
  75. $event->setType('foo', ['bar']);
  76. }, get_parent_class($proxy));
  77. $event = $this->createEvent($proxy, array('name' => get_class($proxy), 'params' => array()));
  78. $this->dispatcher->dispatch('serializer.pre_serialize', get_class($proxy), 'json', $event);
  79. $this->assertSame(['name' => 'foo', 'params' => ['bar']], $event->getType());
  80. }
  81. public function testListenersDoNotChangeTypeOnProxiesAndVirtualTypes()
  82. {
  83. $proxy = new SimpleObjectProxy('foo', 'bar');
  84. $event = $this->createEvent($proxy, ['name' => 'foo', 'params' => []]);
  85. $this->dispatcher->dispatch('serializer.pre_serialize', get_class($proxy), 'json', $event);
  86. $this->assertSame(['name' => 'foo', 'params' => []], $event->getType());
  87. }
  88. public function testOnPreSerializeMaintainsParams()
  89. {
  90. $object = new SimpleObjectProxy('foo', 'bar');
  91. $type = ['name' => SimpleObjectProxy::class, 'params' => ['baz']];
  92. $event = $this->createEvent($object, $type);
  93. $this->subscriber->onPreSerialize($event);
  94. $this->assertSame(['name' => SimpleObject::class, 'params' => ['baz']], $event->getType());
  95. }
  96. protected function setUp()
  97. {
  98. $this->subscriber = new DoctrineProxySubscriber();
  99. $this->visitor = $this->getMockBuilder('JMS\Serializer\Context')->getMock();
  100. $this->dispatcher = new EventDispatcher();
  101. $this->dispatcher->addSubscriber($this->subscriber);
  102. }
  103. private function createEvent($object, array $type)
  104. {
  105. return new PreSerializeEvent($this->visitor, $object, $type);
  106. }
  107. }