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