Failed Conditions
Pull Request — master (#26)
by Bob Olde
07:33
created

tests/services/UserGroupsTest.php (3 issues)

Labels
Severity

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
3
namespace NerdsAndCompany\Schematic\Services;
4
5
use Craft\Craft;
6
use Craft\BaseTest;
7
use Craft\UserGroupModel;
8
use Craft\SectionModel;
9
use Craft\AssetSourceModel;
10
use Craft\GlobalSetModel;
11
use Craft\UserGroupsService;
12
use Craft\SectionsService;
13
use Craft\AssetSourcesService;
14
use Craft\GlobalsService;
15
use Craft\UserPermissionsService;
16
use NerdsAndCompany\Schematic\Models\Result;
17
use PHPUnit_Framework_MockObject_MockObject as Mock;
18
19
/**
20
 * Class UserGroupsTest.
21
 *
22
 * @author    Nerds & Company
23
 * @copyright Copyright (c) 2015, Nerds & Company
24
 * @license   MIT
25
 *
26
 * @link      http://www.nerds.company
27
 *
28
 * @coversDefaultClass NerdsAndCompany\Schematic\Services\UserGroups
29
 * @covers ::__construct
30
 * @covers ::<!public>
31
 */
32
class UserGroupsTest extends BaseTest
33
{
34
    //==============================================================================================================
35
    //=================================================  TESTS  ====================================================
36
    //==============================================================================================================
37
38
    /**
39
     * @covers ::export
40
     * @dataProvider provideValidUserGroups
41
     *
42
     * @param UserGroupModel[] $groups
43
     * @param string[]         $groupPermissions
44
     * @param array            $expectedResult
45
     */
46
    public function testSuccessfulExport(array $groups, array $groupPermissions, array $expectedResult = [])
47
    {
48
        $this->setMockUserGroupsService();
49
        $this->setMockUserPermissionsService($groupPermissions);
50
        $this->setMockSectionsService('id');
51
        $this->setMockAssetSourcesService('id');
52
        $this->setMockGlobalsService('id');
53
54
        $schematicUserGroupsService = new UserGroups();
55
56
        $actualResult = $schematicUserGroupsService->export($groups);
57
58
        $this->assertSame($expectedResult, $actualResult);
59
    }
60
61
    /**
62
     * @covers ::import
63
     * @dataProvider provideValidUserGroupDefinitions
64
     *
65
     * @param array $groupDefinitions
66
     */
67 View Code Duplication
    public function testSuccessfulImport(array $groupDefinitions)
68
    {
69
        $this->setMockUserGroupsService();
70
        $this->setMockUserPermissionsService();
71
        $this->setMockSectionsService('handle');
72
        $this->setMockAssetSourcesService('handle');
73
        $this->setMockGlobalsService('handle');
74
75
        $schematicUserGroupsService = new UserGroups();
76
77
        $import = $schematicUserGroupsService->import($groupDefinitions);
78
79
        $this->assertTrue($import instanceof Result);
0 ignored issues
show
The class NerdsAndCompany\Schematic\Models\Result does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
80
        $this->assertFalse($import->hasErrors());
81
    }
82
83
    /**
84
     * @covers ::import
85
     * @dataProvider provideValidUserGroupDefinitions
86
     *
87
     * @param array $groupDefinitions
88
     */
89 View Code Duplication
    public function testImportWhereSavingGroupFails(array $groupDefinitions)
90
    {
91
        $this->setMockUserGroupsService(false);
92
        $this->setMockUserPermissionsService();
93
        $this->setMockSectionsService('handle');
94
        $this->setMockAssetSourcesService('handle');
95
        $this->setMockGlobalsService('handle');
96
97
        $schematicUserGroupsService = new UserGroups();
98
        $import = $schematicUserGroupsService->import($groupDefinitions);
99
100
        $this->assertTrue($import instanceof Result);
0 ignored issues
show
The class NerdsAndCompany\Schematic\Models\Result does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
101
        if (!empty($groupDefinitions)) {
102
            $this->assertTrue($import->hasErrors());
103
        }
104
    }
105
106
    /**
107
     * @covers ::import
108
     * @dataProvider provideValidUserGroupDefinitions
109
     *
110
     * @param array $groupDefinitions
111
     */
112 View Code Duplication
    public function testImportWithForceOption(array $groupDefinitions)
113
    {
114
        $this->setMockUserGroupsService();
115
        $this->setMockUserPermissionsService();
116
        $this->setMockSectionsService('handle');
117
        $this->setMockAssetSourcesService('handle');
118
        $this->setMockGlobalsService('handle');
119
120
        $schematicUserGroupsService = new UserGroups();
121
122
        $import = $schematicUserGroupsService->import($groupDefinitions, true);
123
124
        $this->assertTrue($import instanceof Result);
0 ignored issues
show
The class NerdsAndCompany\Schematic\Models\Result does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
125
        $this->assertFalse($import->hasErrors());
126
    }
127
128
    //==============================================================================================================
129
    //==============================================  PROVIDERS  ===================================================
130
    //==============================================================================================================
131
132
    /**
133
     * @return array
134
     */
135
    public function provideValidUserGroups()
136
    {
137
        return [
138
            'emptyArray' => [
139
                'userGroups' => [],
140
                'groupPermissions' => [],
141
                'expectedResult' => [],
142
            ],
143
            'single group without permissions' => [
144
                'userGroups' => [
145
                    'group1' => $this->getMockUserGroup(1),
146
                ],
147
                'groupPermissions' => [
148
                    [1, []],
149
                ],
150
                'expectedResult' => [
151
                    'groupHandle1' => [
152
                        'name' => 'groupName1',
153
                        'permissions' => [],
154
                    ],
155
                ],
156
            ],
157
            'multiple groups without permissions' => [
158
                'userGroups' => [
159
                    'group1' => $this->getMockUserGroup(1),
160
                    'group2' => $this->getMockUserGroup(2),
161
                ],
162
                'groupPermissions' => [
163
                    [1, []],
164
                    [2, []],
165
                ],
166
                'expectedResult' => [
167
                    'groupHandle1' => [
168
                        'name' => 'groupName1',
169
                        'permissions' => [],
170
                    ],
171
                    'groupHandle2' => [
172
                        'name' => 'groupName2',
173
                        'permissions' => [],
174
                    ],
175
                ],
176
            ],
177
            'single group with permissions' => [
178
                'userGroups' => [
179
                    'group1' => $this->getMockUserGroup(1),
180
                ],
181
                'groupPermissions' => [
182
                    [1, [
183
                        'accesssitewhensystemisoff',
184
                        'performupdates',
185
                        'editentries:1',
186
                        'editglobalset:1',
187
                        'viewassetsource:1',
188
189
                    ]],
190
                ],
191
                'expectedResult' => [
192
                    'groupHandle1' => [
193
                        'name' => 'groupName1',
194
                        'permissions' => [
195
                            'accessSiteWhenSystemIsOff',
196
                            'editEntries:sectionHandle1',
197
                            'editGlobalSet:globalSetHandle1',
198
                            'performUpdates',
199
                            'viewAssetSource:assetSourceHandle1',
200
                        ],
201
                    ],
202
                ],
203
            ],
204
        ];
205
    }
206
207
    /**
208
     * @return array
209
     */
210
    public function provideValidUserGroupDefinitions()
211
    {
212
        return [
213
            'emptyArray' => [
214
                'groupDefinitions' => [],
215
            ],
216
            'single group without permissions' => [
217
                'groupDefinitions' => [
218
                    'groupHandle1' => [
219
                        'name' => 'groupName1',
220
                        'permissions' => [],
221
                    ],
222
                ],
223
            ],
224
            'single group with permissions' => [
225
                'groupDefinitions' => [
226
                    'groupHandle1' => [
227
                        'name' => 'groupName1',
228
                        'permissions' => [
229
                            'accessSiteWhenSystemIsOff',
230
                            'performUpdates',
231
                            'editEntries:sectionHandle1',
232
                            'editGlobalSet:globalSetHandle1',
233
                            'viewAssetSource:assetSourceHandle1',
234
                        ],
235
                    ],
236
                ],
237
            ],
238
        ];
239
    }
240
241
    //==============================================================================================================
242
    //=================================================  MOCKS  ====================================================
243
    //==============================================================================================================
244
245
    /**
246
     * @param string $groupId
247
     *
248
     * @return Mock|UserGroupModel
249
     */
250
    private function getMockUserGroup($groupId)
251
    {
252
        $mockUserGroup = $this->getMockBuilder(UserGroupModel::class)
253
            ->disableOriginalConstructor()
254
            ->getMock();
255
256
        $mockUserGroup->expects($this->any())
257
            ->method('__get')
258
            ->willReturnMap([
259
                ['id', $groupId],
260
                ['handle', 'groupHandle'.$groupId],
261
                ['name', 'groupName'.$groupId],
262
            ]);
263
264
        $mockUserGroup->expects($this->any())
265
            ->method('getAllErrors')
266
            ->willReturn([
267
                'ohnoes' => 'horrible error',
268
            ]);
269
270
        return $mockUserGroup;
271
    }
272
273
    /**
274
     * @param $indexBy
275
     *
276
     * @return Mock|SectionsService
277
     */
278 View Code Duplication
    private function setMockSectionsService($indexBy)
279
    {
280
        $mockSectionService = $this->getMockBuilder(SectionsService::class)
281
            ->disableOriginalConstructor()
282
            ->getMock();
283
284
        $mockSectionService->expects($this->any())
285
            ->method('getAllSections')
286
            ->with($indexBy)
287
            ->willReturn($this->getMockSections($indexBy, 2));
288
289
        $this->setComponent(Craft::app(), 'sections', $mockSectionService);
290
291
        return $mockSectionService;
292
    }
293
294
    /**
295
     * @param string $indexBy
296
     * @param int    $count
297
     *
298
     * @return Mock[]|SectionModel[]
299
     */
300 View Code Duplication
    private function getMockSections($indexBy, $count)
301
    {
302
        $keyPrefix = $indexBy == 'id' ? '' : 'sectionHandle';
303
        $mockSections = [];
304
        for ($x = 0; $x <= $count; $x++) {
305
            $mockSection = $this->getMockBuilder(SectionModel::class)
306
                ->disableOriginalConstructor()
307
                ->getMock();
308
309
            $mockSection->expects($this->any())
310
                ->method('__get')
311
                ->willReturnMap([
312
                    ['handle', 'sectionHandle'.$x],
313
                    ['id', $x],
314
                    ['name', 'sectionName'.$x],
315
                ]);
316
317
            $mockSections[$keyPrefix.$x] = $mockSection;
318
        }
319
320
        return $mockSections;
321
    }
322
323
    /**
324
     * @param string $indexBy
325
     *
326
     * @return Mock|AssetSourcesService
327
     */
328 View Code Duplication
    private function setMockAssetSourcesService($indexBy)
329
    {
330
        $mockAssetSourcesService = $this->getMockBuilder(AssetSourcesService::class)
331
            ->disableOriginalConstructor()
332
            ->getMock();
333
334
        $mockAssetSourcesService->expects($this->exactly(1))
335
            ->method('getAllSources')
336
            ->with($indexBy)
337
            ->willReturn($this->getMockAssetSources($indexBy, 1));
338
339
        $this->setComponent(Craft::app(), 'assetSources', $mockAssetSourcesService);
340
341
        return $mockAssetSourcesService;
342
    }
343
344
    /**
345
     * @param string $indexBy
346
     * @param int    $count
347
     *
348
     * @return Mock[]|AssetSourceModel[]
349
     */
350 View Code Duplication
    private function getMockAssetSources($indexBy, $count)
351
    {
352
        $keyPrefix = $indexBy == 'id' ? '' : 'assetSourceHandle';
353
        $mockAssetSources = [];
354
        for ($x = 0; $x <= $count; $x++) {
355
            $mockAssetSource = $this->getMockBuilder(AssetSourceModel::class)
356
                ->disableOriginalConstructor()
357
                ->getMock();
358
359
            $mockAssetSource->expects($this->any())
360
                ->method('__get')
361
                ->willReturnMap([
362
                    ['handle', 'assetSourceHandle'.$x],
363
                    ['id', $x],
364
                    ['name', 'assetSourceName'.$x],
365
                ]);
366
367
            $mockAssetSources[$keyPrefix.$x] = $mockAssetSource;
368
        }
369
370
        return $mockAssetSources;
371
    }
372
373
    /**
374
     * @param string $indexBy
375
     *
376
     * @return Mock|AssetSourcesService
377
     */
378 View Code Duplication
    private function setMockGlobalsService($indexBy)
379
    {
380
        $mockAssetSourcesService = $this->getMockBuilder(GlobalsService::class)
381
            ->disableOriginalConstructor()
382
            ->getMock();
383
384
        $mockAssetSourcesService->expects($this->exactly(1))
385
            ->method('getAllSets')
386
            ->with($indexBy)
387
            ->willReturn($this->getMockGlobalSets($indexBy, 1));
388
389
        $this->setComponent(Craft::app(), 'globals', $mockAssetSourcesService);
390
391
        return $mockAssetSourcesService;
392
    }
393
394
    /**
395
     * @param string $indexBy
396
     * @param int    $count
397
     *
398
     * @return Mock[]|GlobalSetModel[]
399
     */
400 View Code Duplication
    private function getMockGlobalSets($indexBy, $count)
401
    {
402
        $keyPrefix = $indexBy == 'id' ? '' : 'globalSetHandle';
403
        $mockGlobalSets = [];
404
        for ($x = 0; $x <= $count; $x++) {
405
            $mockGlobalSet = $this->getMockBuilder(GlobalSetModel::class)
406
                ->disableOriginalConstructor()
407
                ->getMock();
408
409
            $mockGlobalSet->expects($this->any())
410
                ->method('__get')
411
                ->willReturnMap([
412
                    ['handle', 'globalSetHandle'.$x],
413
                    ['id', $x],
414
                    ['name', 'globalSetName'.$x],
415
                ]);
416
417
            $mockGlobalSets[$keyPrefix.$x] = $mockGlobalSet;
418
        }
419
420
        return $mockGlobalSets;
421
    }
422
423
    /**
424
     * @param bool $success
425
     *
426
     * @return UserGroupsService|Mock
427
     */
428 View Code Duplication
    private function setMockUserGroupsService($success = true)
429
    {
430
        $mockUserGroupsService = $this->getMockBuilder(UserGroupsService::class)
431
            ->disableOriginalConstructor()
432
            ->getMock();
433
434
        $mockUserGroupsService->expects($this->any())
435
            ->method('getAllGroups')
436
            ->with('handle')
437
            ->willReturn($this->getMockuserGroups(2));
438
439
        $mockUserGroupsService->expects($this->any())
440
            ->method('saveGroup')
441
            ->with($this->isInstanceOf(UserGroupModel::class))
442
            ->willReturn($success);
443
444
        $this->setComponent(Craft::app(), 'userGroups', $mockUserGroupsService);
445
446
        return $mockUserGroupsService;
447
    }
448
449
    /**
450
     * @param int $count
451
     *
452
     * @return array
453
     */
454
    private function getMockUserGroups($count)
455
    {
456
        $mockUserGroups = [];
457
        for ($x = 0; $x <= $count; $x++) {
458
            $mockUserGroups['groupHandle'.$x] = $this->getMockUserGroup($x);
459
        }
460
461
        return $mockUserGroups;
462
    }
463
464
    /**
465
     * @param array $permissions
466
     * @param bool  $success
467
     *
468
     * @return UserPermissionsService|Mock
469
     */
470 View Code Duplication
    private function setMockUserPermissionsService(array $permissions = [], $success = true)
471
    {
472
        $mockUserPermissionsService = $this->getMockBuilder(UserPermissionsService::class)
473
            ->disableOriginalConstructor()
474
            ->getMock();
475
476
        $mockUserPermissionsService->expects($this->any())
477
            ->method('getAllPermissions')
478
            ->willReturn($this->getAllPermissionsExample());
479
480
        $mockUserPermissionsService->expects($this->any())
481
            ->method('getPermissionsByGroupId')
482
            ->willReturnMap($permissions);
483
484
        $mockUserPermissionsService->expects($this->any())
485
            ->method('saveGroupPermissions')
486
            ->willReturn($success);
487
488
        $this->setComponent(Craft::app(), 'userPermissions', $mockUserPermissionsService);
489
490
        return $mockUserPermissionsService;
491
    }
492
493
    /**
494
     * @return array of example permissions
495
     */
496
    private function getAllPermissionsExample()
497
    {
498
        return [
499
            'General' => [
500
                'accessSiteWhenSystemIsOff' => [
501
                    'nested' => [
502
                        'accessCpWhenSystemIsOff' => [],
503
                        'performUpdates' => [],
504
                        'accessPlugin-PluginName1' => [],
505
                        'accessPlugin-PluginName2' => [],
506
                    ],
507
                ],
508
            ],
509
            'Users' => [
510
                'editUsers' => [
511
                    'nested' => [
512
                        'registerUsers' => [],
513
                        'assignUserPermissions' => [],
514
                        'administrateUsers' => [
515
                            'nested' => [
516
                                'changeUserEmails' => [],
517
                            ],
518
                        ],
519
                        'deleteUsers' => [],
520
                    ],
521
                ],
522
            ],
523
            'Section - 1' => [
524
                'editEntries:1' => [
525
                    'nested' => [
526
                        'publishEntries:1' => [],
527
                        'editPeerEntryDrafts:1' => [
528
                            'nested' => [
529
                                'publishPeerEntryDrafts:1' => [],
530
                                'deletePeerEntryDrafts:1' => [],
531
                            ],
532
                        ],
533
                    ],
534
                ],
535
            ],
536
            'Section - 2' => [
537
                'editEntries:2' => [
538
                    'nested' => [
539
                        'publishEntries:2' => [],
540
                        'editPeerEntryDrafts:2' => [
541
                            'nested' => [
542
                                'publishPeerEntryDrafts:2' => [],
543
                                'deletePeerEntryDrafts:2' => [],
544
                            ],
545
                        ],
546
                    ],
547
                ],
548
            ],
549
            'GlobalSet - 1' => [
550
                'editGlobalSet:1' => [],
551
            ],
552
            'AssetSources - 1' => [
553
                'viewAssetSource:1' => [
554
                    'nested' => [
555
                        'uploadToAssetSource:1' => [],
556
                        'createSubfoldersInAssetSource:1' => [],
557
                        'removeFromAssetSource:1' => [],
558
                    ],
559
                ],
560
            ],
561
        ];
562
    }
563
}
564