Failed Conditions
Push — master ( 2ade86...13f838 )
by Jonathan
18s
created

Tests/ORM/Functional/PostLoadEventTest.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Doctrine\Tests\ORM\Functional;
3
4
use Doctrine\Common\Util\ClassUtils;
5
use Doctrine\ORM\Event\LifecycleEventArgs;
6
use Doctrine\ORM\Events;
7
use Doctrine\Tests\Models\CMS\CmsAddress;
8
use Doctrine\Tests\Models\CMS\CmsEmail;
9
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
10
use Doctrine\Tests\Models\CMS\CmsUser;
11
use Doctrine\Tests\OrmFunctionalTestCase;
12
13
/**
14
 * PostLoadEventTest
15
 *
16
 * @author Guilherme Blanco <[email protected]>
17
 */
18
class PostLoadEventTest extends OrmFunctionalTestCase
19
{
20
    /**
21
     * @var integer
22
     */
23
    private $userId;
24
25
    /**
26
     * {@inheritdoc}
27
     */
28
    protected function setUp()
29
    {
30
        $this->useModelSet('cms');
31
32
        parent::setUp();
33
34
        $this->loadFixture();
35
    }
36
37
    public function testLoadedEntityUsingFindShouldTriggerEvent()
38
    {
39
        $mockListener = $this->createMock(PostLoadListener::class);
40
41
        // CmsUser and CmsAddres, because it's a ToOne inverse side on CmsUser
42
        $mockListener
43
            ->expects($this->exactly(2))
44
            ->method('postLoad')
45
            ->will($this->returnValue(true));
46
47
        $eventManager = $this->_em->getEventManager();
48
49
        $eventManager->addEventListener([Events::postLoad], $mockListener);
50
51
        $this->_em->find(CmsUser::class, $this->userId);
52
    }
53
54 View Code Duplication
    public function testLoadedEntityUsingQueryShouldTriggerEvent()
55
    {
56
        $mockListener = $this->createMock(PostLoadListener::class);
57
58
        // CmsUser and CmsAddres, because it's a ToOne inverse side on CmsUser
59
        $mockListener
60
            ->expects($this->exactly(2))
61
            ->method('postLoad')
62
            ->will($this->returnValue(true));
63
64
        $eventManager = $this->_em->getEventManager();
65
66
        $eventManager->addEventListener([Events::postLoad], $mockListener);
67
68
        $query = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id');
69
70
        $query->setParameter('id', $this->userId);
71
        $query->getResult();
72
    }
73
74 View Code Duplication
    public function testLoadedAssociationToOneShouldTriggerEvent()
75
    {
76
        $mockListener = $this->createMock(PostLoadListener::class);
77
78
        // CmsUser (root), CmsAddress (ToOne inverse side), CmsEmail (joined association)
79
        $mockListener
80
            ->expects($this->exactly(3))
81
            ->method('postLoad')
82
            ->will($this->returnValue(true));
83
84
        $eventManager = $this->_em->getEventManager();
85
86
        $eventManager->addEventListener([Events::postLoad], $mockListener);
87
88
        $query = $this->_em->createQuery('SELECT u, e FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e WHERE u.id = :id');
89
90
        $query->setParameter('id', $this->userId);
91
        $query->getResult();
92
    }
93
94 View Code Duplication
    public function testLoadedAssociationToManyShouldTriggerEvent()
95
    {
96
        $mockListener = $this->createMock(PostLoadListener::class);
97
98
        // CmsUser (root), CmsAddress (ToOne inverse side), 2 CmsPhonenumber (joined association)
99
        $mockListener
100
            ->expects($this->exactly(4))
101
            ->method('postLoad')
102
            ->will($this->returnValue(true));
103
104
        $eventManager = $this->_em->getEventManager();
105
106
        $eventManager->addEventListener([Events::postLoad], $mockListener);
107
108
        $query = $this->_em->createQuery('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p WHERE u.id = :id');
109
110
        $query->setParameter('id', $this->userId);
111
        $query->getResult();
112
    }
113
114
    public function testLoadedProxyEntityShouldTriggerEvent()
115
    {
116
        $eventManager = $this->_em->getEventManager();
117
118
        // Should not be invoked during getReference call
119
        $mockListener = $this->createMock(PostLoadListener::class);
120
121
        $mockListener
122
            ->expects($this->never())
123
            ->method('postLoad')
124
            ->will($this->returnValue(true));
125
126
        $eventManager->addEventListener([Events::postLoad], $mockListener);
127
128
        $userProxy = $this->_em->getReference(CmsUser::class, $this->userId);
129
130
        // Now deactivate original listener and attach new one
131
        $eventManager->removeEventListener([Events::postLoad], $mockListener);
132
133
        $mockListener2 = $this->createMock(PostLoadListener::class);
134
135
        $mockListener2
136
            ->expects($this->exactly(2))
137
            ->method('postLoad')
138
            ->will($this->returnValue(true));
139
140
        $eventManager->addEventListener([Events::postLoad], $mockListener2);
141
142
        $userProxy->getName();
143
    }
144
145 View Code Duplication
    public function testLoadedProxyPartialShouldTriggerEvent()
146
    {
147
        $eventManager = $this->_em->getEventManager();
148
149
        // Should not be invoked during getReference call
150
        $mockListener = $this->createMock(PostLoadListener::class);
151
152
        // CmsUser (partially loaded), CmsAddress (inverse ToOne), 2 CmsPhonenumber
153
        $mockListener
154
            ->expects($this->exactly(4))
155
            ->method('postLoad')
156
            ->will($this->returnValue(true));
157
158
        $eventManager->addEventListener([Events::postLoad], $mockListener);
159
160
        $query = $this->_em->createQuery('SELECT PARTIAL u.{id, name}, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p WHERE u.id = :id');
161
162
        $query->setParameter('id', $this->userId);
163
        $query->getResult();
164
    }
165
166 View Code Duplication
    public function testLoadedProxyAssociationToOneShouldTriggerEvent()
167
    {
168
        $user = $this->_em->find(CmsUser::class, $this->userId);
169
170
        $mockListener = $this->createMock(PostLoadListener::class);
171
172
        // CmsEmail (proxy)
173
        $mockListener
174
            ->expects($this->exactly(1))
175
            ->method('postLoad')
176
            ->will($this->returnValue(true));
177
178
        $eventManager = $this->_em->getEventManager();
179
180
        $eventManager->addEventListener([Events::postLoad], $mockListener);
181
182
        $emailProxy = $user->getEmail();
183
184
        $emailProxy->getEmail();
185
    }
186
187 View Code Duplication
    public function testLoadedProxyAssociationToManyShouldTriggerEvent()
188
    {
189
        $user = $this->_em->find(CmsUser::class, $this->userId);
190
191
        $mockListener = $this->createMock(PostLoadListener::class);
192
193
        // 2 CmsPhonenumber (proxy)
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
194
        $mockListener
195
            ->expects($this->exactly(2))
196
            ->method('postLoad')
197
            ->will($this->returnValue(true));
198
199
        $eventManager = $this->_em->getEventManager();
200
201
        $eventManager->addEventListener([Events::postLoad], $mockListener);
202
203
        $phonenumbersCol = $user->getPhonenumbers();
204
205
        $phonenumbersCol->first();
206
    }
207
208
    /**
209
     * @group DDC-3005
210
     */
211
    public function testAssociationsArePopulatedWhenEventIsFired()
212
    {
213
        $checkerListener = new PostLoadListenerCheckAssociationsArePopulated();
214
        $this->_em->getEventManager()->addEventListener([Events::postLoad], $checkerListener);
215
216
        $qb = $this->_em->getRepository(CmsUser::class)->createQueryBuilder('u');
217
        $qb->leftJoin('u.email', 'email');
218
        $qb->addSelect('email');
219
        $qb->getQuery()->getSingleResult();
220
221
        $this->assertTrue($checkerListener->checked, 'postLoad event is not invoked');
222
        $this->assertTrue($checkerListener->populated, 'Association of email is not populated in postLoad event');
223
    }
224
225
    /**
226
     * @group DDC-3005
227
     */
228
    public function testEventRaisedCorrectTimesWhenOtherEntityLoadedInEventHandler()
229
    {
230
        $eventManager = $this->_em->getEventManager();
231
        $listener = new PostLoadListenerLoadEntityInEventHandler();
232
        $eventManager->addEventListener([Events::postLoad], $listener);
233
234
        $this->_em->find(CmsUser::class, $this->userId);
235
        $this->assertSame(1, $listener->countHandledEvents(CmsUser::class), CmsUser::class . ' should be handled once!');
236
        $this->assertSame(1, $listener->countHandledEvents(CmsEmail::class), CmsEmail::class . ' should be handled once!');
237
    }
238
239
    private function loadFixture()
240
    {
241
        $user = new CmsUser;
242
        $user->name = 'Roman';
243
        $user->username = 'romanb';
244
        $user->status = 'developer';
245
246
        $address = new CmsAddress;
247
        $address->country = 'Germany';
248
        $address->city = 'Berlin';
249
        $address->zip = '12345';
250
251
        $user->setAddress($address);
252
253
        $email = new CmsEmail;
254
        $email->setEmail('[email protected]');
255
256
        $user->setEmail($email);
257
258
        $ph1 = new CmsPhonenumber;
259
        $ph1->phonenumber = "0301234";
260
261
        $ph2 = new CmsPhonenumber;
262
        $ph2->phonenumber = "987654321";
263
264
        $user->addPhonenumber($ph1);
265
        $user->addPhonenumber($ph2);
266
267
        $this->_em->persist($user);
268
        $this->_em->flush();
269
270
        $this->userId = $user->getId();
271
272
        $this->_em->clear();
273
    }
274
}
275
276
class PostLoadListener
277
{
278
    public function postLoad(LifecycleEventArgs $event)
0 ignored issues
show
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
279
    {
280
        // Expected to be mocked out
281
        echo 'Should never be called!';
282
    }
283
}
284
285
class PostLoadListenerCheckAssociationsArePopulated
286
{
287
    public $checked = false;
288
289
    public $populated = false;
290
291
    public function postLoad(LifecycleEventArgs $event)
292
    {
293
        $object = $event->getObject();
294
        if ($object instanceof CmsUser) {
295
            if ($this->checked) {
296
                throw new \RuntimeException('Expected to be one user!');
297
            }
298
            $this->checked = true;
299
            $this->populated = null !== $object->getEmail();
300
        }
301
    }
302
}
303
304
class PostLoadListenerLoadEntityInEventHandler
305
{
306
    private $firedByClasses = [];
307
308
    public function postLoad(LifecycleEventArgs $event)
309
    {
310
        $object = $event->getObject();
311
        $class = ClassUtils::getClass($object);
312
        if (!isset($this->firedByClasses[$class])) {
313
            $this->firedByClasses[$class] = 1;
314
        } else {
315
            $this->firedByClasses[$class]++;
316
        }
317
        if ($object instanceof CmsUser) {
318
            $object->getEmail()->getEmail();
319
        }
320
    }
321
322
    public function countHandledEvents($className)
323
    {
324
        return isset($this->firedByClasses[$className]) ? $this->firedByClasses[$className] : 0;
325
    }
326
}
327