Completed
Push — master ( 08b605...3e0b85 )
by Łukasz
22:32
created

LocationServiceTest   F

Complexity

Total Complexity 105

Size/Duplication

Total Lines 2557
Duplicated Lines 19.48 %

Coupling/Cohesion

Components 1
Dependencies 20

Importance

Changes 0
Metric Value
wmc 105
lcom 1
cbo 20
dl 498
loc 2557
rs 0.8
c 0
b 0
f 0

72 Methods

Rating   Name   Duplication   Size   Complexity  
A testNewLocationCreateStruct() 21 21 1
A testNewLocationCreateStructValues() 0 15 1
A testCreateLocation() 0 40 1
A testCreateLocationStructValues() 0 24 1
A testCreateLocationThrowsInvalidArgumentExceptionContentAlreadyBelowParent() 25 25 1
A testCreateLocationThrowsInvalidArgumentExceptionParentIsSubLocationOfContent() 25 25 1
A testCreateLocationThrowsInvalidArgumentExceptionRemoteIdExists() 25 25 1
A testCreateLocationThrowsInvalidArgumentExceptionPriorityIsOutOfRange() 29 29 1
A dataProviderForOutOfRangeLocationPriority() 0 4 1
A testCreateLocationInTransactionWithRollback() 0 43 3
A testLoadLocation() 0 20 1
A testLoadLocationRootStructValues() 0 48 1
A testLoadLocationStructValues() 0 31 1
A testLoadLocationPrioritizedLanguagesFallback() 0 35 1
A testLoadLocationThrowsNotFoundExceptionForNotAvailableContent() 0 13 1
A testLoadLocationThrowsNotFoundException() 0 13 1
A testLoadLocationList() 0 14 1
A testLoadLocationListPrioritizedLanguagesFallback() 0 13 1
A testLoadLocationListPrioritizedLanguagesFallbackAndAlwaysAvailable() 0 16 1
A testLoadLocationByRemoteId() 17 17 1
A testLoadLocationByRemoteIdThrowsNotFoundException() 0 13 1
A testLoadLocations() 0 25 2
A testLoadLocationsContent() 0 30 2
A testLoadLocationsLimitedSubtree() 0 38 1
A testLoadLocationsLimitedSubtreeContent() 0 9 1
A testLoadLocationsThrowsBadStateException() 21 21 1
A testLoadLocationsThrowsBadStateExceptionLimitedSubtree() 0 26 1
A testLoadLocationChildren() 0 26 2
A testLoadParentLocationsForDraftContent() 0 30 3
A testLoadParentLocationsForDraftContentThrowsBadStateException() 0 13 1
A testGetLocationChildCount() 0 12 1
A testLoadLocationChildrenData() 0 28 2
A testLoadLocationChildrenWithOffset() 20 20 1
A testLoadLocationChildrenDataWithOffset() 26 26 2
A testLoadLocationChildrenWithOffsetAndLimit() 20 20 1
A testLoadLocationChildrenDataWithOffsetAndLimit() 25 25 2
A testNewLocationUpdateStruct() 25 25 1
A testUpdateLocation() 0 31 1
A testUpdateLocationStructValues() 0 23 1
A testUpdateLocationWithSameRemoteId() 0 28 1
A testUpdateLocationThrowsInvalidArgumentException() 20 20 1
A testUpdateLocationThrowsInvalidArgumentExceptionPriorityIsOutOfRange() 0 20 1
A testUpdateLocationTwice() 0 23 1
A testSwapLocation() 0 52 1
A testSwapLocationUpdatesMainLocation() 0 31 1
A testBookmarksAreSwappedAfterSwapLocation() 0 29 1
A testHideLocation() 0 36 2
A assertSubtreeProperties() 0 20 4
A testUnhideLocation() 0 37 2
B testUnhideLocationNotUnhidesHiddenSubtree() 0 58 3
B testDeleteLocation() 0 42 6
A testDeleteLocationDecrementsChildCountOnParent() 0 38 1
A testDeleteContentObjectLastLocation() 0 36 1
A testDeleteLocationDeletesRelatedBookmarks() 0 26 2
A testCopySubtree() 0 45 1
A testCopySubtreeWithAliases() 0 33 1
A assertDefaultContentStates() 19 19 3
B testCopySubtreeUpdatesSubtreeProperties() 0 59 3
A testCopySubtreeIncrementsChildCountOfNewParent() 0 38 1
A testCopySubtreeThrowsInvalidArgumentException() 27 27 1
A testMoveSubtree() 0 43 1
A testMoveSubtreeHidden() 0 46 1
A testMoveSubtreeUpdatesSubtreeProperties() 0 54 2
B testMoveSubtreeUpdatesSubtreePropertiesHidden() 0 58 2
A testMoveSubtreeIncrementsChildCountOfNewParent() 51 51 1
A testMoveSubtreeDecrementsChildCountOfOldParent() 51 51 1
A testMoveSubtreeThrowsInvalidArgumentException() 29 29 1
A loadSubtreeProperties() 0 12 2
A loadLocationProperties() 0 18 1
A assertGeneratedAliases() 0 7 2
A assertAliasesBeforeCopy() 0 11 3
A publishContentWithParentLocation() 22 22 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like LocationServiceTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LocationServiceTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * File containing the LocationServiceTest class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\API\Repository\Tests;
10
11
use eZ\Publish\API\Repository\Exceptions\BadStateException;
12
use eZ\Publish\API\Repository\Values\Content\Content;
13
use eZ\Publish\API\Repository\Values\Content\Location;
14
use eZ\Publish\API\Repository\Values\Content\LocationCreateStruct;
15
use eZ\Publish\API\Repository\Values\Content\LocationList;
16
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
17
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
18
use Exception;
19
use eZ\Publish\API\Repository\Values\Content\LocationUpdateStruct;
20
21
/**
22
 * Test case for operations in the LocationService using in memory storage.
23
 *
24
 * @see eZ\Publish\API\Repository\LocationService
25
 * @group location
26
 */
27
class LocationServiceTest extends BaseTest
28
{
29
    /**
30
     * Test for the newLocationCreateStruct() method.
31
     *
32
     * @return \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct
33
     *
34
     * @see \eZ\Publish\API\Repository\LocationService::newLocationCreateStruct()
35
     */
36 View Code Duplication
    public function testNewLocationCreateStruct()
37
    {
38
        $repository = $this->getRepository();
39
40
        $parentLocationId = $this->generateId('location', 1);
41
        /* BEGIN: Use Case */
42
        // $parentLocationId is the ID of an existing location
43
        $locationService = $repository->getLocationService();
44
45
        $locationCreate = $locationService->newLocationCreateStruct(
46
            $parentLocationId
47
        );
48
        /* END: Use Case */
49
50
        $this->assertInstanceOf(
51
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationCreateStruct',
52
            $locationCreate
53
        );
54
55
        return $locationCreate;
56
    }
57
58
    /**
59
     * Test for the newLocationCreateStruct() method.
60
     *
61
     * @param \eZ\Publish\API\Repository\Values\Content\LocationCreateStruct $locationCreate
62
     *
63
     * @see \eZ\Publish\API\Repository\LocationService::newLocationCreateStruct()
64
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
65
     */
66
    public function testNewLocationCreateStructValues(LocationCreateStruct $locationCreate)
67
    {
68
        $this->assertPropertiesCorrect(
69
            array(
70
                'priority' => 0,
71
                'hidden' => false,
72
                // remoteId should be initialized with a default value
73
                //'remoteId' => null,
74
                'sortField' => Location::SORT_FIELD_NAME,
75
                'sortOrder' => Location::SORT_ORDER_ASC,
76
                'parentLocationId' => $this->generateId('location', 1),
77
            ),
78
            $locationCreate
79
        );
80
    }
81
82
    /**
83
     * Test for the createLocation() method.
84
     *
85
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
86
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
87
     */
88
    public function testCreateLocation()
89
    {
90
        $repository = $this->getRepository();
91
92
        $contentId = $this->generateId('object', 41);
93
        $parentLocationId = $this->generateId('location', 5);
94
        /* BEGIN: Use Case */
95
        // $contentId is the ID of an existing content object
96
        // $parentLocationId is the ID of an existing location
97
        $contentService = $repository->getContentService();
98
        $locationService = $repository->getLocationService();
99
100
        // ContentInfo for "How to use eZ Publish"
101
        $contentInfo = $contentService->loadContentInfo($contentId);
102
103
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
104
        $locationCreate->priority = 23;
105
        $locationCreate->hidden = true;
106
        $locationCreate->remoteId = 'sindelfingen';
107
        $locationCreate->sortField = Location::SORT_FIELD_NODE_ID;
108
        $locationCreate->sortOrder = Location::SORT_ORDER_DESC;
109
110
        $location = $locationService->createLocation(
111
            $contentInfo,
112
            $locationCreate
113
        );
114
        /* END: Use Case */
115
116
        $this->assertInstanceOf(
117
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
118
            $location
119
        );
120
121
        return array(
122
            'locationCreate' => $locationCreate,
123
            'createdLocation' => $location,
124
            'contentInfo' => $contentInfo,
125
            'parentLocation' => $locationService->loadLocation($this->generateId('location', 5)),
126
        );
127
    }
128
129
    /**
130
     * Test for the createLocation() method.
131
     *
132
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
133
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
134
     */
135
    public function testCreateLocationStructValues(array $data)
136
    {
137
        $locationCreate = $data['locationCreate'];
138
        $createdLocation = $data['createdLocation'];
139
        $contentInfo = $data['contentInfo'];
140
141
        $this->assertPropertiesCorrect(
142
            array(
143
                'priority' => $locationCreate->priority,
144
                'hidden' => $locationCreate->hidden,
145
                'invisible' => $locationCreate->hidden,
146
                'remoteId' => $locationCreate->remoteId,
147
                'contentInfo' => $contentInfo,
148
                'parentLocationId' => $locationCreate->parentLocationId,
149
                'pathString' => '/1/5/' . $this->parseId('location', $createdLocation->id) . '/',
150
                'depth' => 2,
151
                'sortField' => $locationCreate->sortField,
152
                'sortOrder' => $locationCreate->sortOrder,
153
            ),
154
            $createdLocation
155
        );
156
157
        $this->assertNotNull($createdLocation->id);
158
    }
159
160
    /**
161
     * Test for the createLocation() method.
162
     *
163
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
164
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
165
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
166
     */
167 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionContentAlreadyBelowParent()
168
    {
169
        $repository = $this->getRepository();
170
171
        $contentId = $this->generateId('object', 11);
172
        $parentLocationId = $this->generateId('location', 5);
173
        /* BEGIN: Use Case */
174
        // $contentId is the ID of an existing content object
175
        // $parentLocationId is the ID of an existing location which already
176
        // has the content assigned to one of its descendant locations
177
        $contentService = $repository->getContentService();
178
        $locationService = $repository->getLocationService();
179
180
        // ContentInfo for "How to use eZ Publish"
181
        $contentInfo = $contentService->loadContentInfo($contentId);
182
183
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
184
185
        // Throws exception, since content is already located at "/1/2/107/110/"
186
        $locationService->createLocation(
187
            $contentInfo,
188
            $locationCreate
189
        );
190
        /* END: Use Case */
191
    }
192
193
    /**
194
     * Test for the createLocation() method.
195
     *
196
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
197
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
198
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
199
     */
200 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionParentIsSubLocationOfContent()
201
    {
202
        $repository = $this->getRepository();
203
204
        $contentId = $this->generateId('object', 4);
205
        $parentLocationId = $this->generateId('location', 12);
206
        /* BEGIN: Use Case */
207
        // $contentId is the ID of an existing content object
208
        // $parentLocationId is the ID of an existing location which is below a
209
        // location that is assigned to the content
210
        $contentService = $repository->getContentService();
211
        $locationService = $repository->getLocationService();
212
213
        // ContentInfo for "How to use eZ Publish"
214
        $contentInfo = $contentService->loadContentInfo($contentId);
215
216
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
217
218
        // Throws exception, since content is already located at "/1/2/"
219
        $locationService->createLocation(
220
            $contentInfo,
221
            $locationCreate
222
        );
223
        /* END: Use Case */
224
    }
225
226
    /**
227
     * Test for the createLocation() method.
228
     *
229
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
230
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
231
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
232
     */
233 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionRemoteIdExists()
234
    {
235
        $repository = $this->getRepository();
236
237
        $contentId = $this->generateId('object', 41);
238
        $parentLocationId = $this->generateId('location', 5);
239
        /* BEGIN: Use Case */
240
        // $contentId is the ID of an existing content object
241
        $contentService = $repository->getContentService();
242
        $locationService = $repository->getLocationService();
243
244
        // ContentInfo for "How to use eZ Publish"
245
        $contentInfo = $contentService->loadContentInfo($contentId);
246
247
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
248
        // This remote ID already exists
249
        $locationCreate->remoteId = 'f3e90596361e31d496d4026eb624c983';
250
251
        // Throws exception, since remote ID is already in use
252
        $locationService->createLocation(
253
            $contentInfo,
254
            $locationCreate
255
        );
256
        /* END: Use Case */
257
    }
258
259
    /**
260
     * Test for the createLocation() method.
261
     *
262
     * @covers \eZ\Publish\API\Repository\LocationService::createLocation()
263
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testNewLocationCreateStruct
264
     * @dataProvider dataProviderForOutOfRangeLocationPriority
265
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
266
     */
267 View Code Duplication
    public function testCreateLocationThrowsInvalidArgumentExceptionPriorityIsOutOfRange($priority)
268
    {
269
        $repository = $this->getRepository();
270
271
        $contentId = $this->generateId('object', 41);
272
        $parentLocationId = $this->generateId('location', 5);
273
        /* BEGIN: Use Case */
274
        // $contentId is the ID of an existing content object
275
        // $parentLocationId is the ID of an existing location
276
        $contentService = $repository->getContentService();
277
        $locationService = $repository->getLocationService();
278
279
        // ContentInfo for "How to use eZ Publish"
280
        $contentInfo = $contentService->loadContentInfo($contentId);
281
282
        $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
283
        $locationCreate->priority = $priority;
284
        $locationCreate->hidden = true;
285
        $locationCreate->remoteId = 'sindelfingen';
286
        $locationCreate->sortField = Location::SORT_FIELD_NODE_ID;
287
        $locationCreate->sortOrder = Location::SORT_ORDER_DESC;
288
289
        // Throws exception, since priority is out of range
290
        $locationService->createLocation(
291
            $contentInfo,
292
            $locationCreate
293
        );
294
        /* END: Use Case */
295
    }
296
297
    public function dataProviderForOutOfRangeLocationPriority()
298
    {
299
        return [[-2147483649], [2147483648]];
300
    }
301
302
    /**
303
     * Test for the createLocation() method.
304
     *
305
     * @see \eZ\Publish\API\Repository\LocationService::createLocation()
306
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
307
     */
308
    public function testCreateLocationInTransactionWithRollback()
309
    {
310
        $repository = $this->getRepository();
311
312
        $contentId = $this->generateId('object', 41);
313
        $parentLocationId = $this->generateId('location', 5);
314
        /* BEGIN: Use Case */
315
        // $contentId is the ID of an existing content object
316
        // $parentLocationId is the ID of an existing location
317
        $contentService = $repository->getContentService();
318
        $locationService = $repository->getLocationService();
319
320
        $repository->beginTransaction();
321
322
        try {
323
            // ContentInfo for "How to use eZ Publish"
324
            $contentInfo = $contentService->loadContentInfo($contentId);
325
326
            $locationCreate = $locationService->newLocationCreateStruct($parentLocationId);
327
            $locationCreate->remoteId = 'sindelfingen';
328
329
            $createdLocationId = $locationService->createLocation(
330
                $contentInfo,
331
                $locationCreate
332
            )->id;
333
        } catch (Exception $e) {
334
            // Cleanup hanging transaction on error
335
            $repository->rollback();
336
            throw $e;
337
        }
338
339
        $repository->rollback();
340
341
        try {
342
            // Throws exception since creation of location was rolled back
343
            $location = $locationService->loadLocation($createdLocationId);
0 ignored issues
show
Unused Code introduced by
$location is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
344
        } catch (NotFoundException $e) {
345
            return;
346
        }
347
        /* END: Use Case */
348
349
        $this->fail('Objects still exists after rollback.');
350
    }
351
352
    /**
353
     * Test for the loadLocation() method.
354
     *
355
     * @return \eZ\Publish\API\Repository\Values\Content\Location
356
     *
357
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocation
358
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
359
     */
360
    public function testLoadLocation()
361
    {
362
        $repository = $this->getRepository();
363
364
        $locationId = $this->generateId('location', 5);
365
        /* BEGIN: Use Case */
366
        // $locationId is the ID of an existing location
367
        $locationService = $repository->getLocationService();
368
369
        $location = $locationService->loadLocation($locationId);
370
        /* END: Use Case */
371
372
        $this->assertInstanceOf(
373
            Location::class,
374
            $location
375
        );
376
        self::assertEquals(5, $location->id);
377
378
        return $location;
379
    }
380
381
    /**
382
     * Test for the loadLocation() method.
383
     *
384
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
385
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
386
     */
387
    public function testLoadLocationRootStructValues()
388
    {
389
        $repository = $this->getRepository();
390
        $locationService = $repository->getLocationService();
391
        $location = $locationService->loadLocation($this->generateId('location', 1));
392
393
        $legacyDateTime = new \DateTime();
394
        $legacyDateTime->setTimestamp(1030968000);
395
396
        // $location
397
        $this->assertPropertiesCorrect(
398
            array(
399
                'id' => $this->generateId('location', 1),
400
                'status' => 1,
401
                'priority' => 0,
402
                'hidden' => false,
403
                'invisible' => false,
404
                'remoteId' => '629709ba256fe317c3ddcee35453a96a',
405
                'parentLocationId' => $this->generateId('location', 1),
406
                'pathString' => '/1/',
407
                'depth' => 0,
408
                'sortField' => 1,
409
                'sortOrder' => 1,
410
            ),
411
            $location
412
        );
413
414
        // $location->contentInfo
415
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo', $location->contentInfo);
416
        $this->assertPropertiesCorrect(
417
            array(
418
                'id' => $this->generateId('content', 0),
419
                'name' => 'Top Level Nodes',
420
                'sectionId' => 1,
421
                'mainLocationId' => 1,
422
                'contentTypeId' => 1,
423
                'currentVersionNo' => 1,
424
                'published' => 1,
425
                'ownerId' => 14,
426
                'modificationDate' => $legacyDateTime,
427
                'publishedDate' => $legacyDateTime,
428
                'alwaysAvailable' => 1,
429
                'remoteId' => null,
430
                'mainLanguageCode' => 'eng-GB',
431
            ),
432
            $location->contentInfo
433
        );
434
    }
435
436
    /**
437
     * Test for the loadLocation() method.
438
     *
439
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
440
     *
441
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
442
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
443
     */
444
    public function testLoadLocationStructValues(Location $location)
445
    {
446
        $this->assertPropertiesCorrect(
447
            array(
448
                'id' => $this->generateId('location', 5),
449
                'priority' => 0,
450
                'hidden' => false,
451
                'invisible' => false,
452
                'remoteId' => '3f6d92f8044aed134f32153517850f5a',
453
                'parentLocationId' => $this->generateId('location', 1),
454
                'pathString' => '/1/5/',
455
                'depth' => 1,
456
                'sortField' => 1,
457
                'sortOrder' => 1,
458
            ),
459
            $location
460
        );
461
462
        $this->assertInstanceOf(
463
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\ContentInfo',
464
            $location->contentInfo
465
        );
466
        $this->assertEquals($this->generateId('object', 4), $location->contentInfo->id);
467
468
        // Check lazy loaded proxy on ->content
469
        $this->assertInstanceOf(
470
            Content::class,
471
            $content = $location->getContent()
472
        );
473
        $this->assertEquals(4, $content->contentInfo->id);
474
    }
475
476
    public function testLoadLocationPrioritizedLanguagesFallback()
477
    {
478
        $repository = $this->getRepository();
479
480
        // Add a language
481
        $this->createLanguage('nor-NO', 'Norsk');
482
483
        $locationService = $repository->getLocationService();
484
        $contentService = $repository->getContentService();
485
        $location = $locationService->loadLocation(5);
486
487
        // Translate "Users"
488
        $draft = $contentService->createContentDraft($location->contentInfo);
489
        $struct = $contentService->newContentUpdateStruct();
490
        $struct->setField('name', 'Brukere', 'nor-NO');
491
        $draft = $contentService->updateContent($draft->getVersionInfo(), $struct);
492
        $contentService->publishVersion($draft->getVersionInfo());
493
494
        // Load with priority language (fallback will be the old one)
495
        $location = $locationService->loadLocation(5, ['nor-NO']);
496
497
        $this->assertInstanceOf(
498
            Location::class,
499
            $location
500
        );
501
        self::assertEquals(5, $location->id);
502
        $this->assertInstanceOf(
503
            Content::class,
504
            $content = $location->getContent()
505
        );
506
        $this->assertEquals(4, $content->contentInfo->id);
507
508
        $this->assertEquals($content->getVersionInfo()->getName(), 'Brukere');
509
        $this->assertEquals($content->getVersionInfo()->getName('eng-US'), 'Users');
510
    }
511
512
    /**
513
     * Test that accessing lazy-loaded Content without a translation in the specific
514
     * not available language throws NotFoundException.
515
     */
516
    public function testLoadLocationThrowsNotFoundExceptionForNotAvailableContent(): void
517
    {
518
        $repository = $this->getRepository();
519
520
        $locationService = $repository->getLocationService();
521
522
        $this->createLanguage('pol-PL', 'Polski');
523
524
        $this->expectException(NotFoundException::class);
525
526
        // Note: relying on existing database fixtures to make test case more readable
527
        $locationService->loadLocation(60, ['pol-PL']);
528
    }
529
530
    /**
531
     * Test for the loadLocation() method.
532
     *
533
     * @see \eZ\Publish\API\Repository\LocationService::loadLocation()
534
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
535
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
536
     */
537
    public function testLoadLocationThrowsNotFoundException()
538
    {
539
        $repository = $this->getRepository();
540
541
        $nonExistentLocationId = $this->generateId('location', 2342);
542
        /* BEGIN: Use Case */
543
        $locationService = $repository->getLocationService();
544
545
        // Throws exception, if Location with $nonExistentLocationId does not
546
        // exist
547
        $location = $locationService->loadLocation($nonExistentLocationId);
0 ignored issues
show
Unused Code introduced by
$location is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
548
        /* END: Use Case */
549
    }
550
551
    /**
552
     * Test for the loadLocationList() method.
553
     *
554
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocationList
555
     */
556
    public function testLoadLocationList(): void
557
    {
558
        $repository = $this->getRepository();
559
560
        // 5 is the ID of an existing location, 442 is a non-existing id
561
        $locationService = $repository->getLocationService();
562
        $locations = $locationService->loadLocationList([5, 442]);
563
564
        self::assertInternalType('iterable', $locations);
565
        self::assertCount(1, $locations);
0 ignored issues
show
Bug introduced by
It seems like $locations defined by $locationService->loadLocationList(array(5, 442)) on line 562 can also be of type array<integer,object<eZ\...lues\Content\Location>>; however, PHPUnit\Framework\Assert::assertCount() does only seem to accept object<Countable>|object...nit\Framework\iterable>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
566
        self::assertEquals([5], array_keys($locations));
567
        self::assertInstanceOf(Location::class, $locations[5]);
568
        self::assertEquals(5, $locations[5]->id);
569
    }
570
571
    /**
572
     * Test for the loadLocationList() method.
573
     *
574
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocationList
575
     * @depends testLoadLocationList
576
     */
577
    public function testLoadLocationListPrioritizedLanguagesFallback(): void
578
    {
579
        $repository = $this->getRepository();
580
581
        $this->createLanguage('pol-PL', 'Polski');
582
583
        // 5 is the ID of an existing location, 442 is a non-existing id
584
        $locationService = $repository->getLocationService();
585
        $locations = $locationService->loadLocationList([5, 442], ['pol-PL'], false);
586
587
        self::assertInternalType('iterable', $locations);
588
        self::assertCount(0, $locations);
0 ignored issues
show
Bug introduced by
It seems like $locations defined by $locationService->loadLo...array('pol-PL'), false) on line 585 can also be of type array<integer,object<eZ\...lues\Content\Location>>; however, PHPUnit\Framework\Assert::assertCount() does only seem to accept object<Countable>|object...nit\Framework\iterable>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
589
    }
590
591
    /**
592
     * Test for the loadLocationList() method.
593
     *
594
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocationList
595
     * @depends testLoadLocationListPrioritizedLanguagesFallback
596
     */
597
    public function testLoadLocationListPrioritizedLanguagesFallbackAndAlwaysAvailable(): void
598
    {
599
        $repository = $this->getRepository();
600
601
        $this->createLanguage('pol-PL', 'Polski');
602
603
        // 5 is the ID of an existing location, 442 is a non-existing id
604
        $locationService = $repository->getLocationService();
605
        $locations = $locationService->loadLocationList([5, 442], ['pol-PL'], true);
606
607
        self::assertInternalType('iterable', $locations);
608
        self::assertCount(1, $locations);
0 ignored issues
show
Bug introduced by
It seems like $locations defined by $locationService->loadLo... array('pol-PL'), true) on line 605 can also be of type array<integer,object<eZ\...lues\Content\Location>>; however, PHPUnit\Framework\Assert::assertCount() does only seem to accept object<Countable>|object...nit\Framework\iterable>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
609
        self::assertEquals([5], array_keys($locations));
610
        self::assertInstanceOf(Location::class, $locations[5]);
611
        self::assertEquals(5, $locations[5]->id);
612
    }
613
614
    /**
615
     * Test for the loadLocationByRemoteId() method.
616
     *
617
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
618
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
619
     */
620 View Code Duplication
    public function testLoadLocationByRemoteId()
621
    {
622
        $repository = $this->getRepository();
623
624
        /* BEGIN: Use Case */
625
        $locationService = $repository->getLocationService();
626
627
        $location = $locationService->loadLocationByRemoteId(
628
            '3f6d92f8044aed134f32153517850f5a'
629
        );
630
        /* END: Use Case */
631
632
        $this->assertEquals(
633
            $locationService->loadLocation($this->generateId('location', 5)),
634
            $location
635
        );
636
    }
637
638
    /**
639
     * Test for the loadLocationByRemoteId() method.
640
     *
641
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationByRemoteId()
642
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
643
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
644
     */
645
    public function testLoadLocationByRemoteIdThrowsNotFoundException()
646
    {
647
        $repository = $this->getRepository();
648
649
        /* BEGIN: Use Case */
650
        $locationService = $repository->getLocationService();
651
652
        // Throws exception, since Location with remote ID does not exist
653
        $location = $locationService->loadLocationByRemoteId(
0 ignored issues
show
Unused Code introduced by
$location is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
654
            'not-exists'
655
        );
656
        /* END: Use Case */
657
    }
658
659
    /**
660
     * Test for the loadLocations() method.
661
     *
662
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
663
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCreateLocation
664
     */
665
    public function testLoadLocations()
666
    {
667
        $repository = $this->getRepository();
668
669
        $contentId = $this->generateId('object', 4);
670
        /* BEGIN: Use Case */
671
        // $contentId contains the ID of an existing content object
672
        $contentService = $repository->getContentService();
673
        $locationService = $repository->getLocationService();
674
675
        $contentInfo = $contentService->loadContentInfo($contentId);
676
677
        $locations = $locationService->loadLocations($contentInfo);
678
        /* END: Use Case */
679
680
        $this->assertInternalType('array', $locations);
681
        self::assertNotEmpty($locations);
682
683
        foreach ($locations as $location) {
684
            self::assertInstanceOf(Location::class, $location);
685
            self::assertEquals($contentInfo->id, $location->getContentInfo()->id);
686
        }
687
688
        return $locations;
689
    }
690
691
    /**
692
     * Test for the loadLocations() method.
693
     *
694
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
695
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
696
     */
697
    public function testLoadLocationsContent(array $locations)
698
    {
699
        $repository = $this->getRepository();
700
        $locationService = $repository->getLocationService();
0 ignored issues
show
Unused Code introduced by
$locationService is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
701
702
        $this->assertEquals(1, count($locations));
703
        foreach ($locations as $loadedLocation) {
704
            $this->assertInstanceOf(
705
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
706
                $loadedLocation
707
            );
708
        }
709
710
        usort(
711
            $locations,
712
            function ($a, $b) {
713
                strcmp($a->id, $b->id);
714
            }
715
        );
716
717
        $this->assertEquals(
718
            array($this->generateId('location', 5)),
719
            array_map(
720
                function (Location $location) {
721
                    return $location->id;
722
                },
723
                $locations
724
            )
725
        );
726
    }
727
728
    /**
729
     * Test for the loadLocations() method.
730
     *
731
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
732
     *
733
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
734
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
735
     */
736
    public function testLoadLocationsLimitedSubtree()
737
    {
738
        $repository = $this->getRepository();
739
740
        $originalLocationId = $this->generateId('location', 54);
741
        $originalParentLocationId = $this->generateId('location', 48);
742
        $newParentLocationId = $this->generateId('location', 43);
743
        /* BEGIN: Use Case */
744
        // $originalLocationId is the ID of an existing location
745
        // $originalParentLocationId is the ID of the parent location of
746
        //     $originalLocationId
747
        // $newParentLocationId is the ID of an existing location outside the tree
748
        // of $originalLocationId and $originalParentLocationId
749
        $locationService = $repository->getLocationService();
750
751
        // Location at "/1/48/54"
752
        $originalLocation = $locationService->loadLocation($originalLocationId);
753
754
        // Create location under "/1/43/"
755
        $locationCreate = $locationService->newLocationCreateStruct($newParentLocationId);
756
        $locationService->createLocation(
757
            $originalLocation->contentInfo,
758
            $locationCreate
759
        );
760
761
        $findRootLocation = $locationService->loadLocation($originalParentLocationId);
762
763
        // Returns an array with only $originalLocation
764
        $locations = $locationService->loadLocations(
765
            $originalLocation->contentInfo,
766
            $findRootLocation
767
        );
768
        /* END: Use Case */
769
770
        $this->assertInternalType('array', $locations);
771
772
        return $locations;
773
    }
774
775
    /**
776
     * Test for the loadLocations() method.
777
     *
778
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
779
     *
780
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
781
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationsLimitedSubtree
782
     */
783
    public function testLoadLocationsLimitedSubtreeContent(array $locations)
784
    {
785
        $this->assertEquals(1, count($locations));
786
787
        $this->assertEquals(
788
            $this->generateId('location', 54),
789
            reset($locations)->id
790
        );
791
    }
792
793
    /**
794
     * Test for the loadLocations() method.
795
     *
796
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations()
797
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
798
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
799
     */
800 View Code Duplication
    public function testLoadLocationsThrowsBadStateException()
801
    {
802
        $repository = $this->getRepository();
803
804
        /* BEGIN: Use Case */
805
        $contentTypeService = $repository->getContentTypeService();
806
        $contentService = $repository->getContentService();
807
        $locationService = $repository->getLocationService();
808
809
        // Create new content, which is not published
810
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
811
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
812
        $contentCreate->setField('name', 'New Folder');
813
        $content = $contentService->createContent($contentCreate);
814
815
        // Throws Exception, since $content has no published version, yet
816
        $locationService->loadLocations(
817
            $content->contentInfo
818
        );
819
        /* END: Use Case */
820
    }
821
822
    /**
823
     * Test for the loadLocations() method.
824
     *
825
     * @see \eZ\Publish\API\Repository\LocationService::loadLocations($contentInfo, $rootLocation)
826
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocations
827
     * @expectedException \eZ\Publish\API\Repository\Exceptions\BadStateException
828
     */
829
    public function testLoadLocationsThrowsBadStateExceptionLimitedSubtree()
830
    {
831
        $repository = $this->getRepository();
832
833
        $someLocationId = $this->generateId('location', 2);
834
        /* BEGIN: Use Case */
835
        // $someLocationId is the ID of an existing location
836
        $contentTypeService = $repository->getContentTypeService();
837
        $contentService = $repository->getContentService();
838
        $locationService = $repository->getLocationService();
839
840
        // Create new content, which is not published
841
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
842
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
843
        $contentCreate->setField('name', 'New Folder');
844
        $content = $contentService->createContent($contentCreate);
845
846
        $findRootLocation = $locationService->loadLocation($someLocationId);
847
848
        // Throws Exception, since $content has no published version, yet
849
        $locationService->loadLocations(
850
            $content->contentInfo,
851
            $findRootLocation
852
        );
853
        /* END: Use Case */
854
    }
855
856
    /**
857
     * Test for the loadLocationChildren() method.
858
     *
859
     * @covers \eZ\Publish\API\Repository\LocationService::loadLocationChildren
860
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
861
     */
862
    public function testLoadLocationChildren()
863
    {
864
        $repository = $this->getRepository();
865
866
        $locationId = $this->generateId('location', 5);
867
        /* BEGIN: Use Case */
868
        // $locationId is the ID of an existing location
869
        $locationService = $repository->getLocationService();
870
871
        $location = $locationService->loadLocation($locationId);
872
873
        $childLocations = $locationService->loadLocationChildren($location);
874
        /* END: Use Case */
875
876
        $this->assertInstanceOf(LocationList::class, $childLocations);
877
        $this->assertInternalType('array', $childLocations->locations);
878
        $this->assertNotEmpty($childLocations->locations);
879
        $this->assertInternalType('int', $childLocations->totalCount);
880
881
        foreach ($childLocations->locations as $childLocation) {
882
            $this->assertInstanceOf(Location::class, $childLocation);
883
            $this->assertEquals($location->id, $childLocation->parentLocationId);
884
        }
885
886
        return $childLocations;
887
    }
888
889
    /**
890
     * Test loading parent Locations for draft Content.
891
     *
892
     * @covers \eZ\Publish\API\Repository\LocationService::loadParentLocationsForDraftContent
893
     */
894
    public function testLoadParentLocationsForDraftContent()
895
    {
896
        $repository = $this->getRepository();
897
        $locationService = $repository->getLocationService();
898
        $contentService = $repository->getContentService();
899
        $contentTypeService = $repository->getContentTypeService();
900
901
        // prepare locations
902
        $locationCreateStructs = [
903
            $locationService->newLocationCreateStruct(2),
904
            $locationService->newLocationCreateStruct(5),
905
        ];
906
907
        // Create new content
908
        $folderType = $contentTypeService->loadContentTypeByIdentifier('folder');
909
        $contentCreate = $contentService->newContentCreateStruct($folderType, 'eng-US');
910
        $contentCreate->setField('name', 'New Folder');
911
        $contentDraft = $contentService->createContent($contentCreate, $locationCreateStructs);
912
913
        // Test loading parent Locations
914
        $locations = $locationService->loadParentLocationsForDraftContent($contentDraft->versionInfo);
915
916
        self::assertCount(2, $locations);
917
        foreach ($locations as $location) {
918
            // test it is one of the given parent locations
919
            self::assertTrue($location->id === 2 || $location->id === 5);
920
        }
921
922
        return $contentDraft;
923
    }
924
925
    /**
926
     * Test that trying to load parent Locations throws Exception if Content is not a draft.
927
     *
928
     * @depends testLoadParentLocationsForDraftContent
929
     *
930
     * @param \eZ\Publish\API\Repository\Values\Content\Content $contentDraft
931
     */
932
    public function testLoadParentLocationsForDraftContentThrowsBadStateException(Content $contentDraft)
933
    {
934
        $this->expectException(BadStateException::class);
935
        $this->expectExceptionMessageRegExp('/has been already published/');
936
937
        $repository = $this->getRepository(false);
938
        $locationService = $repository->getLocationService();
939
        $contentService = $repository->getContentService();
940
941
        $content = $contentService->publishVersion($contentDraft->versionInfo);
942
943
        $locationService->loadParentLocationsForDraftContent($content->versionInfo);
944
    }
945
946
    /**
947
     * Test for the getLocationChildCount() method.
948
     *
949
     * @see \eZ\Publish\API\Repository\LocationService::getLocationChildCount()
950
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
951
     */
952
    public function testGetLocationChildCount()
953
    {
954
        // $locationId is the ID of an existing location
955
        $locationService = $this->getRepository()->getLocationService();
956
957
        $this->assertSame(
958
            5,
959
            $locationService->getLocationChildCount(
960
                $locationService->loadLocation($this->generateId('location', 5))
961
            )
962
        );
963
    }
964
965
    /**
966
     * Test for the loadLocationChildren() method.
967
     *
968
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren()
969
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
970
     */
971
    public function testLoadLocationChildrenData(LocationList $locations)
972
    {
973
        $this->assertEquals(5, count($locations->locations));
974
        $this->assertEquals(5, $locations->totalCount);
975
976
        foreach ($locations->locations as $location) {
977
            $this->assertInstanceOf(
978
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
979
                $location
980
            );
981
        }
982
983
        $this->assertEquals(
984
            array(
985
                $this->generateId('location', 12),
986
                $this->generateId('location', 13),
987
                $this->generateId('location', 14),
988
                $this->generateId('location', 44),
989
                $this->generateId('location', 61),
990
            ),
991
            array_map(
992
                function (Location $location) {
993
                    return $location->id;
994
                },
995
                $locations->locations
996
            )
997
        );
998
    }
999
1000
    /**
1001
     * Test for the loadLocationChildren() method.
1002
     *
1003
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
1004
     *
1005
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
1006
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
1007
     */
1008 View Code Duplication
    public function testLoadLocationChildrenWithOffset()
1009
    {
1010
        $repository = $this->getRepository();
1011
1012
        $locationId = $this->generateId('location', 5);
1013
        /* BEGIN: Use Case */
1014
        // $locationId is the ID of an existing location
1015
        $locationService = $repository->getLocationService();
1016
1017
        $location = $locationService->loadLocation($locationId);
1018
1019
        $childLocations = $locationService->loadLocationChildren($location, 2);
1020
        /* END: Use Case */
1021
1022
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
1023
        $this->assertInternalType('array', $childLocations->locations);
1024
        $this->assertInternalType('int', $childLocations->totalCount);
1025
1026
        return $childLocations;
1027
    }
1028
1029
    /**
1030
     * Test for the loadLocationChildren() method.
1031
     *
1032
     * @param \eZ\Publish\API\Repository\Values\Content\LocationList $locations
1033
     *
1034
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset)
1035
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffset
1036
     */
1037 View Code Duplication
    public function testLoadLocationChildrenDataWithOffset(LocationList $locations)
1038
    {
1039
        $this->assertEquals(3, count($locations->locations));
1040
        $this->assertEquals(5, $locations->totalCount);
1041
1042
        foreach ($locations->locations as $location) {
1043
            $this->assertInstanceOf(
1044
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1045
                $location
1046
            );
1047
        }
1048
1049
        $this->assertEquals(
1050
            array(
1051
                $this->generateId('location', 14),
1052
                $this->generateId('location', 44),
1053
                $this->generateId('location', 61),
1054
            ),
1055
            array_map(
1056
                function (Location $location) {
1057
                    return $location->id;
1058
                },
1059
                $locations->locations
1060
            )
1061
        );
1062
    }
1063
1064
    /**
1065
     * Test for the loadLocationChildren() method.
1066
     *
1067
     * @return \eZ\Publish\API\Repository\Values\Content\Location[]
1068
     *
1069
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
1070
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildren
1071
     */
1072 View Code Duplication
    public function testLoadLocationChildrenWithOffsetAndLimit()
1073
    {
1074
        $repository = $this->getRepository();
1075
1076
        $locationId = $this->generateId('location', 5);
1077
        /* BEGIN: Use Case */
1078
        // $locationId is the ID of an existing location
1079
        $locationService = $repository->getLocationService();
1080
1081
        $location = $locationService->loadLocation($locationId);
1082
1083
        $childLocations = $locationService->loadLocationChildren($location, 2, 2);
1084
        /* END: Use Case */
1085
1086
        $this->assertInstanceOf('\\eZ\\Publish\\API\\Repository\\Values\\Content\\LocationList', $childLocations);
1087
        $this->assertInternalType('array', $childLocations->locations);
1088
        $this->assertInternalType('int', $childLocations->totalCount);
1089
1090
        return $childLocations;
1091
    }
1092
1093
    /**
1094
     * Test for the loadLocationChildren() method.
1095
     *
1096
     * @param \eZ\Publish\API\Repository\Values\Content\Location[] $locations
1097
     *
1098
     * @see \eZ\Publish\API\Repository\LocationService::loadLocationChildren($location, $offset, $limit)
1099
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocationChildrenWithOffsetAndLimit
1100
     */
1101 View Code Duplication
    public function testLoadLocationChildrenDataWithOffsetAndLimit(LocationList $locations)
1102
    {
1103
        $this->assertEquals(2, count($locations->locations));
1104
        $this->assertEquals(5, $locations->totalCount);
1105
1106
        foreach ($locations->locations as $location) {
1107
            $this->assertInstanceOf(
1108
                '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1109
                $location
1110
            );
1111
        }
1112
1113
        $this->assertEquals(
1114
            array(
1115
                $this->generateId('location', 14),
1116
                $this->generateId('location', 44),
1117
            ),
1118
            array_map(
1119
                function (Location $location) {
1120
                    return $location->id;
1121
                },
1122
                $locations->locations
1123
            )
1124
        );
1125
    }
1126
1127
    /**
1128
     * Test for the newLocationUpdateStruct() method.
1129
     *
1130
     * @covers \eZ\Publish\API\Repository\LocationService::newLocationUpdateStruct
1131
     */
1132 View Code Duplication
    public function testNewLocationUpdateStruct()
1133
    {
1134
        $repository = $this->getRepository();
1135
1136
        /* BEGIN: Use Case */
1137
        $locationService = $repository->getLocationService();
1138
1139
        $updateStruct = $locationService->newLocationUpdateStruct();
1140
        /* END: Use Case */
1141
1142
        $this->assertInstanceOf(
1143
            LocationUpdateStruct::class,
1144
            $updateStruct
1145
        );
1146
1147
        $this->assertPropertiesCorrect(
1148
            [
1149
                'priority' => null,
1150
                'remoteId' => null,
1151
                'sortField' => null,
1152
                'sortOrder' => null,
1153
            ],
1154
            $updateStruct
1155
        );
1156
    }
1157
1158
    /**
1159
     * Test for the updateLocation() method.
1160
     *
1161
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1162
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1163
     */
1164
    public function testUpdateLocation()
1165
    {
1166
        $repository = $this->getRepository();
1167
1168
        $originalLocationId = $this->generateId('location', 5);
1169
        /* BEGIN: Use Case */
1170
        // $originalLocationId is the ID of an existing location
1171
        $locationService = $repository->getLocationService();
1172
1173
        $originalLocation = $locationService->loadLocation($originalLocationId);
1174
1175
        $updateStruct = $locationService->newLocationUpdateStruct();
1176
        $updateStruct->priority = 3;
1177
        $updateStruct->remoteId = 'c7adcbf1e96bc29bca28c2d809d0c7ef69272651';
1178
        $updateStruct->sortField = Location::SORT_FIELD_PRIORITY;
1179
        $updateStruct->sortOrder = Location::SORT_ORDER_DESC;
1180
1181
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
1182
        /* END: Use Case */
1183
1184
        $this->assertInstanceOf(
1185
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1186
            $updatedLocation
1187
        );
1188
1189
        return array(
1190
            'originalLocation' => $originalLocation,
1191
            'updateStruct' => $updateStruct,
1192
            'updatedLocation' => $updatedLocation,
1193
        );
1194
    }
1195
1196
    /**
1197
     * Test for the updateLocation() method.
1198
     *
1199
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1200
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testUpdateLocation
1201
     */
1202
    public function testUpdateLocationStructValues(array $data)
1203
    {
1204
        $originalLocation = $data['originalLocation'];
1205
        $updateStruct = $data['updateStruct'];
1206
        $updatedLocation = $data['updatedLocation'];
1207
1208
        $this->assertPropertiesCorrect(
1209
            array(
1210
                'id' => $originalLocation->id,
1211
                'priority' => $updateStruct->priority,
1212
                'hidden' => $originalLocation->hidden,
1213
                'invisible' => $originalLocation->invisible,
1214
                'remoteId' => $updateStruct->remoteId,
1215
                'contentInfo' => $originalLocation->contentInfo,
1216
                'parentLocationId' => $originalLocation->parentLocationId,
1217
                'pathString' => $originalLocation->pathString,
1218
                'depth' => $originalLocation->depth,
1219
                'sortField' => $updateStruct->sortField,
1220
                'sortOrder' => $updateStruct->sortOrder,
1221
            ),
1222
            $updatedLocation
1223
        );
1224
    }
1225
1226
    /**
1227
     * Test for the updateLocation() method.
1228
     *
1229
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1230
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1231
     */
1232
    public function testUpdateLocationWithSameRemoteId()
1233
    {
1234
        $repository = $this->getRepository();
1235
1236
        $locationId = $this->generateId('location', 5);
1237
        /* BEGIN: Use Case */
1238
        // $locationId and remote ID is the IDs of the same, existing location
1239
        $locationService = $repository->getLocationService();
1240
1241
        $originalLocation = $locationService->loadLocation($locationId);
1242
1243
        $updateStruct = $locationService->newLocationUpdateStruct();
1244
1245
        // Remote ID of an existing location with the same locationId
1246
        $updateStruct->remoteId = $originalLocation->remoteId;
1247
1248
        // Sets one of the properties to be able to confirm location gets updated, here: priority
1249
        $updateStruct->priority = 2;
1250
1251
        $location = $locationService->updateLocation($originalLocation, $updateStruct);
1252
1253
        // Checks that the location was updated
1254
        $this->assertEquals(2, $location->priority);
1255
1256
        // Checks that remoteId remains the same
1257
        $this->assertEquals($originalLocation->remoteId, $location->remoteId);
1258
        /* END: Use Case */
1259
    }
1260
1261
    /**
1262
     * Test for the updateLocation() method.
1263
     *
1264
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1265
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1266
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1267
     */
1268 View Code Duplication
    public function testUpdateLocationThrowsInvalidArgumentException()
1269
    {
1270
        $repository = $this->getRepository();
1271
1272
        $locationId = $this->generateId('location', 5);
1273
        /* BEGIN: Use Case */
1274
        // $locationId and remoteId is the IDs of an existing, but not the same, location
1275
        $locationService = $repository->getLocationService();
1276
1277
        $originalLocation = $locationService->loadLocation($locationId);
1278
1279
        $updateStruct = $locationService->newLocationUpdateStruct();
1280
1281
        // Remote ID of an existing location with a different locationId
1282
        $updateStruct->remoteId = 'f3e90596361e31d496d4026eb624c983';
1283
1284
        // Throws exception, since remote ID is already taken
1285
        $locationService->updateLocation($originalLocation, $updateStruct);
1286
        /* END: Use Case */
1287
    }
1288
1289
    /**
1290
     * Test for the updateLocation() method.
1291
     *
1292
     * @covers \eZ\Publish\API\Repository\LocationService::updateLocation()
1293
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1294
     * @dataProvider dataProviderForOutOfRangeLocationPriority
1295
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
1296
     */
1297
    public function testUpdateLocationThrowsInvalidArgumentExceptionPriorityIsOutOfRange($priority)
1298
    {
1299
        $repository = $this->getRepository();
1300
1301
        $locationId = $this->generateId('location', 5);
1302
        /* BEGIN: Use Case */
1303
        // $locationId and remoteId is the IDs of an existing, but not the same, location
1304
        $locationService = $repository->getLocationService();
1305
1306
        $originalLocation = $locationService->loadLocation($locationId);
1307
1308
        $updateStruct = $locationService->newLocationUpdateStruct();
1309
1310
        // Priority value is out of range
1311
        $updateStruct->priority = $priority;
1312
1313
        // Throws exception, since remote ID is already taken
1314
        $locationService->updateLocation($originalLocation, $updateStruct);
1315
        /* END: Use Case */
1316
    }
1317
1318
    /**
1319
     * Test for the updateLocation() method.
1320
     * Ref EZP-23302: Update Location fails if no change is performed with the update.
1321
     *
1322
     * @see \eZ\Publish\API\Repository\LocationService::updateLocation()
1323
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1324
     */
1325
    public function testUpdateLocationTwice()
1326
    {
1327
        $repository = $this->getRepository();
1328
1329
        $locationId = $this->generateId('location', 5);
1330
        /* BEGIN: Use Case */
1331
        $locationService = $repository->getLocationService();
1332
        $repository->setCurrentUser($repository->getUserService()->loadUser(14));
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\API\Repositor...itory::setCurrentUser() has been deprecated with message: since 6.6, to be removed. Use PermissionResolver::setCurrentUserReference() instead. Sets the current user to the given $user.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
1333
1334
        $originalLocation = $locationService->loadLocation($locationId);
1335
1336
        $updateStruct = $locationService->newLocationUpdateStruct();
1337
        $updateStruct->priority = 42;
1338
1339
        $updatedLocation = $locationService->updateLocation($originalLocation, $updateStruct);
1340
1341
        // Repeated update with the same, unchanged struct
1342
        $secondUpdatedLocation = $locationService->updateLocation($updatedLocation, $updateStruct);
1343
        /* END: Use Case */
1344
1345
        $this->assertEquals($updatedLocation->priority, 42);
1346
        $this->assertEquals($secondUpdatedLocation->priority, 42);
1347
    }
1348
1349
    /**
1350
     * Test for the swapLocation() method.
1351
     *
1352
     * @see \eZ\Publish\API\Repository\LocationService::swapLocation()
1353
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1354
     */
1355
    public function testSwapLocation()
1356
    {
1357
        $repository = $this->getRepository();
1358
        $locationService = $repository->getLocationService();
1359
1360
        $mediaLocationId = $this->generateId('location', 43);
1361
        $demoDesignLocationId = $this->generateId('location', 56);
1362
1363
        $mediaContentInfo = $locationService->loadLocation($mediaLocationId)->getContentInfo();
1364
        $demoDesignContentInfo = $locationService->loadLocation($demoDesignLocationId)->getContentInfo();
1365
1366
        /* BEGIN: Use Case */
1367
        // $mediaLocationId is the ID of the "Media" page location in
1368
        // an eZ Publish demo installation
1369
1370
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1371
        // Publish demo installation
1372
1373
        // Load the location service
1374
        $locationService = $repository->getLocationService();
1375
1376
        $mediaLocation = $locationService->loadLocation($mediaLocationId);
1377
        $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId);
1378
1379
        // Swaps the content referred to by the locations
1380
        $locationService->swapLocation($mediaLocation, $demoDesignLocation);
1381
        /* END: Use Case */
1382
1383
        // Reload Locations, IDs swapped
1384
        $demoDesignLocation = $locationService->loadLocation($mediaLocationId);
1385
        $mediaLocation = $locationService->loadLocation($demoDesignLocationId);
1386
1387
        // Assert Location's Content is updated
1388
        $this->assertEquals(
1389
            $mediaContentInfo->id,
1390
            $mediaLocation->getContentInfo()->id
1391
        );
1392
        $this->assertEquals(
1393
            $demoDesignContentInfo->id,
1394
            $demoDesignLocation->getContentInfo()->id
1395
        );
1396
1397
        // Assert URL aliases are updated
1398
        $this->assertEquals(
1399
            $mediaLocation->id,
1400
            $repository->getURLAliasService()->lookup('/Design/Media')->destination
1401
        );
1402
        $this->assertEquals(
1403
            $demoDesignLocation->id,
1404
            $repository->getURLAliasService()->lookup('/eZ-Publish-Demo-Design-without-demo-content')->destination
1405
        );
1406
    }
1407
1408
    /**
1409
     * Test swapping Main Location of a Content with another one updates Content item Main Location.
1410
     *
1411
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1412
     */
1413
    public function testSwapLocationUpdatesMainLocation()
1414
    {
1415
        $repository = $this->getRepository();
1416
        $locationService = $repository->getLocationService();
1417
        $contentService = $repository->getContentService();
1418
1419
        $mainLocationParentId = 60;
1420
        $secondaryLocationId = 43;
1421
1422
        $publishedContent = $this->publishContentWithParentLocation(
1423
            'Content for Swap Location Test', $mainLocationParentId
1424
        );
1425
1426
        // sanity check
1427
        $mainLocation = $locationService->loadLocation($publishedContent->contentInfo->mainLocationId);
1428
        self::assertEquals($mainLocationParentId, $mainLocation->parentLocationId);
1429
1430
        // load another pre-existing location
1431
        $secondaryLocation = $locationService->loadLocation($secondaryLocationId);
1432
1433
        // swap the Main Location with a secondary one
1434
        $locationService->swapLocation($mainLocation, $secondaryLocation);
1435
1436
        // check if Main Location has been updated
1437
        $mainLocation = $locationService->loadLocation($secondaryLocation->id);
1438
        self::assertEquals($publishedContent->contentInfo->id, $mainLocation->contentInfo->id);
1439
        self::assertEquals($mainLocation->id, $mainLocation->contentInfo->mainLocationId);
1440
1441
        $reloadedContent = $contentService->loadContentByContentInfo($publishedContent->contentInfo);
1442
        self::assertEquals($mainLocation->id, $reloadedContent->contentInfo->mainLocationId);
1443
    }
1444
1445
    /**
1446
     * Test if location swap affects related bookmarks.
1447
     *
1448
     * @covers \eZ\Publish\API\Repository\LocationService::swapLocation
1449
     */
1450
    public function testBookmarksAreSwappedAfterSwapLocation()
1451
    {
1452
        $repository = $this->getRepository();
1453
1454
        $mediaLocationId = $this->generateId('location', 43);
1455
        $demoDesignLocationId = $this->generateId('location', 56);
1456
1457
        /* BEGIN: Use Case */
1458
        $locationService = $repository->getLocationService();
1459
        $bookmarkService = $repository->getBookmarkService();
1460
1461
        $mediaLocation = $locationService->loadLocation($mediaLocationId);
1462
        $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId);
1463
1464
        // Bookmark locations
1465
        $bookmarkService->createBookmark($mediaLocation);
1466
        $bookmarkService->createBookmark($demoDesignLocation);
1467
1468
        $beforeSwap = $bookmarkService->loadBookmarks();
1469
1470
        // Swaps the content referred to by the locations
1471
        $locationService->swapLocation($mediaLocation, $demoDesignLocation);
1472
1473
        $afterSwap = $bookmarkService->loadBookmarks();
1474
        /* END: Use Case */
1475
1476
        $this->assertEquals($beforeSwap->items[0]->id, $afterSwap->items[1]->id);
1477
        $this->assertEquals($beforeSwap->items[1]->id, $afterSwap->items[0]->id);
1478
    }
1479
1480
    /**
1481
     * Test for the hideLocation() method.
1482
     *
1483
     * @see \eZ\Publish\API\Repository\LocationService::hideLocation()
1484
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1485
     */
1486
    public function testHideLocation()
1487
    {
1488
        $repository = $this->getRepository();
1489
1490
        $locationId = $this->generateId('location', 5);
1491
        /* BEGIN: Use Case */
1492
        // $locationId is the ID of an existing location
1493
        $locationService = $repository->getLocationService();
1494
1495
        $visibleLocation = $locationService->loadLocation($locationId);
1496
1497
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1498
        /* END: Use Case */
1499
1500
        $this->assertInstanceOf(
1501
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1502
            $hiddenLocation
1503
        );
1504
1505
        $this->assertTrue(
1506
            $hiddenLocation->hidden,
1507
            sprintf(
1508
                'Location with ID "%s" not hidden.',
1509
                $hiddenLocation->id
1510
            )
1511
        );
1512
1513
        $this->refreshSearch($repository);
1514
1515
        foreach ($locationService->loadLocationChildren($hiddenLocation)->locations as $child) {
1516
            $this->assertSubtreeProperties(
1517
                array('invisible' => true),
1518
                $child
1519
            );
1520
        }
1521
    }
1522
1523
    /**
1524
     * Assert that $expectedValues are set in the subtree starting at $location.
1525
     *
1526
     * @param array $expectedValues
1527
     * @param Location $location
1528
     */
1529
    protected function assertSubtreeProperties(array $expectedValues, Location $location, $stopId = null)
1530
    {
1531
        $repository = $this->getRepository();
1532
        $locationService = $repository->getLocationService();
1533
1534
        if ($location->id === $stopId) {
1535
            return;
1536
        }
1537
1538
        foreach ($expectedValues as $propertyName => $propertyValue) {
1539
            $this->assertEquals(
1540
                $propertyValue,
1541
                $location->$propertyName
1542
            );
1543
1544
            foreach ($locationService->loadLocationChildren($location)->locations as $child) {
1545
                $this->assertSubtreeProperties($expectedValues, $child);
1546
            }
1547
        }
1548
    }
1549
1550
    /**
1551
     * Test for the unhideLocation() method.
1552
     *
1553
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1554
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testHideLocation
1555
     */
1556
    public function testUnhideLocation()
1557
    {
1558
        $repository = $this->getRepository();
1559
1560
        $locationId = $this->generateId('location', 5);
1561
        /* BEGIN: Use Case */
1562
        // $locationId is the ID of an existing location
1563
        $locationService = $repository->getLocationService();
1564
1565
        $visibleLocation = $locationService->loadLocation($locationId);
1566
        $hiddenLocation = $locationService->hideLocation($visibleLocation);
1567
1568
        $unHiddenLocation = $locationService->unhideLocation($hiddenLocation);
1569
        /* END: Use Case */
1570
1571
        $this->assertInstanceOf(
1572
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1573
            $unHiddenLocation
1574
        );
1575
1576
        $this->assertFalse(
1577
            $unHiddenLocation->hidden,
1578
            sprintf(
1579
                'Location with ID "%s" not unhidden.',
1580
                $unHiddenLocation->id
1581
            )
1582
        );
1583
1584
        $this->refreshSearch($repository);
1585
1586
        foreach ($locationService->loadLocationChildren($unHiddenLocation)->locations as $child) {
1587
            $this->assertSubtreeProperties(
1588
                array('invisible' => false),
1589
                $child
1590
            );
1591
        }
1592
    }
1593
1594
    /**
1595
     * Test for the unhideLocation() method.
1596
     *
1597
     * @see \eZ\Publish\API\Repository\LocationService::unhideLocation()
1598
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testUnhideLocation
1599
     */
1600
    public function testUnhideLocationNotUnhidesHiddenSubtree()
1601
    {
1602
        $repository = $this->getRepository();
1603
1604
        $higherLocationId = $this->generateId('location', 5);
1605
        $lowerLocationId = $this->generateId('location', 13);
1606
        /* BEGIN: Use Case */
1607
        // $higherLocationId is the ID of a location
1608
        // $lowerLocationId is the ID of a location below $higherLocationId
1609
        $locationService = $repository->getLocationService();
1610
1611
        $higherLocation = $locationService->loadLocation($higherLocationId);
1612
        $hiddenHigherLocation = $locationService->hideLocation($higherLocation);
1613
1614
        $lowerLocation = $locationService->loadLocation($lowerLocationId);
1615
        $hiddenLowerLocation = $locationService->hideLocation($lowerLocation);
0 ignored issues
show
Unused Code introduced by
$hiddenLowerLocation is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1616
1617
        $unHiddenHigherLocation = $locationService->unhideLocation($hiddenHigherLocation);
1618
        /* END: Use Case */
1619
1620
        $this->assertInstanceOf(
1621
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1622
            $unHiddenHigherLocation
1623
        );
1624
1625
        $this->assertFalse(
1626
            $unHiddenHigherLocation->hidden,
1627
            sprintf(
1628
                'Location with ID "%s" not unhidden.',
1629
                $unHiddenHigherLocation->id
1630
            )
1631
        );
1632
1633
        $this->refreshSearch($repository);
1634
1635
        foreach ($locationService->loadLocationChildren($unHiddenHigherLocation)->locations as $child) {
1636
            $this->assertSubtreeProperties(
1637
                array('invisible' => false),
1638
                $child,
1639
                $this->generateId('location', 13)
1640
            );
1641
        }
1642
1643
        $stillHiddenLocation = $locationService->loadLocation($this->generateId('location', 13));
1644
        $this->assertTrue(
1645
            $stillHiddenLocation->hidden,
1646
            sprintf(
1647
                'Hidden sub-location with ID %s accidentally unhidden.',
1648
                $stillHiddenLocation->id
1649
            )
1650
        );
1651
        foreach ($locationService->loadLocationChildren($stillHiddenLocation)->locations as $child) {
1652
            $this->assertSubtreeProperties(
1653
                array('invisible' => true),
1654
                $child
1655
            );
1656
        }
1657
    }
1658
1659
    /**
1660
     * Test for the deleteLocation() method.
1661
     *
1662
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1663
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1664
     */
1665
    public function testDeleteLocation()
1666
    {
1667
        $repository = $this->getRepository();
1668
1669
        $mediaLocationId = $this->generateId('location', 43);
1670
        /* BEGIN: Use Case */
1671
        // $mediaLocationId is the ID of the location of the
1672
        // "Media" location in an eZ Publish demo installation
1673
        $locationService = $repository->getLocationService();
1674
1675
        $location = $locationService->loadLocation($mediaLocationId);
1676
1677
        $locationService->deleteLocation($location);
1678
        /* END: Use Case */
1679
1680
        try {
1681
            $locationService->loadLocation($mediaLocationId);
1682
            $this->fail("Location $mediaLocationId not deleted.");
1683
        } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1684
        }
1685
1686
        // The following IDs are IDs of child locations of $mediaLocationId location
1687
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1688
        foreach (array(51, 52, 53) as $childLocationId) {
1689
            try {
1690
                $locationService->loadLocation($this->generateId('location', $childLocationId));
1691
                $this->fail("Location $childLocationId not deleted.");
1692
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1693
            }
1694
        }
1695
1696
        // The following IDs are IDs of content below $mediaLocationId location
1697
        // ( Media/Images, Media/Files, Media/Multimedia respectively )
1698
        $contentService = $this->getRepository()->getContentService();
1699
        foreach (array(49, 50, 51) as $childContentId) {
1700
            try {
1701
                $contentService->loadContentInfo($this->generateId('object', $childContentId));
1702
                $this->fail("Content $childContentId not deleted.");
1703
            } catch (NotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1704
            }
1705
        }
1706
    }
1707
1708
    /**
1709
     * Test for the deleteLocation() method.
1710
     *
1711
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1712
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testDeleteLocation
1713
     */
1714
    public function testDeleteLocationDecrementsChildCountOnParent()
1715
    {
1716
        $repository = $this->getRepository();
1717
1718
        $mediaLocationId = $this->generateId('location', 43);
1719
        /* BEGIN: Use Case */
1720
        // $mediaLocationId is the ID of the location of the
1721
        // "Media" location in an eZ Publish demo installation
1722
1723
        $locationService = $repository->getLocationService();
1724
1725
        // Load the current the user group location
1726
        $location = $locationService->loadLocation($mediaLocationId);
1727
1728
        // Load the parent location
1729
        $parentLocation = $locationService->loadLocation(
1730
            $location->parentLocationId
1731
        );
1732
1733
        // Get child count
1734
        $childCountBefore = $locationService->getLocationChildCount($parentLocation);
1735
1736
        // Delete the user group location
1737
        $locationService->deleteLocation($location);
1738
1739
        $this->refreshSearch($repository);
1740
1741
        // Reload parent location
1742
        $parentLocation = $locationService->loadLocation(
1743
            $location->parentLocationId
1744
        );
1745
1746
        // This will be $childCountBefore - 1
1747
        $childCountAfter = $locationService->getLocationChildCount($parentLocation);
1748
        /* END: Use Case */
1749
1750
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
1751
    }
1752
1753
    /**
1754
     * Test for the deleteLocation() method.
1755
     *
1756
     * Related issue: EZP-21904
1757
     *
1758
     * @see \eZ\Publish\API\Repository\LocationService::deleteLocation()
1759
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
1760
     */
1761
    public function testDeleteContentObjectLastLocation()
1762
    {
1763
        $repository = $this->getRepository();
1764
1765
        /* BEGIN: Use case */
1766
        $contentService = $repository->getContentService();
1767
        $locationService = $repository->getLocationService();
1768
        $contentTypeService = $repository->getContentTypeService();
1769
        $urlAliasService = $repository->getURLAliasService();
1770
1771
        // prepare Content object
1772
        $createStruct = $contentService->newContentCreateStruct(
1773
            $contentTypeService->loadContentTypeByIdentifier('folder'),
1774
            'eng-GB'
1775
        );
1776
        $createStruct->setField('name', 'Test folder');
1777
1778
        // creata Content object
1779
        $content = $contentService->publishVersion(
1780
            $contentService->createContent(
1781
                $createStruct,
1782
                array($locationService->newLocationCreateStruct(2))
1783
            )->versionInfo
1784
        );
1785
1786
        // delete location
1787
        $locationService->deleteLocation(
1788
            $locationService->loadLocation(
1789
                $urlAliasService->lookup('/Test-folder')->destination
1790
            )
1791
        );
1792
1793
        // this should throw a not found exception
1794
        $contentService->loadContent($content->versionInfo->contentInfo->id);
1795
        /* END: Use case*/
1796
    }
1797
1798
    /**
1799
     * Test for the deleteLocation() method.
1800
     *
1801
     * @covers  \eZ\Publish\API\Repository\LocationService::deleteLocation()
1802
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testDeleteLocation
1803
     */
1804
    public function testDeleteLocationDeletesRelatedBookmarks()
1805
    {
1806
        $repository = $this->getRepository();
1807
1808
        $parentLocationId = $this->generateId('location', 43);
1809
        $childLocationId = $this->generateId('location', 53);
1810
1811
        /* BEGIN: Use Case */
1812
        $locationService = $repository->getLocationService();
1813
        $bookmarkService = $repository->getBookmarkService();
1814
1815
        // Load location
1816
        $childLocation = $locationService->loadLocation($childLocationId);
1817
        // Add location to bookmarks
1818
        $bookmarkService->createBookmark($childLocation);
1819
        // Load parent location
1820
        $parentLocation = $locationService->loadLocation($parentLocationId);
1821
        // Delete parent location
1822
        $locationService->deleteLocation($parentLocation);
1823
        /* END: Use Case */
1824
1825
        // Location isn't bookmarked anymore
1826
        foreach ($bookmarkService->loadBookmarks(0, 9999) as $bookmarkedLocation) {
1827
            $this->assertNotEquals($childLocation->id, $bookmarkedLocation->id);
1828
        }
1829
    }
1830
1831
    /**
1832
     * Test for the copySubtree() method.
1833
     *
1834
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1835
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1836
     */
1837
    public function testCopySubtree()
1838
    {
1839
        $repository = $this->getRepository();
1840
1841
        $mediaLocationId = $this->generateId('location', 43);
1842
        $demoDesignLocationId = $this->generateId('location', 56);
1843
        /* BEGIN: Use Case */
1844
        // $mediaLocationId is the ID of the "Media" page location in
1845
        // an eZ Publish demo installation
1846
1847
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1848
        // Publish demo installation
1849
1850
        // Load the location service
1851
        $locationService = $repository->getLocationService();
1852
1853
        // Load location to copy
1854
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1855
1856
        // Load new parent location
1857
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1858
1859
        // Copy location "Media" to "Demo Design"
1860
        $copiedLocation = $locationService->copySubtree(
1861
            $locationToCopy,
1862
            $newParentLocation
1863
        );
1864
        /* END: Use Case */
1865
1866
        $this->assertInstanceOf(
1867
            '\\eZ\\Publish\\API\\Repository\\Values\\Content\\Location',
1868
            $copiedLocation
1869
        );
1870
1871
        $this->assertPropertiesCorrect(
1872
            array(
1873
                'depth' => $newParentLocation->depth + 1,
1874
                'parentLocationId' => $newParentLocation->id,
1875
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $copiedLocation->id) . '/',
1876
            ),
1877
            $copiedLocation
1878
        );
1879
1880
        $this->assertDefaultContentStates($copiedLocation->contentInfo);
1881
    }
1882
1883
    /**
1884
     * Test for the copySubtree() method.
1885
     *
1886
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1887
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
1888
     */
1889
    public function testCopySubtreeWithAliases()
1890
    {
1891
        $repository = $this->getRepository();
1892
        $urlAliasService = $repository->getURLAliasService();
1893
1894
        // $mediaLocationId is the ID of the "Media" page location in
1895
        // an eZ Publish demo installation
1896
1897
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1898
        // Publish demo installation
1899
        $mediaLocationId = $this->generateId('location', 43);
1900
        $demoDesignLocationId = $this->generateId('location', 56);
1901
1902
        $locationService = $repository->getLocationService();
1903
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1904
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1905
1906
        $expectedSubItemAliases = [
1907
            '/Design/Plain-site/Media/Multimedia',
1908
            '/Design/Plain-site/Media/Images',
1909
            '/Design/Plain-site/Media/Files',
1910
        ];
1911
1912
        $this->assertAliasesBeforeCopy($urlAliasService, $expectedSubItemAliases);
1913
1914
        // Copy location "Media" to "Design"
1915
        $locationService->copySubtree(
1916
            $locationToCopy,
1917
            $newParentLocation
1918
        );
1919
1920
        $this->assertGeneratedAliases($urlAliasService, $expectedSubItemAliases);
1921
    }
1922
1923
    /**
1924
     * Asserts that given Content has default ContentStates.
1925
     *
1926
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
1927
     */
1928 View Code Duplication
    private function assertDefaultContentStates(ContentInfo $contentInfo)
1929
    {
1930
        $repository = $this->getRepository();
1931
        $objectStateService = $repository->getObjectStateService();
1932
1933
        $objectStateGroups = $objectStateService->loadObjectStateGroups();
1934
1935
        foreach ($objectStateGroups as $objectStateGroup) {
1936
            $contentState = $objectStateService->getContentState($contentInfo, $objectStateGroup);
1937
            foreach ($objectStateService->loadObjectStates($objectStateGroup) as $objectState) {
1938
                // Only check the first object state which is the default one.
1939
                $this->assertEquals(
1940
                    $objectState,
1941
                    $contentState
1942
                );
1943
                break;
1944
            }
1945
        }
1946
    }
1947
1948
    /**
1949
     * Test for the copySubtree() method.
1950
     *
1951
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
1952
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
1953
     */
1954
    public function testCopySubtreeUpdatesSubtreeProperties()
1955
    {
1956
        $repository = $this->getRepository();
1957
        $locationService = $repository->getLocationService();
1958
1959
        $locationToCopy = $locationService->loadLocation($this->generateId('location', 43));
1960
1961
        // Load Subtree properties before copy
1962
        $expected = $this->loadSubtreeProperties($locationToCopy);
1963
1964
        $mediaLocationId = $this->generateId('location', 43);
1965
        $demoDesignLocationId = $this->generateId('location', 56);
1966
        /* BEGIN: Use Case */
1967
        // $mediaLocationId is the ID of the "Media" page location in
1968
        // an eZ Publish demo installation
1969
1970
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
1971
        // Publish demo installation
1972
1973
        // Load the location service
1974
        $locationService = $repository->getLocationService();
1975
1976
        // Load location to copy
1977
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
1978
1979
        // Load new parent location
1980
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
1981
1982
        // Copy location "Media" to "Demo Design"
1983
        $copiedLocation = $locationService->copySubtree(
1984
            $locationToCopy,
1985
            $newParentLocation
1986
        );
1987
        /* END: Use Case */
1988
1989
        $beforeIds = array();
1990
        foreach ($expected as $properties) {
1991
            $beforeIds[] = $properties['id'];
1992
        }
1993
1994
        $this->refreshSearch($repository);
1995
1996
        // Load Subtree properties after copy
1997
        $actual = $this->loadSubtreeProperties($copiedLocation);
1998
1999
        $this->assertEquals(count($expected), count($actual));
2000
2001
        foreach ($actual as $properties) {
2002
            $this->assertNotContains($properties['id'], $beforeIds);
2003
            $this->assertStringStartsWith(
2004
                $newParentLocation->pathString . $this->parseId('location', $copiedLocation->id) . '/',
2005
                $properties['pathString']
2006
            );
2007
            $this->assertStringEndsWith(
2008
                '/' . $this->parseId('location', $properties['id']) . '/',
2009
                $properties['pathString']
2010
            );
2011
        }
2012
    }
2013
2014
    /**
2015
     * Test for the copySubtree() method.
2016
     *
2017
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2018
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
2019
     */
2020
    public function testCopySubtreeIncrementsChildCountOfNewParent()
2021
    {
2022
        $repository = $this->getRepository();
2023
        $locationService = $repository->getLocationService();
2024
2025
        $childCountBefore = $locationService->getLocationChildCount($locationService->loadLocation(56));
2026
2027
        $mediaLocationId = $this->generateId('location', 43);
2028
        $demoDesignLocationId = $this->generateId('location', 56);
2029
        /* BEGIN: Use Case */
2030
        // $mediaLocationId is the ID of the "Media" page location in
2031
        // an eZ Publish demo installation
2032
2033
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2034
        // Publish demo installation
2035
2036
        // Load the location service
2037
        $locationService = $repository->getLocationService();
2038
2039
        // Load location to copy
2040
        $locationToCopy = $locationService->loadLocation($mediaLocationId);
2041
2042
        // Load new parent location
2043
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2044
2045
        // Copy location "Media" to "Demo Design"
2046
        $copiedLocation = $locationService->copySubtree(
0 ignored issues
show
Unused Code introduced by
$copiedLocation is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2047
            $locationToCopy,
2048
            $newParentLocation
2049
        );
2050
        /* END: Use Case */
2051
2052
        $this->refreshSearch($repository);
2053
2054
        $childCountAfter = $locationService->getLocationChildCount($locationService->loadLocation($demoDesignLocationId));
2055
2056
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
2057
    }
2058
2059
    /**
2060
     * Test for the copySubtree() method.
2061
     *
2062
     * @see \eZ\Publish\API\Repository\LocationService::copySubtree()
2063
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2064
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testCopySubtree
2065
     */
2066 View Code Duplication
    public function testCopySubtreeThrowsInvalidArgumentException()
2067
    {
2068
        $repository = $this->getRepository();
2069
2070
        $communityLocationId = $this->generateId('location', 5);
2071
        /* BEGIN: Use Case */
2072
        // $communityLocationId is the ID of the "Community" page location in
2073
        // an eZ Publish demo installation
2074
2075
        // Load the location service
2076
        $locationService = $repository->getLocationService();
2077
2078
        // Load location to copy
2079
        $locationToCopy = $locationService->loadLocation($communityLocationId);
2080
2081
        // Use a child as new parent
2082
        $childLocations = $locationService->loadLocationChildren($locationToCopy)->locations;
2083
        $newParentLocation = end($childLocations);
2084
2085
        // This call will fail with an "InvalidArgumentException", because the
2086
        // new parent is a child location of the subtree to copy.
2087
        $locationService->copySubtree(
2088
            $locationToCopy,
2089
            $newParentLocation
0 ignored issues
show
Security Bug introduced by
It seems like $newParentLocation defined by end($childLocations) on line 2083 can also be of type false; however, eZ\Publish\API\Repositor...nService::copySubtree() does only seem to accept object<eZ\Publish\API\Re...alues\Content\Location>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
2090
        );
2091
        /* END: Use Case */
2092
    }
2093
2094
    /**
2095
     * Test for the moveSubtree() method.
2096
     *
2097
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2098
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testLoadLocation
2099
     */
2100
    public function testMoveSubtree()
2101
    {
2102
        $repository = $this->getRepository();
2103
2104
        $mediaLocationId = $this->generateId('location', 43);
2105
        $demoDesignLocationId = $this->generateId('location', 56);
2106
        /* BEGIN: Use Case */
2107
        // $mediaLocationId is the ID of the "Media" page location in
2108
        // an eZ Publish demo installation
2109
2110
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2111
        // Publish demo installation
2112
2113
        // Load the location service
2114
        $locationService = $repository->getLocationService();
2115
2116
        // Load location to move
2117
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2118
2119
        // Load new parent location
2120
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2121
2122
        // Move location from "Home" to "Demo Design"
2123
        $locationService->moveSubtree(
2124
            $locationToMove,
2125
            $newParentLocation
2126
        );
2127
2128
        // Load moved location
2129
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2130
        /* END: Use Case */
2131
2132
        $this->assertPropertiesCorrect(
2133
            array(
2134
                'hidden' => false,
2135
                'invisible' => false,
2136
                'depth' => $newParentLocation->depth + 1,
2137
                'parentLocationId' => $newParentLocation->id,
2138
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $movedLocation->id) . '/',
2139
            ),
2140
            $movedLocation
2141
        );
2142
    }
2143
2144
    /**
2145
     * Test for the moveSubtree() method.
2146
     *
2147
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2148
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2149
     */
2150
    public function testMoveSubtreeHidden()
2151
    {
2152
        $repository = $this->getRepository();
2153
2154
        $mediaLocationId = $this->generateId('location', 43);
2155
        $demoDesignLocationId = $this->generateId('location', 56);
2156
        /* BEGIN: Use Case */
2157
        // $mediaLocationId is the ID of the "Media" page location in
2158
        // an eZ Publish demo installation
2159
2160
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2161
        // Publish demo installation
2162
2163
        // Load the location service
2164
        $locationService = $repository->getLocationService();
2165
2166
        // Load location to move
2167
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2168
2169
        // Load new parent location
2170
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2171
2172
        // Hide the target location before we move
2173
        $newParentLocation = $locationService->hideLocation($newParentLocation);
2174
2175
        // Move location from "Home" to "Demo Design"
2176
        $locationService->moveSubtree(
2177
            $locationToMove,
2178
            $newParentLocation
2179
        );
2180
2181
        // Load moved location
2182
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2183
        /* END: Use Case */
2184
2185
        $this->assertPropertiesCorrect(
2186
            array(
2187
                'hidden' => false,
2188
                'invisible' => true,
2189
                'depth' => $newParentLocation->depth + 1,
2190
                'parentLocationId' => $newParentLocation->id,
2191
                'pathString' => $newParentLocation->pathString . $this->parseId('location', $movedLocation->id) . '/',
2192
            ),
2193
            $movedLocation
2194
        );
2195
    }
2196
2197
    /**
2198
     * Test for the moveSubtree() method.
2199
     *
2200
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2201
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2202
     */
2203
    public function testMoveSubtreeUpdatesSubtreeProperties()
2204
    {
2205
        $repository = $this->getRepository();
2206
        $locationService = $repository->getLocationService();
2207
2208
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2209
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2210
2211
        // Load Subtree properties before move
2212
        $expected = $this->loadSubtreeProperties($locationToMove);
2213
        foreach ($expected as $id => $properties) {
2214
            $expected[$id]['depth'] = $properties['depth'] + 2;
2215
            $expected[$id]['pathString'] = str_replace(
2216
                $locationToMove->pathString,
2217
                $newParentLocation->pathString . $this->parseId('location', $locationToMove->id) . '/',
2218
                $properties['pathString']
2219
            );
2220
        }
2221
2222
        $mediaLocationId = $this->generateId('location', 43);
2223
        $demoDesignLocationId = $this->generateId('location', 56);
2224
        /* BEGIN: Use Case */
2225
        // $mediaLocationId is the ID of the "Media" page location in
2226
        // an eZ Publish demo installation
2227
2228
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2229
        // Publish demo installation
2230
2231
        // Load the location service
2232
        $locationService = $repository->getLocationService();
2233
2234
        // Load location to move
2235
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2236
2237
        // Load new parent location
2238
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2239
2240
        // Move location from "Home" to "Demo Design"
2241
        $locationService->moveSubtree(
2242
            $locationToMove,
2243
            $newParentLocation
2244
        );
2245
2246
        // Load moved location
2247
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2248
        /* END: Use Case */
2249
2250
        $this->refreshSearch($repository);
2251
2252
        // Load Subtree properties after move
2253
        $actual = $this->loadSubtreeProperties($movedLocation);
2254
2255
        $this->assertEquals($expected, $actual);
2256
    }
2257
2258
    /**
2259
     * Test for the moveSubtree() method.
2260
     *
2261
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2262
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtreeUpdatesSubtreeProperties
2263
     */
2264
    public function testMoveSubtreeUpdatesSubtreePropertiesHidden()
2265
    {
2266
        $repository = $this->getRepository();
2267
        $locationService = $repository->getLocationService();
2268
2269
        $locationToMove = $locationService->loadLocation($this->generateId('location', 43));
2270
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2271
2272
        // Hide the target location before we move
2273
        $newParentLocation = $locationService->hideLocation($newParentLocation);
2274
2275
        // Load Subtree properties before move
2276
        $expected = $this->loadSubtreeProperties($locationToMove);
2277
        foreach ($expected as $id => $properties) {
2278
            $expected[$id]['invisible'] = true;
2279
            $expected[$id]['depth'] = $properties['depth'] + 2;
2280
            $expected[$id]['pathString'] = str_replace(
2281
                $locationToMove->pathString,
2282
                $newParentLocation->pathString . $this->parseId('location', $locationToMove->id) . '/',
2283
                $properties['pathString']
2284
            );
2285
        }
2286
2287
        $mediaLocationId = $this->generateId('location', 43);
2288
        $demoDesignLocationId = $this->generateId('location', 56);
2289
        /* BEGIN: Use Case */
2290
        // $mediaLocationId is the ID of the "Media" page location in
2291
        // an eZ Publish demo installation
2292
2293
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2294
        // Publish demo installation
2295
2296
        // Load the location service
2297
        $locationService = $repository->getLocationService();
2298
2299
        // Load location to move
2300
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2301
2302
        // Load new parent location
2303
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2304
2305
        // Move location from "Home" to "Demo Design"
2306
        $locationService->moveSubtree(
2307
            $locationToMove,
2308
            $newParentLocation
2309
        );
2310
2311
        // Load moved location
2312
        $movedLocation = $locationService->loadLocation($mediaLocationId);
2313
        /* END: Use Case */
2314
2315
        $this->refreshSearch($repository);
2316
2317
        // Load Subtree properties after move
2318
        $actual = $this->loadSubtreeProperties($movedLocation);
2319
2320
        $this->assertEquals($expected, $actual);
2321
    }
2322
2323
    /**
2324
     * Test for the moveSubtree() method.
2325
     *
2326
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2327
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2328
     */
2329 View Code Duplication
    public function testMoveSubtreeIncrementsChildCountOfNewParent()
2330
    {
2331
        $repository = $this->getRepository();
2332
        $locationService = $repository->getLocationService();
2333
2334
        $newParentLocation = $locationService->loadLocation($this->generateId('location', 56));
2335
2336
        // Load expected properties before move
2337
        $expected = $this->loadLocationProperties($newParentLocation);
2338
        $childCountBefore = $locationService->getLocationChildCount($newParentLocation);
2339
2340
        $mediaLocationId = $this->generateId('location', 43);
2341
        $demoDesignLocationId = $this->generateId('location', 56);
2342
        /* BEGIN: Use Case */
2343
        // $mediaLocationId is the ID of the "Media" page location in
2344
        // an eZ Publish demo installation
2345
2346
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2347
        // Publish demo installation
2348
2349
        // Load the location service
2350
        $locationService = $repository->getLocationService();
2351
2352
        // Load location to move
2353
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2354
2355
        // Load new parent location
2356
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2357
2358
        // Move location from "Home" to "Demo Design"
2359
        $locationService->moveSubtree(
2360
            $locationToMove,
2361
            $newParentLocation
2362
        );
2363
2364
        // Load moved location
2365
        $movedLocation = $locationService->loadLocation($mediaLocationId);
0 ignored issues
show
Unused Code introduced by
$movedLocation is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2366
2367
        // Reload new parent location
2368
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2369
        /* END: Use Case */
2370
2371
        $this->refreshSearch($repository);
2372
2373
        // Load Subtree properties after move
2374
        $actual = $this->loadLocationProperties($newParentLocation);
2375
        $childCountAfter = $locationService->getLocationChildCount($newParentLocation);
2376
2377
        $this->assertEquals($expected, $actual);
2378
        $this->assertEquals($childCountBefore + 1, $childCountAfter);
2379
    }
2380
2381
    /**
2382
     * Test for the moveSubtree() method.
2383
     *
2384
     * @see \eZ\Publish\API\Repository\LocationService::moveSubtree()
2385
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2386
     */
2387 View Code Duplication
    public function testMoveSubtreeDecrementsChildCountOfOldParent()
2388
    {
2389
        $repository = $this->getRepository();
2390
        $locationService = $repository->getLocationService();
2391
2392
        $oldParentLocation = $locationService->loadLocation($this->generateId('location', 1));
2393
2394
        // Load expected properties before move
2395
        $expected = $this->loadLocationProperties($oldParentLocation);
2396
        $childCountBefore = $locationService->getLocationChildCount($oldParentLocation);
2397
2398
        $mediaLocationId = $this->generateId('location', 43);
2399
        $demoDesignLocationId = $this->generateId('location', 56);
2400
        /* BEGIN: Use Case */
2401
        // $mediaLocationId is the ID of the "Media" page location in
2402
        // an eZ Publish demo installation
2403
2404
        // $demoDesignLocationId is the ID of the "Demo Design" page location in an eZ
2405
        // Publish demo installation
2406
2407
        // Load the location service
2408
        $locationService = $repository->getLocationService();
2409
2410
        // Load location to move
2411
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2412
2413
        // Get the location id of the old parent
2414
        $oldParentLocationId = $locationToMove->parentLocationId;
2415
2416
        // Load new parent location
2417
        $newParentLocation = $locationService->loadLocation($demoDesignLocationId);
2418
2419
        // Move location from "Home" to "Demo Design"
2420
        $locationService->moveSubtree(
2421
            $locationToMove,
2422
            $newParentLocation
2423
        );
2424
2425
        // Reload old parent location
2426
        $oldParentLocation = $locationService->loadLocation($oldParentLocationId);
2427
        /* END: Use Case */
2428
2429
        $this->refreshSearch($repository);
2430
2431
        // Load Subtree properties after move
2432
        $actual = $this->loadLocationProperties($oldParentLocation);
2433
        $childCountAfter = $locationService->getLocationChildCount($oldParentLocation);
2434
2435
        $this->assertEquals($expected, $actual);
2436
        $this->assertEquals($childCountBefore - 1, $childCountAfter);
2437
    }
2438
2439
    /**
2440
     * Test for the moveSubtree() method.
2441
     *
2442
     * @depends eZ\Publish\API\Repository\Tests\LocationServiceTest::testMoveSubtree
2443
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
2444
     */
2445 View Code Duplication
    public function testMoveSubtreeThrowsInvalidArgumentException()
2446
    {
2447
        $repository = $this->getRepository();
2448
        $mediaLocationId = $this->generateId('location', 43);
2449
        $multimediaLocationId = $this->generateId('location', 53);
2450
2451
        /* BEGIN: Use Case */
2452
        // $mediaLocationId is the ID of the "Media" page location in
2453
        // an eZ Publish demo installation
2454
2455
        // $multimediaLocationId is the ID of the "Multimedia" page location in an eZ
2456
        // Publish demo installation
2457
2458
        // Load the location service
2459
        $locationService = $repository->getLocationService();
2460
2461
        // Load location to move
2462
        $locationToMove = $locationService->loadLocation($mediaLocationId);
2463
2464
        // Load new parent location
2465
        $newParentLocation = $locationService->loadLocation($multimediaLocationId);
2466
2467
        // Throws an exception because new parent location is placed below location to move
2468
        $locationService->moveSubtree(
2469
            $locationToMove,
2470
            $newParentLocation
2471
        );
2472
        /* END: Use Case */
2473
    }
2474
2475
    /**
2476
     * Loads properties from all locations in the $location's subtree.
2477
     *
2478
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2479
     * @param array $properties
2480
     *
2481
     * @return array
2482
     */
2483
    private function loadSubtreeProperties(Location $location, array $properties = array())
2484
    {
2485
        $locationService = $this->getRepository()->getLocationService();
2486
2487
        foreach ($locationService->loadLocationChildren($location)->locations as $childLocation) {
2488
            $properties[] = $this->loadLocationProperties($childLocation);
2489
2490
            $properties = $this->loadSubtreeProperties($childLocation, $properties);
2491
        }
2492
2493
        return $properties;
2494
    }
2495
2496
    /**
2497
     * Loads assertable properties from the given location.
2498
     *
2499
     * @param \eZ\Publish\API\Repository\Values\Content\Location $location
2500
     * @param mixed[] $overwrite
2501
     *
2502
     * @return array
2503
     */
2504
    private function loadLocationProperties(Location $location, array $overwrite = array())
2505
    {
2506
        return array_merge(
2507
            array(
2508
                'id' => $location->id,
2509
                'depth' => $location->depth,
2510
                'parentLocationId' => $location->parentLocationId,
2511
                'pathString' => $location->pathString,
2512
                'remoteId' => $location->remoteId,
2513
                'hidden' => $location->hidden,
2514
                'invisible' => $location->invisible,
2515
                'priority' => $location->priority,
2516
                'sortField' => $location->sortField,
2517
                'sortOrder' => $location->sortOrder,
2518
            ),
2519
            $overwrite
2520
        );
2521
    }
2522
2523
    /**
2524
     * Assert generated aliases to expected alias return.
2525
     *
2526
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2527
     * @param array $expectedAliases
2528
     */
2529
    protected function assertGeneratedAliases($urlAliasService, array $expectedAliases)
2530
    {
2531
        foreach ($expectedAliases as $expectedAlias) {
2532
            $urlAlias = $urlAliasService->lookup($expectedAlias);
2533
            $this->assertPropertiesCorrect(['type' => 0], $urlAlias);
2534
        }
2535
    }
2536
2537
    /**
2538
     * @param \eZ\Publish\API\Repository\URLAliasService $urlAliasService
2539
     * @param array $expectedSubItemAliases
2540
     */
2541
    private function assertAliasesBeforeCopy($urlAliasService, array $expectedSubItemAliases)
2542
    {
2543
        foreach ($expectedSubItemAliases as $aliasUrl) {
2544
            try {
2545
                $urlAliasService->lookup($aliasUrl);
2546
                $this->fail('We didn\'t expect to find alias, but it was found');
2547
            } catch (\Exception $e) {
2548
                $this->assertTrue(true); // OK - alias was not found
2549
            }
2550
        }
2551
    }
2552
2553
    /**
2554
     * Create and publish Content with the given parent Location.
2555
     *
2556
     * @param string $contentName
2557
     * @param int $parentLocationId
2558
     *
2559
     * @return \eZ\Publish\API\Repository\Values\Content\Content published Content
2560
     */
2561 View Code Duplication
    private function publishContentWithParentLocation($contentName, $parentLocationId)
2562
    {
2563
        $repository = $this->getRepository(false);
2564
        $locationService = $repository->getLocationService();
2565
2566
        $contentService = $repository->getContentService();
2567
        $contentTypeService = $repository->getContentTypeService();
2568
2569
        $contentCreateStruct = $contentService->newContentCreateStruct(
2570
            $contentTypeService->loadContentTypeByIdentifier('folder'),
2571
            'eng-US'
2572
        );
2573
        $contentCreateStruct->setField('name', $contentName);
2574
        $contentDraft = $contentService->createContent(
2575
            $contentCreateStruct,
2576
            [
2577
                $locationService->newLocationCreateStruct($parentLocationId),
2578
            ]
2579
        );
2580
2581
        return $contentService->publishVersion($contentDraft->versionInfo);
2582
    }
2583
}
2584