Failed Conditions
Pull Request — master (#262)
by Guilherme
10:25 queued 04:26
created

DynamicFormServiceTest   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 508
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 508
rs 8.8
c 0
b 0
f 0
wmc 36
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LoginCidadao\DynamicFormBundle\Tests\Service;
12
13
use Doctrine\ORM\EntityManagerInterface;
14
use FOS\UserBundle\Model\UserManagerInterface;
15
use LoginCidadao\CoreBundle\Entity\City;
16
use LoginCidadao\CoreBundle\Entity\CityRepository;
17
use LoginCidadao\CoreBundle\Entity\Country;
18
use LoginCidadao\CoreBundle\Entity\CountryRepository;
19
use LoginCidadao\CoreBundle\Entity\IdCard;
20
use LoginCidadao\CoreBundle\Entity\Person;
21
use LoginCidadao\CoreBundle\Entity\PersonAddress;
22
use LoginCidadao\CoreBundle\Entity\State;
23
use LoginCidadao\CoreBundle\Entity\StateRepository;
24
use LoginCidadao\CoreBundle\Model\LocationSelectData;
25
use LoginCidadao\CoreBundle\Model\PersonInterface;
26
use LoginCidadao\DynamicFormBundle\Form\DynamicFormBuilder;
27
use LoginCidadao\DynamicFormBundle\Model\DynamicFormData;
28
use LoginCidadao\DynamicFormBundle\Service\DynamicFormService;
29
use LoginCidadao\OAuthBundle\Entity\Client;
30
use LoginCidadao\TaskStackBundle\Service\TaskStackManagerInterface;
31
use PHPUnit\Framework\MockObject\MockObject;
32
use PHPUnit\Framework\TestCase;
33
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
34
use Symfony\Component\Form\FormInterface;
35
use Symfony\Component\HttpFoundation\Request;
36
use Symfony\Component\HttpFoundation\Response;
37
use Symfony\Component\Routing\RouterInterface;
38
39
class DynamicFormServiceTest extends TestCase
40
{
41
    public function testGetDynamicFormDataWithStateId()
42
    {
43
        $target = $this->createMock('LoginCidadao\TaskStackBundle\Model\TaskTargetInterface');
44
        $task = $this->getMockBuilder('LoginCidadao\OpenIDBundle\Task\CompleteUserInfoTask')
45
            ->disableOriginalConstructor()->getMock();
46
        $task->expects($this->once())->method('getTarget')->willReturn($target);
47
48
        $redirectUrl = 'https://example.com';
49
        $stackManager = $this->getTaskStackManager();
50
        $stackManager->expects($this->once())->method('getTargetUrl')->willReturn($redirectUrl);
51
        $stackManager->expects($this->once())->method('getNextTask')->willReturn($task);
52
53
        $state = new State();
54
        $stateRepo = $this->getLocationRepo('State');
55
        $stateRepo->expects($this->once())->method('find')->with(1)->willReturn($state);
56
57
        $em = $this->getEntityManager();
58
        $em->expects($this->once())->method('getRepository')->willReturn($stateRepo);
59
60
        $formService = $this->getFormService($em, null, null, $stackManager, null);
61
62
        $person = $this->getPerson();
63
        /** @var MockObject|Request $request */
64
        $request = $this->getRequest();
65
        $request->expects($this->exactly(2))->method('get')->willReturnCallback(
66
            function ($key) {
67
                switch ($key) {
68
                    case 'id_card_state_id':
69
                        return 1;
70
                    case 'redirect_url':
71
                        return 'https://example.com';
72
                    default:
73
                        return null;
74
                }
75
            }
76
        );
77
        $scope = 'scope1 scope2';
78
79
        $data = $formService->getDynamicFormData($person, $request, $scope);
80
        $this->assertEquals($person, $data->getPerson());
81
        $this->assertEquals($scope, $data->getScope());
82
        $this->assertEquals($redirectUrl, $data->getRedirectUrl());
83
    }
84
85
    public function testGetDynamicFormDataWithoutState()
86
    {
87
        $target = $this->createMock('LoginCidadao\TaskStackBundle\Model\TaskTargetInterface');
88
        $task = $this->getMockBuilder('LoginCidadao\OpenIDBundle\Task\CompleteUserInfoTask')
89
            ->disableOriginalConstructor()->getMock();
90
        $task->expects($this->once())->method('getTarget')->willReturn($target);
91
92
        $redirectUrl = 'https://example.com';
93
        $stackManager = $this->getTaskStackManager();
94
        $stackManager->expects($this->once())->method('getTargetUrl')->willReturn($redirectUrl);
95
        $stackManager->expects($this->once())->method('getNextTask')->willReturn($task);
96
97
        $formService = $this->getFormService(null, null, null, $stackManager, null);
98
99
        $person = $this->getPerson();
100
        $request = $this->getRequest();
101
        $scope = 'scope1 scope2';
102
103
        $data = $formService->getDynamicFormData($person, $request, $scope);
104
        $this->assertEquals($person, $data->getPerson());
105
        $this->assertEquals($scope, $data->getScope());
106
        $this->assertEquals($redirectUrl, $data->getRedirectUrl());
107
    }
108
109
    public function testGetDynamicFormDataWithoutRedirectUrlNorEvent()
110
    {
111
        $formService = $this->getFormService();
112
113
        $person = $this->getPerson();
114
        $request = $this->getRequest();
115
        $request->expects($this->atLeastOnce())->method('get')->willReturn(null);
116
        $scope = 'scope1 scope2';
117
118
        $data = $formService->getDynamicFormData($person, $request, $scope);
119
        $this->assertEquals($person, $data->getPerson());
120
        $this->assertEquals($scope, $data->getScope());
121
        $this->assertEquals('lc_dashboard', $data->getRedirectUrl());
122
    }
123
124
    public function testGetDynamicFormDataWithStateAcronym()
125
    {
126
        $target = $this->createMock('LoginCidadao\TaskStackBundle\Model\TaskTargetInterface');
127
        $task = $this->getMockBuilder('LoginCidadao\OpenIDBundle\Task\CompleteUserInfoTask')
128
            ->disableOriginalConstructor()->getMock();
129
        $task->expects($this->once())->method('getTarget')->willReturn($target);
130
131
        $redirectUrl = 'https://example.com';
132
        $stackManager = $this->getTaskStackManager();
133
        $stackManager->expects($this->once())->method('getTargetUrl')->willReturn($redirectUrl);
134
        $stackManager->expects($this->once())->method('getNextTask')->willReturn($task);
135
136
        $state = new State();
137
        $stateRepo = $this->getLocationRepo('State');
138
        $stateRepo->expects($this->once())->method('findOneBy')->willReturn($state);
139
140
        $em = $this->getEntityManager();
141
        $em->expects($this->once())->method('getRepository')->willReturn($stateRepo);
142
143
        $formService = $this->getFormService($em, null, null, $stackManager, null);
144
145
        $person = $this->getPerson();
146
        $request = $this->getRequest();
147
        $request->expects($this->atLeastOnce())->method('get')->willReturnCallback(
148
            function ($key) {
149
                switch ($key) {
150
                    case 'id_card_state':
151
                        return 'RS';
152
                    case 'redirect_url':
153
                        return 'https://example.com';
154
                    default:
155
                        return null;
156
                }
157
            }
158
        );
159
        $scope = 'scope1 scope2';
160
161
        $data = $formService->getDynamicFormData($person, $request, $scope);
162
        $this->assertEquals($person, $data->getPerson());
163
        $this->assertEquals($scope, $data->getScope());
164
        $this->assertEquals($redirectUrl, $data->getRedirectUrl());
165
    }
166
167
    public function testProcessInvalidForm()
168
    {
169
        $form = $this->getForm();
170
        $form->expects($this->once())->method('isValid')->willReturn(false);
171
        $request = $this->getRequest();
172
173
        $formService = $this->getFormService();
174
        $formService->processForm($form, $request);
175
    }
176
177
    public function testProcessFormWithPersonForm()
178
    {
179
        $data = new DynamicFormData();
180
        $data
181
            ->setPerson(new Person())
182
            ->setPlaceOfBirth(new LocationSelectData())
183
            ->setAddress(new PersonAddress())
184
            ->setIdCard(new IdCard())
185
            ->setRedirectUrl('https://example.com');
186
187
        $form = $this->getForm();
188
        $form->expects($this->once())->method('isValid')->willReturn(true);
189
        $form->expects($this->once())->method('getData')->willReturn($data);
190
        $form->expects($this->exactly(2))->method('has')->with('person')->willReturn(true);
191
        $form->expects($this->once())->method('get')->with('person')->willReturn($form);
192
        $request = $this->getRequest();
193
194
        $task = $this->getMockBuilder('LoginCidadao\OpenIDBundle\Task\CompleteUserInfoTask')
195
            ->disableOriginalConstructor()->getMock();
196
        $stackManager = $this->getTaskStackManager();
197
        $stackManager->expects($this->once())->method('getCurrentTask')->willReturn($task);
198
        $stackManager->expects($this->once())->method('processRequest')->willReturnCallback(
199
            function ($request, $response) {
200
                return $response;
201
            }
202
        );
203
204
        $formService = $this->getFormService(null, null, null, $stackManager);
205
        $formService->processForm($form, $request);
206
    }
207
208
    public function testProcessFormWithoutPersonForm()
209
    {
210
        $data = new DynamicFormData();
211
        $data
212
            ->setPerson(new Person())
213
            ->setAddress(new PersonAddress())
214
            ->setRedirectUrl('https://example.com');
215
216
        $form = $this->getForm();
217
        $form->expects($this->once())->method('isValid')->willReturn(true);
218
        $form->expects($this->once())->method('getData')->willReturn($data);
219
        $form->expects($this->exactly(2))->method('has')->with('person')->willReturn(false);
220
        $form->expects($this->never())->method('get')->with('person')->willReturn(null);
221
        $request = $this->getRequest();
222
223
        $task = $this->getMockBuilder('LoginCidadao\OpenIDBundle\Task\CompleteUserInfoTask')
224
            ->disableOriginalConstructor()->getMock();
225
        $stackManager = $this->getTaskStackManager();
226
        $stackManager->expects($this->once())->method('getCurrentTask')->willReturn($task);
227
        $stackManager->expects($this->once())->method('processRequest')->willReturnCallback(
228
            function ($request, $response) {
229
                return $response;
230
            }
231
        );
232
233
        $formService = $this->getFormService(null, null, null, $stackManager);
234
        $formService->processForm($form, $request);
235
    }
236
237
    public function testBuildForm()
238
    {
239
        $data = new DynamicFormData();
240
        $data->setPerson($this->getPerson());
241
242
        $form = $this->getForm();
243
        $form->expects($this->exactly(2))->method('add')->willReturn($form);
244
245
        $scopes = ['scope1', 'scope2'];
246
247
        $formService = $this->getFormService();
248
        $result = $formService->buildForm($form, $data, $scopes);
249
250
        $this->assertEquals($form, $result);
251
    }
252
253
    public function testGetClient()
254
    {
255
        $client = new Client();
256
        $client->setId(1)
257
            ->setRandomId('abc');
258
259
        $repo = $this->getMockBuilder('LoginCidadao\OAuthBundle\Entity\ClientRepository')
260
            ->disableOriginalConstructor()->getMock();
261
        $repo->expects($this->once())->method('findOneBy')->with(
262
            ['id' => $client->getId(), 'randomId' => $client->getRandomId()]
263
        )->willReturn($client);
264
265
        $em = $this->getEntityManager();
266
        $em->expects($this->once())->method('getRepository')->willReturn($repo);
267
268
        $clientId = $client->getPublicId();
269
        $formService = $this->getFormService($em);
270
        $result = $formService->getClient($clientId);
271
272
        $this->assertEquals($client, $result);
273
    }
274
275
    public function testGetClientBadId()
276
    {
277
        $this->expectException('\InvalidArgumentException');
278
        $this->expectExceptionMessage('Invalid client_id.');
279
280
        $clientId = 'invalid';
281
        $formService = $this->getFormService();
282
        $formService->getClient($clientId);
283
    }
284
285
    public function testGetClientNotFound()
286
    {
287
        $this->expectException('Symfony\Component\HttpKernel\Exception\NotFoundHttpException');
288
        $this->expectExceptionMessage('Client not found');
289
290
        $repo = $this->getMockBuilder('LoginCidadao\OAuthBundle\Entity\ClientRepository')
291
            ->disableOriginalConstructor()->getMock();
292
        $repo->expects($this->once())->method('findOneBy')->willReturn(null);
293
294
        $em = $this->getEntityManager();
295
        $em->expects($this->once())->method('getRepository')->willReturn($repo);
296
297
        $clientId = '1_abc';
298
        $formService = $this->getFormService($em);
299
        $formService->getClient($clientId);
300
    }
301
302
    public function testGetLocationDataFromRequestCity()
303
    {
304
        $country = new Country(1);
305
        $state = new State(1);
306
        $state->setCountry($country);
307
        $city = new City();
308
        $city->setId(1)
309
            ->setState($state);
310
311
        $repos = [
312
            'City' => $this->getLocationRepo('City'),
313
            'State' => $this->getLocationRepo('State'),
314
            'Country' => $this->getLocationRepo('Country'),
315
        ];
316
        $repos['City']->expects($this->once())->method('find')->with($city->getId())->willReturn($city);
317
318
        $em = $this->getEntityManager();
319
        $em->expects($this->exactly(3))->method('getRepository')->willReturnCallback(
320
            function ($entity) use (&$repos) {
321
                $parts = explode(':', $entity);
322
323
                return $repos[$parts[1]];
324
            }
325
        );
326
327
        $request = $this->getRequest();
328
        $request->expects($this->exactly(3))->method('get')->willReturn(1);
329
330
        $formService = $this->getFormService($em);
331
        $data = $formService->getLocationDataFromRequest($request);
332
333
        $this->assertEquals($country, $data->getPlaceOfBirth()->getCountry());
334
        $this->assertEquals($state, $data->getPlaceOfBirth()->getState());
335
        $this->assertEquals($city, $data->getPlaceOfBirth()->getCity());
336
    }
337
338
    public function testGetLocationDataFromRequestState()
339
    {
340
        $country = new Country(1);
341
        $state = new State(1);
342
        $state->setCountry($country);
343
344
        $repos = [
345
            'City' => $this->getLocationRepo('City'),
346
            'State' => $this->getLocationRepo('State'),
347
            'Country' => $this->getLocationRepo('Country'),
348
        ];
349
        $repos['State']->expects($this->once())->method('find')->with($state->getId())->willReturn($state);
350
351
        $em = $this->getEntityManager();
352
        $em->expects($this->exactly(3))->method('getRepository')->willReturnCallback(
353
            function ($entity) use (&$repos) {
354
                $parts = explode(':', $entity);
355
356
                return $repos[$parts[1]];
357
            }
358
        );
359
360
        $request = $this->getRequest();
361
        $request->expects($this->exactly(3))->method('get')->willReturn(1);
362
363
        $formService = $this->getFormService($em);
364
        $data = $formService->getLocationDataFromRequest($request);
365
366
        $this->assertEquals($country, $data->getPlaceOfBirth()->getCountry());
367
        $this->assertEquals($state, $data->getPlaceOfBirth()->getState());
368
        $this->assertNull($data->getPlaceOfBirth()->getCity());
369
    }
370
371
    public function testGetLocationDataFromRequestCountry()
372
    {
373
        $country = new Country(1);
374
375
        $repos = [
376
            'City' => $this->getLocationRepo('City'),
377
            'State' => $this->getLocationRepo('State'),
378
            'Country' => $this->getLocationRepo('Country'),
379
        ];
380
        $repos['Country']->expects($this->once())->method('find')->with($country->getId())->willReturn($country);
381
382
        $em = $this->getEntityManager();
383
        $em->expects($this->exactly(3))->method('getRepository')->willReturnCallback(
384
            function ($entity) use (&$repos) {
385
                $parts = explode(':', $entity);
386
387
                return $repos[$parts[1]];
388
            }
389
        );
390
391
        $request = $this->getRequest();
392
        $request->expects($this->exactly(3))->method('get')->willReturn(1);
393
394
        $formService = $this->getFormService($em);
395
        $data = $formService->getLocationDataFromRequest($request);
396
397
        $this->assertEquals($country, $data->getPlaceOfBirth()->getCountry());
398
        $this->assertNull($data->getPlaceOfBirth()->getState());
399
        $this->assertNull($data->getPlaceOfBirth()->getCity());
400
    }
401
402
    public function testGetLocationDataFromRequestNoIds()
403
    {
404
        $request = $this->getRequest();
405
        $request->expects($this->exactly(3))->method('get')->willReturn(null);
406
407
        $formService = $this->getFormService();
408
        $data = $formService->getLocationDataFromRequest($request);
409
410
        $this->assertNull($data->getPlaceOfBirth()->getCountry());
411
        $this->assertNull($data->getPlaceOfBirth()->getState());
412
        $this->assertNull($data->getPlaceOfBirth()->getCity());
413
    }
414
415
    public function testSkipCurrent()
416
    {
417
        $request = $this->getRequest();
418
        /** @var MockObject|Response $defaultResponse */
419
        $defaultResponse = $this->createMock('Symfony\Component\HttpFoundation\Response');
420
421
        $task = $this->getMockBuilder('LoginCidadao\OpenIDBundle\Task\CompleteUserInfoTask')
422
            ->disableOriginalConstructor()->getMock();
423
        $stackManager = $this->getTaskStackManager();
424
        $stackManager->expects($this->once())->method('getCurrentTask')->willReturn($task);
425
        $stackManager->expects($this->once())->method('setTaskSkipped')->with($task);
426
        $stackManager->expects($this->once())->method('processRequest')->with($request, $defaultResponse)->willReturn(
427
            $defaultResponse
428
        );
429
430
        $formService = $this->getFormService(null, null, null, $stackManager);
431
        $response = $formService->skipCurrent($request, $defaultResponse);
432
433
        $this->assertEquals($defaultResponse, $response);
434
    }
435
436
    public function testGetSkipUrl()
437
    {
438
        $data = new DynamicFormData();
439
        $data->setRedirectUrl('https://example.com');
440
441
        $task = $this->getMockBuilder('LoginCidadao\OpenIDBundle\Task\CompleteUserInfoTask')
442
            ->disableOriginalConstructor()->getMock();
443
        $stackManager = $this->getTaskStackManager();
444
        $stackManager->expects($this->once())->method('getCurrentTask')->willReturn($task);
445
446
        $formService = $this->getFormService(null, null, null, $stackManager);
447
        $url = $formService->getSkipUrl($data);
448
449
        $this->assertEquals('dynamic_form_skip', $url);
450
    }
451
452
    public function testGetSkipUrlNoTask()
453
    {
454
        $data = new DynamicFormData();
455
        $data->setRedirectUrl('https://example.com');
456
457
        $stackManager = $this->getTaskStackManager();
458
        $stackManager->expects($this->once())->method('getCurrentTask')->willReturn(null);
459
460
        $formService = $this->getFormService(null, null, null, $stackManager);
461
        $url = $formService->getSkipUrl($data);
462
463
        $this->assertEquals($data->getRedirectUrl(), $url);
464
    }
465
466
    /**
467
     * @param EntityManagerInterface|null $em
468
     * @param EventDispatcherInterface|null $dispatcher
469
     * @param UserManagerInterface|null $userManager
470
     * @param TaskStackManagerInterface|null $taskStackManager
471
     * @param DynamicFormBuilder|null $dynamicFormBuilder
472
     * @param RouterInterface|null $router
473
     * @return DynamicFormService
474
     */
475
    private function getFormService(
476
        $em = null,
477
        $dispatcher = null,
478
        $userManager = null,
479
        $taskStackManager = null,
480
        $dynamicFormBuilder = null,
481
        $router = null
482
    ): DynamicFormService {
483
        if (!$em) {
484
            $em = $this->getEntityManager();
485
        }
486
        if (!$dispatcher) {
487
            /** @var MockObject|EventDispatcherInterface $dispatcher */
488
            $dispatcher = $this->createMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
489
        }
490
        if (!$userManager) {
491
            /** @var MockObject|UserManagerInterface $userManager */
492
            $userManager = $this->createMock('FOS\UserBundle\Model\UserManagerInterface');
493
        }
494
        if (!$taskStackManager) {
495
            $taskStackManager = $this->getTaskStackManager();
496
        }
497
        if (!$dynamicFormBuilder) {
498
            /** @var MockObject|DynamicFormBuilder $dynamicFormBuilder */
499
            $dynamicFormBuilder = $this->getMockBuilder('LoginCidadao\DynamicFormBundle\Form\DynamicFormBuilder')
500
                ->disableOriginalConstructor()
501
                ->getMock();
502
        }
503
        if (!$router) {
504
            /** @var MockObject|RouterInterface $router */
505
            $router = $this->createMock(RouterInterface::class);
506
            $router->expects($this->any())->method('generate')
507
                ->willReturnCallback(function ($name) {
508
                    return $name;
509
                });
510
        }
511
512
        $formService = new DynamicFormService(
513
            $em,
514
            $dispatcher,
515
            $userManager,
516
            $taskStackManager,
517
            $dynamicFormBuilder,
518
            $router
519
        );
520
521
        return $formService;
522
    }
523
524
    /**
525
     * @return \PHPUnit\Framework\MockObject\MockObject|TaskStackManagerInterface
526
     */
527
    private function getTaskStackManager()
528
    {
529
        return $this->createMock('LoginCidadao\TaskStackBundle\Service\TaskStackManagerInterface');
530
    }
531
532
    /**
533
     * @return \PHPUnit\Framework\MockObject\MockObject|PersonInterface
534
     */
535
    private function getPerson()
536
    {
537
        return $this->createMock('LoginCidadao\CoreBundle\Model\PersonInterface');
538
    }
539
540
    /**
541
     * @return \PHPUnit\Framework\MockObject\MockObject|EntityManagerInterface
542
     */
543
    private function getEntityManager()
544
    {
545
        return $this->createMock('Doctrine\ORM\EntityManagerInterface');
546
    }
547
548
    /**
549
     * @param $class
550
     * @return null|\PHPUnit\Framework\MockObject\MockObject|CountryRepository|StateRepository|CityRepository
551
     */
552
    private function getLocationRepo($class)
553
    {
554
        switch ($class) {
555
            case 'Country':
556
                return $this->getMockBuilder('LoginCidadao\CoreBundle\Entity\CountryRepository')
557
                    ->disableOriginalConstructor()->getMock();
558
            case 'State':
559
                return $this->getMockBuilder('LoginCidadao\CoreBundle\Entity\StateRepository')
560
                    ->disableOriginalConstructor()->getMock();
561
            case 'City':
562
                return $this->getMockBuilder('LoginCidadao\CoreBundle\Entity\CityRepository')
563
                    ->disableOriginalConstructor()->getMock();
564
            default:
565
                return null;
566
        }
567
    }
568
569
    /**
570
     * @return MockObject|Request
571
     */
572
    private function getRequest()
573
    {
574
        /** @var MockObject|Request $request */
575
        $request = $this->getMockBuilder(Request::class)
576
            ->disableOriginalConstructor()
577
            ->getMock();
578
579
        return $request;
580
    }
581
582
    /**
583
     * @return MockObject|FormInterface
584
     */
585
    private function getForm()
586
    {
587
        return $this->createMock(FormInterface::class);
588
    }
589
}
590