Completed
Push — master ( 9d95dd...590d86 )
by Bukashk0zzz
02:11
created

JmsSerializeListenerTest::serializeObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 11
rs 9.4285
cc 1
eloc 7
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Bukashk0zzzLiipImagineSerializationBundle
5
 *
6
 * (c) Denis Golubovskiy <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Bukashk0zzz\LiipImagineSerializationBundle\Tests\EventListener;
13
14
use Bukashk0zzz\LiipImagineSerializationBundle\Tests\Fixtures\UserPictures;
15
use Doctrine\Common\Annotations\AnnotationReader;
16
use Doctrine\Common\Annotations\AnnotationRegistry;
17
use Doctrine\Common\Annotations\CachedReader;
18
use Doctrine\Common\Cache\ArrayCache;
19
use JMS\Serializer\Construction\UnserializeObjectConstructor;
20
use JMS\Serializer\Handler\HandlerRegistry;
21
use JMS\Serializer\Metadata\Driver\AnnotationDriver;
22
use JMS\Serializer\DeserializationContext;
23
use JMS\Serializer\EventDispatcher\ObjectEvent;
24
use JMS\Serializer\EventDispatcher\Events as JmsEvents;
25
use JMS\Serializer\EventDispatcher\EventDispatcherInterface;
26
use JMS\Serializer\GraphNavigator;
27
use JMS\Serializer\JsonSerializationVisitor;
28
use JMS\Serializer\Naming\CamelCaseNamingStrategy;
29
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
30
use JMS\Serializer\SerializerBuilder;
31
use Metadata\MetadataFactory;
32
use Symfony\Component\Routing\RequestContext;
33
use JMS\Serializer\EventDispatcher\EventDispatcher;
34
use Vich\UploaderBundle\Storage\StorageInterface;
35
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
36
use Liip\ImagineBundle\Imagine\Cache\Signer;
37
use Bukashk0zzz\LiipImagineSerializationBundle\EventListener\JmsSerializeListener;
38
use Bukashk0zzz\LiipImagineSerializationBundle\Tests\Fixtures\User;
39
40
/**
41
 * JmsSerializeListenerTest
42
 *
43
 * @author Artem Genvald <[email protected]>
44
 */
45
class JmsSerializeListenerTest extends \PHPUnit_Framework_TestCase
46
{
47
    /**
48
     * @var EventDispatcherInterface $dispatcher Dispatcher
49
     */
50
    private $dispatcher;
51
52
    /**
53
     * @var RequestContext $requestContext Request context
54
     */
55
    private $requestContext;
56
57
    /**
58
     * @var CachedReader $annotationReader Cached annotation reader
59
     */
60
    private $annotationReader;
61
62
    /**
63
     * @var CacheManager $cacheManager LiipImagineBundle Cache Manager
64
     */
65
    private $cacheManager;
66
67
    /**
68
     * @var StorageInterface $storage Vich storage
69
     */
70
    private $vichStorage;
71
72
    /**
73
     * @var DeserializationContext $context JMS context
74
     */
75
    private $context;
76
77
    /**
78
     * @var string $filePath Image file path
79
     */
80
    private $filePath;
81
82
    /**
83
     * {@inheritdoc}
84
     */
85
    protected function setUp()
86
    {
87
        AnnotationRegistry::registerLoader('class_exists');
88
        $this->filePath = (new User())->getCoverUrl();
89
        $this->annotationReader = new CachedReader(new AnnotationReader(), new ArrayCache());
90
        $this->generateVichStorage();
91
        $this->generateContext();
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    protected function tearDown()
98
    {
99
        $this->dispatcher       = null;
100
        $this->requestContext   = null;
101
        $this->annotationReader = null;
102
        $this->cacheManager = null;
103
        $this->vichStorage = null;
104
        $this->filePath = null;
105
    }
106
107
    /**
108
     * Test virtualField serialization
109
     */
110
    public function testVirtualFieldSerialization()
111
    {
112
        $user = new User();
113
        $this->generateCacheManager();
114
        $this->generateRequestContext();
115
        $serializer = SerializerBuilder::create()->configureListeners(function (EventDispatcher $dispatcher) {
116
            $this->addEvents($dispatcher);
117
        })->build();
118
        $result = $serializer->serialize($user, 'json');
119
120
        static::assertJson($result);
121
        $data = json_decode($result, true);
122
        static::assertEquals('http://a/path/to/an/image3.png', $data['imageThumb']);
123
    }
124
125
    /**
126
     * Test serialization
127
     */
128
    public function testSerialization()
129
    {
130
        $user = new User();
131
        $this->generateCacheManager();
132
        $this->generateRequestContext();
133
        $this->dispatchEvents($user);
134
        static::assertEquals('http://a/path/to/an/image1.png', $user->getCoverUrl());
135
        static::assertEquals('http://a/path/to/an/image2.png', $user->getPhotoName());
136
137
        // Serialize same object second time (check cache)
138
        $this->generateContext();
139
        $this->dispatchEvents($user);
140
141
        static::assertEquals('http://a/path/to/an/image1.png', $user->getCoverUrl());
142
        static::assertEquals('http://a/path/to/an/image2.png', $user->getPhotoName());
143
        static::assertEquals($this->filePath, $user->getImageUrl());
144
    }
145
146
    /**
147
     * Test serialization of proxy object
148
     */
149
    public function testProxySerialization()
150
    {
151
        $userPictures = new UserPictures();
152
        $this->generateCacheManager();
153
        $this->generateRequestContext(false, true);
154
        $data = $this->serializeObject($userPictures);
155
156
        static::assertEquals('http://a/path/to/an/image1.png', $data['cover']);
157
        static::assertEquals('http://example.com:8000/uploads/photo.jpg', $data['photo']);
158
        static::assertEquals('http://a/path/to/an/image2.png', $data['photoThumb']);
159
    }
160
161
    /**
162
     * Test serialization with included http host and port in the URI
163
     */
164
    public function testHttpsSerialization()
165
    {
166
        $userPictures = new UserPictures();
167
        $this->generateCacheManager();
168
        $this->generateRequestContext(true, true);
169
        $data = $this->serializeObject($userPictures);
170
171
        static::assertEquals('https://example.com:8800/uploads/photo.jpg', $data['photo']);
172
    }
173
174
    /**
175
     * @param User|UserPictures $user
176
     * @return array
177
     */
178
    protected function serializeObject($user)
179
    {
180
        $serializer = SerializerBuilder::create()->configureListeners(function (EventDispatcher $dispatcher) {
181
            $this->addEvents($dispatcher);
182
        })->build();
183
        $result = $serializer->serialize($user, 'json');
184
185
        static::assertJson($result);
186
187
        return json_decode($result, true);
188
    }
189
190
    /**
191
     * @param bool $https
192
     * @param bool $port
193
     */
194
    protected function generateRequestContext($https = false, $port = false)
195
    {
196
        $this->requestContext = $this->getMockBuilder('Symfony\Component\Routing\RequestContext')
197
            ->disableOriginalConstructor()
198
            ->getMock();
199
200
        $scheme = $https ? 'https':'http';
201
202
        $this->requestContext->expects(static::any())
203
            ->method('getScheme')
204
            ->willReturn($scheme);
205
206
        $this->requestContext->expects(static::any())
207
            ->method('getHost')
208
            ->willReturn('example.com');
209
210
        if ($port) {
211
            if ($https) {
212
                $this->requestContext->expects(static::any())
213
                    ->method('getHttpsPort')
214
                    ->willReturn(8800);
215
            } else {
216
                $this->requestContext->expects(static::any())
217
                    ->method('getHttpPort')
218
                    ->willReturn(8000);
219
            }
220
        }
221
222
        $this->addEventListeners();
223
    }
224
225
    /**
226
     * Add post & pre serialize event listeners
227
     */
228
    protected function addEventListeners()
229
    {
230
        $this->dispatcher = new EventDispatcher();
231
        $this->addEvents($this->dispatcher);
232
    }
233
234
    /**
235
     * Add post & pre serialize event to dispatcher
236
     * @param EventDispatcher $dispatcher
237
     */
238
    protected function addEvents(EventDispatcher $dispatcher)
239
    {
240
        $listener = new JmsSerializeListener($this->requestContext, $this->annotationReader, $this->cacheManager, $this->vichStorage, [
241
            'includeHost' => true,
242
            'vichUploaderSerialize' => true,
243
        ]);
244
245
        $dispatcher->addListener(JmsEvents::PRE_SERIALIZE, [$listener, 'onPreSerialize']);
246
        $dispatcher->addListener(JmsEvents::POST_SERIALIZE, [$listener, 'onPostSerialize']);
247
    }
248
249
    /**
250
     * Prepare mock of Liip cache manager
251
     */
252
    protected function generateCacheManager()
253
    {
254
        $resolver = static::getMock('Liip\ImagineBundle\Imagine\Cache\Resolver\ResolverInterface');
255
        $resolver
256
            ->expects(static::any())
257
            ->method('isStored')
258
            ->will(static::returnValue(true))
259
        ;
260
        $resolver
261
            ->expects(static::any())
262
            ->method('resolve')
263
            ->will(static::onConsecutiveCalls('http://a/path/to/an/image1.png', 'http://a/path/to/an/image2.png', 'http://a/path/to/an/image3.png'))
264
        ;
265
266
        $config = static::getMock('Liip\ImagineBundle\Imagine\Filter\FilterConfiguration');
267
        $config->expects(static::any())
268
            ->method('get')
269
            ->with('thumb_filter')
270
            ->will(static::returnValue(array(
271
                'size' => array(180, 180),
272
                'mode' => 'outbound',
273
                'cache' => null,
274
            )))
275
        ;
276
277
        $router = static::getMock('Symfony\Component\Routing\RouterInterface');
278
        $router->expects(static::never())
279
            ->method('generate')
280
        ;
281
282
        $eventDispatcher = static::getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
283
284
        /** @noinspection PhpParamsInspection */
285
        $this->cacheManager = new CacheManager($config, $router, new Signer('secret'), $eventDispatcher);
286
287
        /** @noinspection PhpParamsInspection */
288
        $this->cacheManager->addResolver('default', $resolver);
289
    }
290
291
    /**
292
     * Generate vichStorage mock
293
     */
294
    protected function generateVichStorage()
295
    {
296
        $this->vichStorage = $this->getMockBuilder('Vich\UploaderBundle\Storage\FileSystemStorage')
297
            ->disableOriginalConstructor()
298
            ->getMock();
299
        $this->vichStorage->expects(static::any())
300
            ->method('resolveUri')
301
            ->will(static::returnValue('/uploads/photo.jpg'));
302
    }
303
304
    /**
305
     * Generate JMS context
306
     * @return DeserializationContext
307
     */
308
    protected function generateContext()
309
    {
310
        $namingStrategy = new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy());
311
312
        $context = DeserializationContext::create();
313
        $factory = new MetadataFactory(new AnnotationDriver(new AnnotationReader()));
314
        $context->initialize('json', new JsonSerializationVisitor($namingStrategy), new GraphNavigator($factory, new HandlerRegistry(), new UnserializeObjectConstructor(), new EventDispatcher()), $factory);
315
        $this->context = $context;
316
    }
317
318
    /**
319
     * @param User|UserPictures $user
320
     * @return ObjectEvent
321
     */
322
    protected function dispatchEvents($user)
323
    {
324
        /** @noinspection PhpParamsInspection */
325
        $event = new ObjectEvent($this->context, $user, []);
326
        $this->dispatcher->dispatch(JmsEvents::PRE_SERIALIZE, User::class, $this->context->getFormat(), $event);
327
        $this->dispatcher->dispatch(JmsEvents::POST_SERIALIZE, User::class, $this->context->getFormat(), $event);
328
329
        return $event;
330
    }
331
}
332